Version 1.3.0-dev.0.0

svn merge -r 32598:33057 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@33060 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 1ee2375..23770e1 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -5,7 +5,7 @@
 \usepackage{hyperref}
 \newcommand{\code}[1]{{\sf #1}}
 \title{Dart Programming Language  Specification \\
-{\large Version 1.11}}
+{\large Version 1.2}}
 \author{The Dart Team}
 \begin{document}
 \maketitle
@@ -209,7 +209,9 @@
 \subsection{Privacy}
 \label{privacy}
 
-Dart supports two levels of privacy: {\em public} and {\em private}. A declaration is {\em private} iff its name begins with an underscore (the \_ character) otherwise it is {\em public.} 
+Dart supports two levels of privacy: {\em public} and {\em private}.  A declaration is {\em private} iff its name is private, otherwise it is {\em public.}  A  name $q$ is private iff any one of the identifiers that comprise $q$ is private,  otherwise it is {\em public.}  An identifier is private iff it
+begins with an underscore (the \_ character) otherwise it is {\em public.} 
+
 A declaration $m$ is {\em accessible to library $L$}  if $m$ is declared in $L$ or if $m$ is public.
 
 \commentary{
@@ -218,9 +220,8 @@
 
 Privacy applies only to declarations within a library, not to library declarations themselves. 
 
-\rationale{
-Libraries do not reference each other by name and so the idea of a private library is meaningless.
-Thus, if the name of a library begins with an underscore, it has no special significance.
+\rationale{Libraries do not reference each other by name and so the idea of a private library is meaningless.
+Thus, if the name of a library begins with an underscore, it has no effect on the accessibility of the library or its members.
 }
 
 \rationale{Privacy is, at this point, a static notion tied to a particular piece of code (a library). It is designed to support software engineering concerns rather than security concerns. Untrusted code should always run in an another isolate.  It is possible that libraries will become first class objects and privacy will be a dynamic notion tied to a library instance.
@@ -1667,7 +1668,7 @@
 \item $m$ is accessible to $K$ and 
 \item $A$ is a direct superinterface of $J$ and either 
   \begin{itemize}
-  \item $m$ is a member of  $A$  or
+  \item $A$ declares a member $m$  or
   \item $m$ is a member of $inherited(A, K)$.
   \end{itemize}
 \item $m$ is not overridden by $J$.
@@ -1681,7 +1682,7 @@
 \item $m^\prime$ is accessible to $K$.  
 \item $A$ is a direct superinterface of $J$ and either
   \begin{itemize}
-  \item $m^\prime$ is a member of $A$ or 
+  \item $A$ declares a member $m^\prime$ or 
   \item $m^\prime$ is a member of $inherited(A, K)$.
   \end{itemize}
 \end{itemize}
@@ -4832,7 +4833,7 @@
 
 A Dart program consists of one or more libraries, and may be built out of one or more {\em compilation units}. A compilation unit may be a library or a part (\ref{parts}). 
 
-A library consists of (a possibly empty) set of imports, a set of exports, and a set of top-level declarations. A top-level declaration is either a class (\ref{classes}), a type alias declaration (\ref{typedef}), a function (\ref{functions}) or a variable declaration (\ref{variables}). The members of a library $L$ are those top level declarations given within a $L$.
+A library consists of (a possibly empty) set of imports, a set of exports,  and a set of top-level declarations. A top-level declaration is either a class (\ref{classes}), a type alias declaration (\ref{typedef}), a function (\ref{functions}) or a variable declaration (\ref{variables}). The members of a library $L$ are those top level declarations given within a $L$.
 
  \begin{grammar}
 {\bf topLevelDefinition:}classDefinition;
diff --git a/pkg/analysis_server/bin/dartdeps.dart b/pkg/analysis_server/bin/dartdeps.dart
new file mode 100644
index 0000000..73e5907
--- /dev/null
+++ b/pkg/analysis_server/bin/dartdeps.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:analysis_server/src/analysis_manager.dart';
+
+/**
+ * Start analysis server as a separate process and use the websocket protocol
+ * to analyze the application specified on the command line.
+ */
+void main(List<String> args) {
+  _DartDependencyAnalyzer analyzer = new _DartDependencyAnalyzer();
+  analyzer.start(args);
+}
+
+/**
+ * Instances of [_DartDependencyAnalyzer] launch an analysis server and use
+ * that server to analyze the dependencies of an application.
+ */
+class _DartDependencyAnalyzer {
+  /**
+   * The name of the application that is used to start the analyzer.
+   */
+  static const BINARY_NAME = 'dartdeps';
+
+  /**
+   * The name of the option used to print usage information.
+   */
+  static const String HELP_OPTION = "help";
+
+  /**
+   * The name of the option used to specify an already running server.
+   */
+  static const String SERVER_OPTION = "server";
+
+  /**
+   * Parse the command line arguments to determine the application to be
+   * analyzed, then launch and manage an analysis server to do the work.
+   * If there is a problem with the given arguments, then return a non zero
+   * value, otherwise return zero.
+   */
+  void start(List<String> args) {
+    var parser = new ArgParser();
+    parser.addFlag(HELP_OPTION,
+        help: "print this help message without starting analysis",
+        defaultsTo: false,
+        negatable: false);
+    parser.addOption(
+        SERVER_OPTION,
+        help: "[serverUrl] use an analysis server thats already running");
+
+    // Parse arguments
+    ArgResults results;
+    try {
+      results = parser.parse(args);
+    } on FormatException catch(e) {
+      print(e.message);
+      print('');
+      printUsage(parser);
+      exitCode = 1;
+      return;
+    }
+    if (results[HELP_OPTION]) {
+      printUsage(parser);
+      return;
+    }
+    if (results.rest.length == 0) {
+      printUsage(parser);
+      exitCode = 1;
+      return;
+    }
+    Directory appDir = new Directory(results.rest[0]);
+    if (!appDir.existsSync()) {
+      print('Specified application directory does not exist: $appDir');
+      print('');
+      printUsage(parser);
+      exitCode = 1;
+      return;
+    }
+    if (results.rest.length > 1) {
+      print('Unexpected arguments after $appDir');
+      print('');
+      printUsage(parser);
+      exitCode = 1;
+      return;
+    }
+
+    Future<AnalysisManager> future;
+    String serverUrl = results[SERVER_OPTION];
+    if (serverUrl != null) {
+      // Connect to an already running analysis server
+      future = AnalysisManager.connect(serverUrl);
+
+    } else {
+      // Launch and connect to a new analysis server
+      // Assume that the analysis server entry point is in the same directory
+      StringBuffer path = new StringBuffer();
+      path.write(FileSystemEntity.parentOf(Platform.script.toFilePath()));
+      path.write(Platform.pathSeparator);
+      path.write("server.dart");
+      future = AnalysisManager.start(path.toString());
+    }
+    future.then(analyze);
+  }
+
+  void analyze(AnalysisManager mgr) {
+    print("Analyzing...");
+    new Timer(new Duration(seconds: 5), () {
+      if (mgr.stop()) {
+        print("stopped");
+      } else {
+        print("already stopped");
+      }
+    });
+  }
+
+  /**
+   * Print information about how to use the server.
+   */
+  void printUsage(ArgParser parser) {
+    print('Usage: $BINARY_NAME [flags] <application_directory>');
+    print('');
+    print('Supported flags are:');
+    print(parser.getUsage());
+  }
+}
diff --git a/pkg/analysis_server/lib/http_server.dart b/pkg/analysis_server/lib/http_server.dart
index 3fb08de..6b66383 100644
--- a/pkg/analysis_server/lib/http_server.dart
+++ b/pkg/analysis_server/lib/http_server.dart
@@ -39,7 +39,7 @@
    * The analysis server that was created when an UPGRADE request was received,
    * or `null` if no such request has yet been received.
    */
-  AnalysisServer server;
+  AnalysisServer analysisServer;
 
   /**
    * An object that can handle GET requests.
@@ -74,6 +74,7 @@
       print('Missing required port number');
       print('');
       _printUsage(parser);
+      exitCode = 1;
       return;
     }
 
@@ -85,6 +86,7 @@
       print('Invalid port number: ${results[PORT_OPTION]}');
       print('');
       _printUsage(parser);
+      exitCode = 1;
       return;
     }
   }
@@ -92,11 +94,11 @@
   /**
    * Attach a listener to a newly created HTTP server.
    */
-  void _handleServer(HttpServer server) {
-    server.listen((HttpRequest request) {
+  void _handleServer(HttpServer httServer) {
+    httServer.listen((HttpRequest request) {
       List<String> updateValues = request.headers[HttpHeaders.UPGRADE];
       if (updateValues != null && updateValues.indexOf('websocket') >= 0) {
-        if (server != null) {
+        if (analysisServer != null) {
           _returnServerAlreadyStarted(request);
           return;
         }
@@ -117,7 +119,7 @@
   void _handleGetRequest(HttpRequest request) {
     if (getHandler == null) {
       getHandler = new GetHandler();
-      getHandler.server = server;
+      getHandler.server = analysisServer;
     }
     getHandler.handleGetRequest(request);
   }
@@ -127,12 +129,12 @@
    * running an analysis server on a [WebSocket]-based communication channel.
    */
   void _handleWebSocket(WebSocket socket) {
-    server = new AnalysisServer(new WebSocketChannel(socket));
-    _initializeHandlers(server);
+    analysisServer = new AnalysisServer(new WebSocketChannel(socket));
+    _initializeHandlers(analysisServer);
     if (getHandler != null) {
-      getHandler.server = server;
+      getHandler.server = analysisServer;
     }
-    server.run();
+    analysisServer.run();
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/analysis_manager.dart b/pkg/analysis_server/lib/src/analysis_manager.dart
new file mode 100644
index 0000000..f46d1c9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/analysis_manager.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+/**
+ * [AnalysisManager] is used to launch and manage an analysis server
+ * running in a separate process using the static [start] method.
+ */
+class AnalysisManager {
+  // TODO dynamically allocate port and/or allow client to specify port
+  static const int PORT = 3333;
+
+  /**
+   * The analysis server process being managed
+   * or `null` if managing an analysis server that was already running.
+   */
+  final Process process;
+
+  /**
+   * The websocket used to communicate with the analysis server.
+   */
+  final WebSocket socket;
+
+  /**
+   * Launch analysis server in a separate process and return a
+   * [Future<AnalysisManager>] for managing that analysis server.
+   */
+  static Future<AnalysisManager> start(String pathToServer) {
+    // TODO dynamically allocate port and/or allow client to specify port
+    return Process.start(Platform.executable, [pathToServer, "--port",
+        PORT.toString()]).then(_attach).catchError((error) {
+          print("Failed to launch analysis server: $error");
+          exitCode = 1;
+          throw error;
+        });
+  }
+
+  /**
+   * Open a connection to a running analysis server
+   */
+  static Future<AnalysisManager> connect(String url) {
+    return WebSocket.connect(url)
+        .then((WebSocket socket) => new AnalysisManager(null, socket));
+  }
+
+  /**
+   * Attach this process to the newly launched analysis server process,
+   * and open a connection to the analysis server.
+   */
+  static Future<AnalysisManager> _attach(Process process) {
+    var url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$PORT/';
+    process.stderr.pipe(stderr);
+    Stream out = process.stdout.transform(UTF8.decoder).asBroadcastStream();
+    out.listen((line) {
+      print(line);
+    });
+    return out
+        .any((String line) => line.startsWith("Listening on port"))
+        .then((bool listening) {
+          if (!listening) {
+            throw "Expected analysis server to listen on a port";
+          }
+        })
+        .then((_) => WebSocket.connect(url))
+        .then((WebSocket socket) => new AnalysisManager(process, socket))
+        .catchError((error) {
+          process.kill();
+          print("Failed to connect to analysis server: $error");
+          exitCode = 1;
+          throw error;
+        });
+  }
+
+  /**
+   * Create a new instance that manages the specified analysis server process.
+   */
+  AnalysisManager(this.process, this.socket);
+
+  /**
+   * Stop the analysis server.
+   *
+   * Returns `true` if the signal is successfully sent and process is killed.
+   * Otherwise there was no attached process or the signal could not be sent,
+   * usually meaning that the process is already dead.
+   */
+  // TODO request analysis server stop
+  bool stop() => process != null ? process.kill() : false;
+}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 1c5e683..3cd1305 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -35,7 +35,7 @@
    * The channel from which requests are received and to which responses should
    * be sent.
    */
-  CommunicationChannel channel;
+  final CommunicationChannel channel;
 
   /**
    * A flag indicating whether the server is running.
@@ -63,11 +63,11 @@
    * Initialize a newly created server to receive requests from and send
    * responses to the given [channel].
    */
-  AnalysisServer(CommunicationChannel channel) {
+  AnalysisServer(this.channel) {
     AnalysisEngine.instance.logger = new AnalysisLogger();
     running = true;
-    this.channel = channel;
-    this.channel.listen(handleRequest, onError: error, onDone: done);
+    // TODO set running=false on done or error
+    channel.listen(handleRequest);
   }
 
   /**
@@ -136,8 +136,8 @@
     if (contextWorkQueue.isEmpty) {
       running = false;
     } else {
-      Timer.run(() {
-        performTask();
+      new Future(performTask).catchError((exception, stackTrace) {
+        AnalysisEngine.instance.logger.logError3(exception);
       });
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index c7f631c..738761b7 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -16468,4 +16468,7 @@
     _elements[index] = node;
   }
   int get length => _elements.length;
+  void set length(int value) {
+    throw new UnsupportedError("Cannot resize NodeList.");
+  }
 }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index a2cc12b..9997073 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -756,6 +756,13 @@
    * @return `true` if analysis is to parse comments
    */
   bool get preserveComments;
+
+  /**
+   * Return `true` if analysis is to analyze Angular.
+   *
+   * @return `true` if analysis is to analyze Angular
+   */
+  bool get analyzeAngular;
 }
 
 /**
@@ -5138,28 +5145,30 @@
         _cache.put(source, htmlCopy);
         return new ResolveHtmlTask(this, source);
       }
-      CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
-      if (identical(angularErrorsState, CacheState.INVALID)) {
-        AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
-        if (entryInfo != null) {
-          HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
-          htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
-          _cache.put(source, htmlCopy);
-          return new ResolveAngularEntryHtmlTask(this, source, entryInfo);
-        }
-        AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
-        if (applicationInfo != null) {
-          AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
-          if (component != null) {
+      if (_options.analyzeAngular) {
+        CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
+        if (identical(angularErrorsState, CacheState.INVALID)) {
+          AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
+          if (entryInfo != null) {
             HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
             htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
             _cache.put(source, htmlCopy);
-            return new ResolveAngularComponentTemplateTask(this, source, component, applicationInfo);
+            return new ResolveAngularEntryHtmlTask(this, source, entryInfo);
           }
+          AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
+          if (applicationInfo != null) {
+            AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
+            if (component != null) {
+              HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+              htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
+              _cache.put(source, htmlCopy);
+              return new ResolveAngularComponentTemplateTask(this, source, component, applicationInfo);
+            }
+          }
+          HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+          htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
+          _cache.put(source, htmlCopy);
         }
-        HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
-        htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
-        _cache.put(source, htmlCopy);
       }
     }
     return null;
@@ -5333,20 +5342,22 @@
         sources.add(source);
         return;
       }
-      CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
-      if (identical(angularErrorsState, CacheState.INVALID)) {
-        AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
-        if (entryInfo != null) {
-          sources.add(source);
-          return;
-        }
-        AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
-        if (applicationInfo != null) {
-          AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
-          if (component != null) {
+      if (_options.analyzeAngular) {
+        CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
+        if (identical(angularErrorsState, CacheState.INVALID)) {
+          AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
+          if (entryInfo != null) {
             sources.add(source);
             return;
           }
+          AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
+          if (applicationInfo != null) {
+            AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
+            if (component != null) {
+              sources.add(source);
+              return;
+            }
+          }
         }
       }
     }
@@ -5481,6 +5492,9 @@
    * @param dartCopy the [DartEntryImpl] to record new Angular components
    */
   void recordAngularComponents(HtmlEntryImpl entry, AngularApplicationInfo app) {
+    if (!_options.analyzeAngular) {
+      return;
+    }
     // reset old Angular errors
     AngularApplicationInfo oldApp = entry.getValue(HtmlEntry.ANGULAR_ENTRY);
     if (oldApp != null) {
@@ -6671,11 +6685,16 @@
   bool incremental = false;
 
   /**
-   * flag indicating whether analysis is to parse comments.
+   * A flag indicating whether analysis is to parse comments.
    */
   bool preserveComments = true;
 
   /**
+   * A flag indicating whether analysis is to parse comments.
+   */
+  bool analyzeAngular = true;
+
+  /**
    * Initialize a newly created set of analysis options to have their default values.
    */
   AnalysisOptionsImpl();
@@ -6691,6 +6710,7 @@
     dart2jsHint = options.dart2jsHint;
     hint = options.hint;
     incremental = options.incremental;
+    analyzeAngular = options.analyzeAngular;
   }
 }
 
@@ -10903,8 +10923,10 @@
     RecordingErrorListener errorListener = builder.errorListener;
     LineInfo lineInfo = context.getLineInfo(source);
     // try to resolve as an Angular entry point
-    _isAngularApplication2 = AngularHtmlUnitResolver.hasAngularAnnotation(unit);
-    _angularApplication = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).calculateAngularApplication();
+    if (context.analysisOptions.analyzeAngular) {
+      _isAngularApplication2 = AngularHtmlUnitResolver.hasAngularAnnotation(unit);
+      _angularApplication = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).calculateAngularApplication();
+    }
     // record all resolution errors
     _resolutionErrors = errorListener.getErrors2(source);
     // remember resolved unit
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index 0edd439..eab8d8b 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -137,13 +137,15 @@
 
     var formattedSource = formatter.writer.toString();
 
-    checkTokenStreams(startToken, tokenize(formattedSource));
+    checkTokenStreams(startToken, tokenize(formattedSource),
+                      allowTransforms: options.codeTransforms);
 
     return new FormattedSource(formattedSource, formatter.selection);
   }
 
-  checkTokenStreams(Token t1, Token t2) =>
-      new TokenStreamComparator(lineInfo, t1, t2).verifyEquals();
+  checkTokenStreams(Token t1, Token t2, {allowTransforms: false}) =>
+      new TokenStreamComparator(lineInfo, t1, t2, transforms: allowTransforms).
+          verifyEquals();
 
   ASTNode parse(CodeKind kind, Token start) {
 
@@ -185,8 +187,10 @@
 
   final LineInfo lineInfo;
   Token token1, token2;
+  bool allowTransforms;
 
-  TokenStreamComparator(this.lineInfo, this.token1, this.token2);
+  TokenStreamComparator(this.lineInfo, this.token1, this.token2,
+      {transforms: false}) : this.allowTransforms = transforms;
 
   /// Verify that these two token streams are equal.
   verifyEquals() {
@@ -274,10 +278,23 @@
         return true;
       }
     }
-    // Advance past synthetic { } tokens
-    if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) {
-      token2 = token2.next;
-      return checkTokens();
+
+    // Transform-related special casing
+    if (allowTransforms) {
+
+      // Advance past empty statements
+      if (isSEMICOLON(token1)) {
+        // TODO whitelist
+        token1 = token1.next;
+        return checkTokens();
+      }
+
+      // Advance past synthetic { } tokens
+      if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) {
+        token2 = token2.next;
+        return checkTokens();
+      }
+
     }
 
     return false;
@@ -722,7 +739,9 @@
   }
 
   visitEmptyStatement(EmptyStatement node) {
-    token(node.semicolon);
+    if (!codeTransforms || node.parent is! Block) {
+      token(node.semicolon);
+    }
   }
 
   visitExportDirective(ExportDirective node) {
@@ -1318,7 +1337,32 @@
     visitNodes(node.metadata, followedBy: newlines);
     modifier(node.keyword);
     visitNode(node.type, followedBy: space);
-    visitCommaSeparatedNodes(node.variables);
+
+    var variables = node.variables;
+    // Decls with initializers get their own lines (dartbug.com/16849)
+    if (variables.any((v) => (v.initializer != null))) {
+      var size = variables.length;
+      if (size > 0) {
+        var variable;
+        for (var i = 0; i < size; i++) {
+          variable = variables[i];
+          if (i > 0) {
+            var comma = variable.beginToken.previous;
+            token(comma);
+            newlines();
+          }
+          if (i == 1) {
+            indent(2);
+          }
+          variable.accept(this);
+        }
+        if (size > 1) {
+          unindent(2);
+        }
+      }
+    } else {
+      visitCommaSeparatedNodes(node.variables);
+    }
   }
 
   visitVariableDeclarationStatement(VariableDeclarationStatement node) {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index fb76d5a..52ff899 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,13 +1,13 @@
 name: analyzer
-version: 0.12.0
+version: 0.12.2
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
 dependencies:
-  args: ">=0.9.0 <0.10.0"
+  args: ">=0.9.0 <0.11.0"
   logging: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <2.0.0"
 dev_dependencies:
-  unittest: ">=0.9.0 <0.10.0"
+  unittest: ">=0.9.0 <0.11.0"
 environment:
   sdk: ">=0.8.10+6 <2.0.0"
diff --git a/pkg/analyzer/test/services/data/stmt_tests.data b/pkg/analyzer/test/services/data/stmt_tests.data
index c50f2aa..603d8a4 100644
--- a/pkg/analyzer/test/services/data/stmt_tests.data
+++ b/pkg/analyzer/test/services/data/stmt_tests.data
@@ -133,3 +133,37 @@
 void main() {
 
 }
+>>> Decls with initializers get their own lines (dartbug.com/16849)
+var x, y;
+<<<
+var x, y;
+>>>
+var x = 3, y = 4;
+<<<
+var x = 3,
+    y = 4;
+>>>
+var x = 2, y;
+<<<
+var x = 2,
+    y;
+>>> dartbug.com/16810 [Note: transforms are enabled]
+void f() {
+  var a;;;
+}
+<<<
+void f() {
+  var a;
+}
+>>>
+while (true);
+<<<
+while (true);
+>>>
+for ( ; ; ) {
+  print('!');
+}
+<<<
+for ( ; ; ) {
+  print('!');
+}
\ No newline at end of file
diff --git a/pkg/analyzer/test/services/formatter_test.dart b/pkg/analyzer/test/services/formatter_test.dart
index f3557d7..c77f6f9 100644
--- a/pkg/analyzer/test/services/formatter_test.dart
+++ b/pkg/analyzer/test/services/formatter_test.dart
@@ -18,8 +18,11 @@
 
   /// Data-driven statement tests
   group('stmt_tests.data', () {
+    // NOTE: statement tests are run with transforms enabled
     runTests('stmt_tests.data', (input, expectedOutput) {
-      expect(formatStatement(input) + '\n', equals(expectedOutput));
+      expect(formatStatement(input,
+          options: new FormatterOptions(codeTransforms: true)) + '\n',
+          equals(expectedOutput));
     });
   });
 
diff --git a/pkg/barback/lib/src/log.dart b/pkg/barback/lib/src/log.dart
index 809d8a9..23f425a 100644
--- a/pkg/barback/lib/src/log.dart
+++ b/pkg/barback/lib/src/log.dart
@@ -12,6 +12,7 @@
 /// The severity of a logged message.
 class LogLevel {
   static const INFO = const LogLevel("Info");
+  static const FINE = const LogLevel("Fine");
   static const WARNING = const LogLevel("Warning");
   static const ERROR = const LogLevel("Error");
 
diff --git a/pkg/barback/lib/src/package_graph.dart b/pkg/barback/lib/src/package_graph.dart
index cf198d9..6765cf3 100644
--- a/pkg/barback/lib/src/package_graph.dart
+++ b/pkg/barback/lib/src/package_graph.dart
@@ -84,7 +84,7 @@
       cascade.onLog.listen((entry) {
         if (_logController.hasListener) {
           _logController.add(entry);
-        } else {
+        } else if (entry.level != LogLevel.FINE) {
           // No listeners, so just print entry.
           var buffer = new StringBuffer();
           buffer.write("[${entry.level} ${entry.transform}] ");
diff --git a/pkg/barback/lib/src/transform_logger.dart b/pkg/barback/lib/src/transform_logger.dart
index bdac90f..c3e5c73 100644
--- a/pkg/barback/lib/src/transform_logger.dart
+++ b/pkg/barback/lib/src/transform_logger.dart
@@ -29,6 +29,17 @@
     _logFunction(asset, LogLevel.INFO, message, span);
   }
 
+  /// Logs a message that won't be displayed unless the user is running in
+  /// verbose mode.
+  ///
+  /// If [asset] is provided, the log entry is associated with that asset.
+  /// Otherwise it's associated with the primary input of [transformer].
+  /// If [span] is provided, indicates the location in the input asset that
+  /// caused the message.
+  void fine(String message, {AssetId asset, Span span}) {
+    _logFunction(asset, LogLevel.FINE, message, span);
+  }
+
   /// Logs a warning message.
   ///
   /// If [asset] is provided, the log entry is associated with that asset.
diff --git a/pkg/barback/pubspec.yaml b/pkg/barback/pubspec.yaml
index 803e405..1df6af0 100644
--- a/pkg/barback/pubspec.yaml
+++ b/pkg/barback/pubspec.yaml
@@ -8,7 +8,7 @@
 # When the minor version of this is upgraded, you *must* update that version
 # number in pub to stay in sync with this. New patch versions are considered
 # backwards compatible, and pub will allow later patch versions automatically.
-version: 0.11.0+3
+version: 0.12.0-dev
 
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
@@ -27,7 +27,7 @@
   source_maps: ">=0.9.0 <0.10.0"
   stack_trace: ">=0.9.1 <0.10.0"
 dev_dependencies:
-  scheduled_test: ">=0.9.0 <0.10.0"
+  scheduled_test: ">=0.9.0 <0.11.0"
   unittest: ">=0.9.0 <0.10.0"
 environment:
   sdk: ">=1.0.1 <2.0.0"
diff --git a/pkg/barback/test/logger_test.dart b/pkg/barback/test/logger_test.dart
index 778f42f..5c42b2e 100644
--- a/pkg/barback/test/logger_test.dart
+++ b/pkg/barback/test/logger_test.dart
@@ -17,7 +17,8 @@
     var transformer = new LogTransformer([
       "error: This is an error.",
       "warning: This is a warning.",
-      "info: This is info."
+      "info: This is info.",
+      "fine: This is fine."
     ]);
     initGraph(["app|foo.txt"], {
       "app": [[transformer]]
@@ -27,13 +28,15 @@
     buildShouldLog(LogLevel.ERROR, equals("This is an error."));
     buildShouldLog(LogLevel.WARNING, equals("This is a warning."));
     buildShouldLog(LogLevel.INFO, equals("This is info."));
+    buildShouldLog(LogLevel.FINE, equals("This is fine."));
   });
 
   test("logs messages from a transformer group", () {
     var transformer = new LogTransformer([
       "error: This is an error.",
       "warning: This is a warning.",
-      "info: This is info."
+      "info: This is info.",
+      "fine: This is fine."
     ]);
 
     initGraph(["app|foo.txt"], {"app": [
@@ -44,5 +47,6 @@
     buildShouldLog(LogLevel.ERROR, equals("This is an error."));
     buildShouldLog(LogLevel.WARNING, equals("This is a warning."));
     buildShouldLog(LogLevel.INFO, equals("This is info."));
+    buildShouldLog(LogLevel.FINE, equals("This is fine."));
   });
 }
diff --git a/pkg/barback/test/transformer/log.dart b/pkg/barback/test/transformer/log.dart
index f2b63fc..cfbad8d 100644
--- a/pkg/barback/test/transformer/log.dart
+++ b/pkg/barback/test/transformer/log.dart
@@ -33,6 +33,7 @@
           case "error":   logFn = transform.logger.error; break;
           case "warning": logFn = transform.logger.warning; break;
           case "info":    logFn = transform.logger.info; break;
+          case "fine":    logFn = transform.logger.fine; break;
         }
 
         logFn(parts[1].trim());
diff --git a/pkg/browser/README.md b/pkg/browser/README.md
index 32c736c..fa96851 100644
--- a/pkg/browser/README.md
+++ b/pkg/browser/README.md
@@ -1,3 +1,8 @@
+This package contains dart.js, and previously contained interop.js
+
+dart.js
+=======
+
 The dart.js file is used in Dart browser apps to check for native Dart support
 and either (a) bootstrap Dartium or (b) load compiled JS instead.  Previously,
 we've recommended that you add a script tag pointing the version of dart.js in
@@ -20,3 +25,15 @@
 In this case, you will need to update it yourself as necessary.  We reserve the
 right to move the old file in the repository, so we no longer recommend linking
 to it directly.
+
+interop.js
+==========
+
+This script was required for dart:js interop to work, but it is no longer
+needed. The functionality is now supported by dart:js directly.
+
+If you previously had a script such as this, please remove it:
+
+```html
+<script src="packages/browser/interop.js"></script>
+```
diff --git a/pkg/browser/lib/interop.js b/pkg/browser/lib/interop.js
index d7c7de6..ec02e58 100644
--- a/pkg/browser/lib/interop.js
+++ b/pkg/browser/lib/interop.js
@@ -2,9 +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.
 
-// Type for remote proxies to Dart objects with dart2js.
-// WARNING: do not call this constructor or rely on it being
-// in the global namespace, as it may be removed.
-function DartObject(o) {
-  this.o = o;
+// TODO(jmesserly): remove this script after a deprecation period.
+if (typeof console == "object" && typeof console.warn == "function") {
+  console.warn('<script src="packages/browser/interop.js"> is no longer ' +
+      'needed for dart:js. See http://pub.dartlang.org/packages/browser.');
 }
diff --git a/pkg/browser/pubspec.yaml b/pkg/browser/pubspec.yaml
index 88b59b9..87bc727 100644
--- a/pkg/browser/pubspec.yaml
+++ b/pkg/browser/pubspec.yaml
@@ -1,8 +1,8 @@
 name: browser
-version: 0.9.1
+version: 0.10.0-dev
 authors: ["Dart Team <misc@dartlang.org>"]
 homepage: http://www.dartlang.org
 description: >
  The bootstrap dart.js script for Dart apps running in the browser.
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.2.0-dev.6.0 <2.0.0"
diff --git a/pkg/code_transformers/AUTHORS b/pkg/code_transformers/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/code_transformers/AUTHORS
@@ -0,0 +1,9 @@
+# Names should be added to this file with this pattern:
+#
+# For individuals:
+#   Name <email address>
+#
+# For organizations:
+#   Organization <fnmatch pattern>
+#
+Google Inc. <*@google.com>
diff --git a/pkg/code_transformers/LICENSE b/pkg/code_transformers/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/code_transformers/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/code_transformers/PATENTS b/pkg/code_transformers/PATENTS
new file mode 100644
index 0000000..6954196
--- /dev/null
+++ b/pkg/code_transformers/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Dart Project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell,
+import, transfer, and otherwise run, modify and propagate the contents
+of this implementation of Dart, where such license applies only to
+those patent claims, both currently owned by Google and acquired in
+the future, licensable by Google that are necessarily infringed by
+this implementation of Dart. This grant does not include claims that
+would be infringed only as a consequence of further modification of
+this implementation. If you or your agent or exclusive licensee
+institute or order or agree to the institution of patent litigation
+against any entity (including a cross-claim or counterclaim in a
+lawsuit) alleging that this implementation of Dart or any code
+incorporated within this implementation of Dart constitutes direct or
+contributory patent infringement, or inducement of patent
+infringement, then any patent rights granted to you under this License
+for this implementation of Dart shall terminate as of the date such
+litigation is filed.
diff --git a/pkg/code_transformers/lib/resolver.dart b/pkg/code_transformers/lib/resolver.dart
new file mode 100644
index 0000000..739dd5a
--- /dev/null
+++ b/pkg/code_transformers/lib/resolver.dart
@@ -0,0 +1,10 @@
+// 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 working with resolved ASTs from Barback transformers.
+library code_transformers.resolver;
+
+export 'src/resolver_transformer.dart';
+export 'src/resolver.dart';
+export 'src/dart_sdk.dart';
diff --git a/pkg/code_transformers/lib/src/dart_sdk.dart b/pkg/code_transformers/lib/src/dart_sdk.dart
new file mode 100644
index 0000000..3b79f36
--- /dev/null
+++ b/pkg/code_transformers/lib/src/dart_sdk.dart
@@ -0,0 +1,49 @@
+// 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 code_transformers.src.dart_sdk;
+
+import 'dart:convert' as convert;
+import 'dart:io' show Directory, File, Platform, Process;
+import 'package:path/path.dart' as path;
+
+
+/// Attempts to provide the current Dart SDK directory.
+///
+/// This will return null if the SDK cannot be found
+///
+/// Note that this may not be correct when executing outside of `pub`.
+String get dartSdkDirectory {
+
+  bool isSdkDir(String dirname) =>
+      new File(path.join(dirname, 'lib', '_internal', 'libraries.dart'))
+        .existsSync();
+
+  if (path.split(Platform.executable).length == 1) {
+    // TODO(blois): make this cross-platform.
+    // HACK: A single part, hope it's on the path.
+    var result = Process.runSync('which', ['dart'],
+        stdoutEncoding: convert.UTF8);
+
+    var sdkDir = path.dirname(path.dirname(result.stdout));
+    if (isSdkDir(sdkDir)) return sdkDir;
+  }
+  var dartDir = path.dirname(path.absolute(Platform.executable));
+  // If there's a sub-dir named dart-sdk then we're most likely executing from
+  // a dart enlistment build directory.
+  if (isSdkDir(path.join(dartDir, 'dart-sdk'))) {
+    return path.join(dartDir, 'dart-sdk');
+  }
+  // If we can find libraries.dart then it's the root of the SDK.
+  if (isSdkDir(dartDir)) return dartDir;
+
+  var parts = path.split(dartDir);
+  // If the dart executable is within the sdk dir then get the root.
+  if (parts.contains('dart-sdk')) {
+    var dartSdkDir = path.joinAll(parts.take(parts.indexOf('dart-sdk') + 1));
+    if (isSdkDir(dartSdkDir)) return dartSdkDir;
+  }
+
+  return null;
+}
diff --git a/pkg/code_transformers/lib/src/resolver.dart b/pkg/code_transformers/lib/src/resolver.dart
new file mode 100644
index 0000000..80e385f
--- /dev/null
+++ b/pkg/code_transformers/lib/src/resolver.dart
@@ -0,0 +1,81 @@
+// 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 code_transformer.src.resolver;
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:barback/barback.dart';
+import 'package:source_maps/refactor.dart';
+import 'package:source_maps/span.dart' show SourceFile, Span;
+
+
+/// Class for working with a barback based resolved AST.
+abstract class Resolver {
+  /// The Dart entry point file where parsing begins.
+  AssetId get entryPoint;
+
+  /// Gets the resolved Dart library for the entry asset, or null if
+  /// the AST has not been resolved.
+  ///
+  /// If the AST has not been resolved then this normally means that the
+  /// transformer hosting this needs to be in an earlier phase.
+  LibraryElement get entryLibrary;
+
+  /// Gets all libraries accessible from the entry point, recursively.
+  ///
+  /// This includes all Dart SDK libraries as well.
+  Iterable<LibraryElement> get libraries;
+
+  /// Finds the first library identified by [libraryName], or null if no
+  /// library can be found.
+  LibraryElement getLibraryByName(String libraryName);
+
+  /// Finds the first library identified by [libraryName], or null if no
+  /// library can be found.
+  ///
+  /// [uri] must be an absolute URI of the form
+  /// `[dart:|package:]path/file.dart`.
+  LibraryElement getLibraryByUri(Uri uri);
+
+  /// Resolves a fully-qualified type name (library_name.ClassName).
+  ///
+  /// This will resolve the first instance of [typeName], because of potential
+  /// library name conflicts the name is not guaranteed to be unique.
+  ClassElement getType(String typeName);
+
+  /// Resolves a fully-qualified top-level library variable
+  /// (library_name.variableName).
+  ///
+  /// This will resolve the first instance of [variableName], because of
+  /// potential library name conflicts the name is not guaranteed to be unique.
+  Element getLibraryVariable(String variableName);
+
+  /// Resolves a fully-qualified top-level library function
+  /// (library_name.functionName).
+  ///
+  /// This will resolve the first instance of [functionName], because of
+  /// potential library name conflicts the name is not guaranteed to be unique.
+  Element getLibraryFunction(String functionName);
+
+  /// Gets an URI appropriate for importing the specified library.
+  ///
+  /// Returns null if the library cannot be imported via an absolute URI or
+  /// from [from] (if provided).
+  Uri getImportUri(LibraryElement lib, {AssetId from});
+
+  /// Get the asset ID of the file containing the asset.
+  AssetId getSourceAssetId(Element element);
+
+  /// Get the source span where the specified element was defined or null if
+  /// the element came from the Dart SDK.
+  Span getSourceSpan(Element element);
+
+  /// Creates a text edit transaction for the given element if it is able
+  /// to be edited, returns null otherwise.
+  ///
+  /// The transaction contains the entire text of the source file where the
+  /// element originated. If the element was from a library part then the
+  /// source file is the part file rather than the library.
+  TextEditTransaction createTextEditTransaction(Element element);
+}
diff --git a/pkg/code_transformers/lib/src/resolver_impl.dart b/pkg/code_transformers/lib/src/resolver_impl.dart
new file mode 100644
index 0000000..fe9f6d9
--- /dev/null
+++ b/pkg/code_transformers/lib/src/resolver_impl.dart
@@ -0,0 +1,547 @@
+// 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 code_transformer.src.resolver_impl;
+
+import 'dart:async';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/parser.dart' show Parser;
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:barback/barback.dart';
+import 'package:path/path.dart' as native_path;
+import 'package:source_maps/refactor.dart';
+import 'package:source_maps/span.dart' show SourceFile, Span;
+
+import 'resolver.dart';
+
+// We should always be using url paths here since it's always Dart/pub code.
+final path = native_path.url;
+
+/// Resolves and updates an AST based on Barback-based assets.
+///
+/// This also provides a handful of useful APIs for traversing and working
+/// with the resolved AST.
+class ResolverImpl implements Resolver {
+  /// Cache of all asset sources currently referenced.
+  final Map<AssetId, _AssetBasedSource> sources =
+      <AssetId, _AssetBasedSource>{};
+
+  /// The Dart entry point file where parsing begins.
+  final AssetId entryPoint;
+
+  final AnalysisContext _context =
+      AnalysisEngine.instance.createAnalysisContext();
+
+  /// Transform for which this is currently updating, or null when not updating.
+  Transform _currentTransform;
+
+  /// The currently resolved library, or null if unresolved.
+  LibraryElement _entryLibrary;
+
+  /// Handler for all Dart SDK (dart:) sources.
+  DirectoryBasedDartSdk _dartSdk;
+
+  /// Creates a resolver that will resolve the Dart code starting at
+  /// [entryPoint].
+  ///
+  /// [sdkDir] is the root directory of the Dart SDK, for resolving dart:
+  /// imports.
+  ResolverImpl(this.entryPoint, String sdkDir, {AnalysisOptions options}) {
+    if (options == null) {
+      options = new AnalysisOptionsImpl()
+        ..cacheSize = 256 // # of sources to cache ASTs for.
+        ..preserveComments = false
+        ..analyzeFunctionBodies = true;
+    }
+    _context.analysisOptions = options;
+
+    _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir));
+    _dartSdk.context.analysisOptions = options;
+
+    _context.sourceFactory = new SourceFactory.con2([
+        new DartUriResolverProxy(_dartSdk),
+        new _AssetUriResolver(this)]);
+  }
+
+  LibraryElement get entryLibrary => _entryLibrary;
+
+
+  /// Update the status of all the sources referenced by the entryPoint and
+  /// update the resolved library.
+  ///
+  /// This will be invoked automatically by [ResolverTransformer]. Only one
+  /// transformer may update this at a time.
+  Future updateSources(Transform transform) {
+    if (_currentTransform != null) {
+      throw new StateError('Cannot be accessed by concurrent transforms');
+    }
+    _currentTransform = transform;
+    // Clear this out and update once all asset changes have been processed.
+    _entryLibrary = null;
+
+    // Basic approach is to start at the first file, update it's contents
+    // and see if it changed, then walk all files accessed by it.
+    var visited = new Set<AssetId>();
+    var visiting = new FutureGroup();
+
+    void processAsset(AssetId assetId) {
+      visited.add(assetId);
+
+      visiting.add(transform.readInputAsString(assetId).then((contents) {
+        var source = sources[assetId];
+        if (source == null) {
+          source = new _AssetBasedSource(assetId, this);
+          sources[assetId] = source;
+        }
+        source.updateContents(contents);
+
+        source.dependentAssets
+            .where((id) => !visited.contains(id))
+            .forEach(processAsset);
+
+      }, onError: (e) {
+        _context.applyChanges(new ChangeSet()..removed(sources[assetId]));
+        sources.remove(assetId);
+      }));
+    }
+    processAsset(entryPoint);
+
+    // Once we have all asset sources updated with the new contents then
+    // resolve everything.
+    return visiting.future.then((_) {
+      var changeSet = new ChangeSet();
+      var unreachableAssets = new Set.from(sources.keys).difference(visited);
+      for (var unreachable in unreachableAssets) {
+        changeSet.removed(sources[unreachable]);
+        sources.remove(unreachable);
+      }
+
+      // Update the analyzer context with the latest sources
+      _context.applyChanges(changeSet);
+      // Resolve the AST
+      _entryLibrary = _context.computeLibraryElement(sources[entryPoint]);
+      _currentTransform = null;
+    });
+  }
+
+  Iterable<LibraryElement> get libraries => entryLibrary.visibleLibraries;
+
+  LibraryElement getLibraryByName(String libraryName) =>
+      libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
+
+  LibraryElement getLibraryByUri(Uri uri) =>
+      libraries.firstWhere((l) => getImportUri(l) == uri, orElse: () => null);
+
+  ClassElement getType(String typeName) {
+    var dotIndex = typeName.lastIndexOf('.');
+    var libraryName = dotIndex == -1 ? '' : typeName.substring(0, dotIndex);
+
+    var className = dotIndex == -1 ?
+        typeName : typeName.substring(dotIndex + 1);
+
+    for (var lib in libraries.where((l) => l.name == libraryName)) {
+      var type = lib.getType(className);
+      if (type != null) return type;
+    }
+    return null;
+  }
+
+  Element getLibraryVariable(String variableName) {
+    var dotIndex = variableName.lastIndexOf('.');
+    var libraryName = dotIndex == -1 ? '' : variableName.substring(0, dotIndex);
+
+    var name = dotIndex == -1 ?
+        variableName : variableName.substring(dotIndex + 1);
+
+    return libraries.where((lib) => lib.name == libraryName)
+        .expand((lib) => lib.units)
+        .expand((unit) => unit.topLevelVariables)
+        .firstWhere((variable) => variable.name == name,
+            orElse: () => null);
+  }
+
+  Element getLibraryFunction(String fnName) {
+    var dotIndex = fnName.lastIndexOf('.');
+    var libraryName = dotIndex == -1 ? '' : fnName.substring(0, dotIndex);
+
+    var name = dotIndex == -1 ?
+        fnName : fnName.substring(dotIndex + 1);
+
+    return libraries.where((lib) => lib.name == libraryName)
+        .expand((lib) => lib.units)
+        .expand((unit) => unit.functions)
+        .firstWhere((fn) => fn.name == name,
+            orElse: () => null);
+  }
+
+  Uri getImportUri(LibraryElement lib, {AssetId from}) =>
+      _getSourceUri(lib, from: from);
+
+
+  /// Similar to getImportUri but will get the part URI for parts rather than
+  /// the library URI.
+  Uri _getSourceUri(Element element, {AssetId from}) {
+    var source = element.source;
+    if (source is _AssetBasedSource) {
+      return source.getSourceUri(from);
+    } else if (source is _DartSourceProxy) {
+      return source.uri;
+    }
+    // Should not be able to encounter any other source types.
+    throw new StateError('Unable to resolve URI for ${source.runtimeType}');
+  }
+
+  AssetId getSourceAssetId(Element element) {
+    var source = element.source;
+    if (source is _AssetBasedSource) return source.assetId;
+    return null;
+  }
+
+  Span getSourceSpan(Element element) {
+    var sourceFile = _getSourceFile(element);
+    if (sourceFile == null) return null;
+    return sourceFile.span(element.node.offset, element.node.end);
+  }
+
+  TextEditTransaction createTextEditTransaction(Element element) {
+    if (element.source is! _AssetBasedSource) return null;
+
+    _AssetBasedSource source = element.source;
+    // Cannot modify assets in other packages.
+    if (source.assetId.package != entryPoint.package) return null;
+
+    var sourceFile = _getSourceFile(element);
+    if (sourceFile == null) return null;
+
+    return new TextEditTransaction(source.contents, sourceFile);
+  }
+
+  /// Gets the SourceFile for the source of the element.
+  SourceFile _getSourceFile(Element element) {
+    var assetId = getSourceAssetId(element);
+    if (assetId == null) return null;
+
+    var importUri = _getSourceUri(element, from: entryPoint);
+    var spanPath = importUri != null ? importUri.toString() : assetId.path;
+    return new SourceFile.text(spanPath, sources[assetId].contents);
+  }
+}
+
+/// Implementation of Analyzer's Source for Barback based assets.
+class _AssetBasedSource extends Source {
+
+  /// Asset ID where this source can be found.
+  final AssetId assetId;
+
+  /// The resolver this is being used in.
+  final ResolverImpl _resolver;
+
+  /// Cache of dependent asset IDs, to avoid re-parsing the AST.
+  Iterable<AssetId> _dependentAssets;
+
+  /// The current revision of the file, incremented only when file changes.
+  int _revision = 0;
+
+  /// The file contents.
+  String _contents;
+
+  _AssetBasedSource(this.assetId, this._resolver);
+
+  /// Update the contents of this file with [contents].
+  ///
+  /// Returns true if the contents of this asset have changed.
+  bool updateContents(String contents) {
+    if (contents == _contents) return false;
+    var added = _contents == null;
+    _contents = contents;
+    ++_revision;
+    // Invalidate the imports so we only parse the AST when needed.
+    _dependentAssets = null;
+
+    if (added) {
+      _resolver._context.applyChanges(new ChangeSet()..added(this));
+    } else {
+      _resolver._context.applyChanges(new ChangeSet()..changed(this));
+    }
+
+    var compilationUnit = _resolver._context.parseCompilationUnit(this);
+    _dependentAssets = compilationUnit.directives
+        .where((d) => (d is ImportDirective || d is PartDirective ||
+            d is ExportDirective))
+        .map((d) => _resolve(assetId, d.uri.stringValue,
+            _logger, _getSpan(d)))
+        .where((id) => id != null).toSet();
+    return true;
+  }
+
+  /// Contents of the file.
+  String get contents => _contents;
+
+  /// Logger for the current transform.
+  ///
+  /// Only valid while the resolver is updating assets.
+  TransformLogger get _logger => _resolver._currentTransform.logger;
+
+  /// Gets all imports/parts/exports which resolve to assets (non-Dart files).
+  Iterable<AssetId> get dependentAssets => _dependentAssets;
+
+  bool exists() => true;
+
+  bool operator ==(Object other) =>
+      other is _AssetBasedSource && assetId == other.assetId;
+
+  int get hashCode => assetId.hashCode;
+
+  void getContents(Source_ContentReceiver receiver) {
+    receiver.accept(contents, modificationStamp);
+  }
+
+  String get encoding =>
+      "${uriKind.encoding}${assetId.package}/${assetId.path}";
+
+  String get fullName => assetId.toString();
+
+  int get modificationStamp => _revision;
+
+  String get shortName => path.basename(assetId.path);
+
+  UriKind get uriKind {
+    if (assetId.path.startsWith('lib/')) return UriKind.PACKAGE_URI;
+    return UriKind.FILE_URI;
+  }
+
+  bool get isInSystemLibrary => false;
+
+  Source resolveRelative(Uri relativeUri) {
+    var id = _resolve(assetId, relativeUri.toString(), _logger, null);
+    if (id == null) return null;
+
+    // The entire AST should have been parsed and loaded at this point.
+    var source = _resolver.sources[id];
+    if (source == null) {
+      _logger.error('Could not load asset $id');
+    }
+    return source;
+  }
+
+  /// For logging errors.
+  Span _getSpan(ASTNode node) => _sourceFile.span(node.offset, node.end);
+  /// For logging errors.
+  SourceFile get _sourceFile {
+    var uri = getSourceUri(_resolver.entryPoint);
+    var path = uri != null ? uri.toString() : assetId.path;
+
+    return new SourceFile.text(path, contents);
+  }
+
+  /// Gets a URI which would be appropriate for importing this file.
+  ///
+  /// Note that this file may represent a non-importable file such as a part.
+  Uri getSourceUri([AssetId from]) {
+    if (!assetId.path.startsWith('lib/')) {
+      // Cannot do absolute imports of non lib-based assets.
+      if (from == null) return null;
+
+      if (assetId.package != from.package) return null;
+      return new Uri(
+          path: path.relative(assetId.path, from: path.dirname(from.path)));
+    }
+
+    return Uri.parse('package:${assetId.package}/${assetId.path.substring(4)}');
+  }
+}
+
+/// Implementation of Analyzer's UriResolver for Barback based assets.
+class _AssetUriResolver implements UriResolver {
+  final ResolverImpl _resolver;
+  _AssetUriResolver(this._resolver);
+
+  Source resolveAbsolute(ContentCache contentCache, Uri uri) {
+    var assetId = _resolve(null, uri.toString(), logger, null);
+    var source = _resolver.sources[assetId];
+    /// All resolved assets should be available by this point.
+    if (source == null) {
+      logger.error('Unable to find asset for "$uri"');
+    }
+    return source;
+  }
+
+  Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) =>
+      throw new UnsupportedError('fromEncoding is not supported');
+
+  Uri restoreAbsolute(Source source) =>
+      throw new UnsupportedError('restoreAbsolute is not supported');
+
+  TransformLogger get logger => _resolver._currentTransform.logger;
+}
+
+
+/// Dart SDK which wraps all Dart sources to ensure they are tracked with Uris.
+///
+/// Just a simple wrapper to make it easy to make sure that all sources we
+/// encounter are either _AssetBasedSource or _DartSourceProxy.
+class _DirectoryBasedDartSdkProxy extends DirectoryBasedDartSdk {
+  _DirectoryBasedDartSdkProxy(JavaFile sdkDirectory) : super(sdkDirectory);
+
+  Source mapDartUri(String dartUri) =>
+      _DartSourceProxy.wrap(super.mapDartUri(dartUri), Uri.parse(dartUri));
+}
+
+
+/// Dart SDK resolver which wraps all Dart sources to ensure they are tracked
+/// with URIs.
+class DartUriResolverProxy implements DartUriResolver {
+  final DartUriResolver _proxy;
+  DartUriResolverProxy(DirectoryBasedDartSdk sdk) :
+      _proxy = new DartUriResolver(sdk);
+
+  Source resolveAbsolute(ContentCache contentCache, Uri uri) =>
+    _DartSourceProxy.wrap(_proxy.resolveAbsolute(contentCache, uri), uri);
+
+  DartSdk get dartSdk => _proxy.dartSdk;
+
+  Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) =>
+      throw new UnsupportedError('fromEncoding is not supported');
+
+  Uri restoreAbsolute(Source source) =>
+      throw new UnsupportedError('restoreAbsolute is not supported');
+}
+
+/// Source file for dart: sources which track the sources with dart: URIs.
+///
+/// This is primarily to support [Resolver.getImportUri] for Dart SDK (dart:)
+/// based libraries.
+class _DartSourceProxy implements Source {
+
+  /// Absolute URI which this source can be imported from
+  final Uri uri;
+
+  /// Underlying source object.
+  final Source _proxy;
+
+  _DartSourceProxy(this._proxy, this.uri);
+
+  /// Ensures that [source] is a _DartSourceProxy.
+  static _DartSourceProxy wrap(Source source, Uri uri) {
+    if (source == null || source is _DartSourceProxy) return source;
+    return new _DartSourceProxy(source, uri);
+  }
+
+  Source resolveRelative(Uri relativeUri) {
+    // Assume that the type can be accessed via this URI, since these
+    // should only be parts for dart core files.
+    return wrap(_proxy.resolveRelative(relativeUri), uri);
+  }
+
+  bool exists() => _proxy.exists();
+
+  bool operator ==(Object other) =>
+    (other is _DartSourceProxy && _proxy == other._proxy);
+
+  int get hashCode => _proxy.hashCode;
+
+  void getContents(Source_ContentReceiver receiver) {
+    _proxy.getContents(receiver);
+  }
+
+  String get encoding => _proxy.encoding;
+
+  String get fullName => _proxy.fullName;
+
+  int get modificationStamp => _proxy.modificationStamp;
+
+  String get shortName => _proxy.shortName;
+
+  UriKind get uriKind => _proxy.uriKind;
+
+  bool get isInSystemLibrary => _proxy.isInSystemLibrary;
+}
+
+/// Get an asset ID for a URL relative to another source asset.
+AssetId _resolve(AssetId source, String url, TransformLogger logger,
+    Span span) {
+  if (url == null || url == '') return null;
+  var uri = Uri.parse(url);
+
+  if (uri.scheme == 'package') {
+    var segments = new List.from(uri.pathSegments);
+    var package = segments[0];
+    segments[0] = 'lib';
+    return new AssetId(package, segments.join(path.separator));
+  }
+  // Dart SDK libraries do not have assets.
+  if (uri.scheme == 'dart') return null;
+
+  if (uri.host != '' || uri.scheme != '' || path.isAbsolute(url)) {
+    logger.error('absolute paths not allowed: "$url"', span: span);
+    return null;
+  }
+
+  var targetPath = path.normalize(
+      path.join(path.dirname(source.path), url));
+  return new AssetId(source.package, targetPath);
+}
+
+
+/// A completer that waits until all added [Future]s complete.
+// TODO(blois): Copied from quiver. Remove from here when it gets
+// added to dart:core. (See #6626.)
+class FutureGroup<E> {
+  static const _FINISHED = -1;
+
+  int _pending = 0;
+  Future _failedTask;
+  final Completer<List> _completer = new Completer<List>();
+  final List results = [];
+
+  /** Gets the task that failed, if any. */
+  Future get failedTask => _failedTask;
+
+  /**
+   * Wait for [task] to complete.
+   *
+   * If this group has already been marked as completed, a [StateError] will be
+   * thrown.
+   *
+   * If this group has a [failedTask], new tasks will be ignored, because the
+   * error has already been signaled.
+   */
+  void add(Future task) {
+    if (_failedTask != null) return;
+    if (_pending == _FINISHED) throw new StateError("Future already completed");
+
+    _pending++;
+    var i = results.length;
+    results.add(null);
+    task.then((res) {
+      results[i] = res;
+      if (_failedTask != null) return;
+      _pending--;
+      if (_pending == 0) {
+        _pending = _FINISHED;
+        _completer.complete(results);
+      }
+    }, onError: (e, s) {
+      if (_failedTask != null) return;
+      _failedTask = task;
+      _completer.completeError(e, s);
+    });
+  }
+
+  /**
+   * A Future that complets with a List of the values from all the added
+   * tasks, when they have all completed.
+   *
+   * If any task fails, this Future will receive the error. Only the first
+   * error will be sent to the Future.
+   */
+  Future<List<E>> get future => _completer.future;
+}
diff --git a/pkg/code_transformers/lib/src/resolver_transformer.dart b/pkg/code_transformers/lib/src/resolver_transformer.dart
new file mode 100644
index 0000000..ed8325a
--- /dev/null
+++ b/pkg/code_transformers/lib/src/resolver_transformer.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library code_transformers.src.resolver_transformer;
+
+import 'dart:async';
+import 'package:barback/barback.dart';
+
+import 'resolver.dart';
+import 'resolver_impl.dart';
+
+/// Filter for whether the specified asset is an entry point to the Dart
+/// application.
+typedef EntryPointFilter(Asset input);
+
+/// Transformer which maintains up-to-date resolved ASTs for the specified
+/// code entry points.
+///
+/// This can used by transformers dependent on resolved ASTs which can reference
+/// this transformer to get the resolver needed.
+///
+/// This transformer must be in a phase before any dependent transformers. The
+/// resolve AST is automatically updated any time any dependent assets are
+/// changed.
+///
+/// This will only resolve the AST for code beginning from assets which are
+/// accepted by [entryPointFilter].
+///
+/// If multiple transformers rely on a resolved AST they should (ideally) share
+/// the same ResolverTransformer to avoid re-parsing the AST.
+class ResolverTransformer extends Transformer {
+  final Map<AssetId, Resolver> _resolvers = {};
+  final EntryPointFilter entryPointFilter;
+  final String dartSdkDirectory;
+
+  ResolverTransformer(this.dartSdkDirectory, this.entryPointFilter);
+
+  Future<bool> isPrimary(Asset input) =>
+      new Future.value(entryPointFilter(input));
+
+  /// Updates the resolved AST for the primary input of the transform.
+  Future apply(Transform transform) {
+    var resolver = getResolver(transform.primaryInput.id);
+
+    return resolver.updateSources(transform).then((_) {
+      transform.addOutput(transform.primaryInput);
+      return null;
+    });
+  }
+
+  /// Get a resolver for the AST starting from [id].
+  Resolver getResolver(AssetId id) =>
+      _resolvers.putIfAbsent(id, () => new ResolverImpl(id, dartSdkDirectory));
+}
diff --git a/pkg/code_transformers/lib/src/test_harness.dart b/pkg/code_transformers/lib/src/test_harness.dart
new file mode 100644
index 0000000..db53909
--- /dev/null
+++ b/pkg/code_transformers/lib/src/test_harness.dart
@@ -0,0 +1,124 @@
+// 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.
+
+/// Utilities for creating unit tests of Barback transformers.
+library code_transformers.src.test_harness;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:stack_trace/stack_trace.dart';
+import 'package:unittest/unittest.dart';
+
+String idToString(AssetId id) => '${id.package}|${id.path}';
+AssetId idFromString(String s) {
+  int index = s.indexOf('|');
+  return new AssetId(s.substring(0, index), s.substring(index + 1));
+}
+
+String _removeTrailingWhitespace(String str) =>
+    str.splitMapJoin('\n',
+        onNonMatch: (s) => s.replaceAll(new RegExp(r'\s+$'), ''));
+
+/// A helper package provider that has files stored in memory, also wraps
+/// [Barback] to simply our tests.
+class TestHelper implements PackageProvider {
+
+  /// Maps from an asset string identifier of the form 'package|path' to the
+  /// file contents.
+  final Map<String, String> files;
+  final Iterable<String> packages;
+  final List<String> messages;
+  int messagesSeen = 0;
+  bool errorSeen = false;
+
+  Barback barback;
+  var errorSubscription;
+  var resultSubscription;
+  var logSubscription;
+
+  Future<Asset> getAsset(AssetId id) =>
+      new Future.value(new Asset.fromString(id, files[idToString(id)]));
+
+  TestHelper(List<List<Transformer>> transformers, Map<String, String> files,
+      this.messages)
+      : files = files,
+        packages = files.keys.map((s) => idFromString(s).package) {
+    barback = new Barback(this);
+    for (var p in packages) {
+      barback.updateTransformers(p, transformers);
+    }
+
+    errorSubscription = barback.errors.listen((e) {
+      var trace = null;
+      if (e is Error) trace = e.stackTrace;
+      if (trace != null) {
+        print(Trace.format(trace));
+      }
+      fail('error running barback: $e');
+    });
+
+    resultSubscription = barback.results.listen((result) {
+      expect(result.succeeded, !errorSeen, reason: "${result.errors}");
+    });
+
+    logSubscription = barback.log.listen((entry) {
+      // Ignore info messages.
+      if (entry.level == LogLevel.INFO) return;
+      if (entry.level == LogLevel.ERROR) errorSeen = true;
+      // We only check messages when an expectation is provided.
+      if (messages == null) return;
+
+      var msg = '${entry.level.name.toLowerCase()}: ${entry.message}';
+      var span = entry.span;
+      var spanInfo = span == null ? '' :
+          ' (${span.sourceUrl} ${span.start.line} ${span.start.column})';
+      expect(messagesSeen, lessThan(messages.length),
+          reason: 'more messages than expected.\nMessage seen: $msg$spanInfo');
+      expect('$msg$spanInfo', messages[messagesSeen++]);
+    });
+  }
+
+  void tearDown() {
+    errorSubscription.cancel();
+    resultSubscription.cancel();
+    logSubscription.cancel();
+  }
+
+  /// Tells barback which files have changed, and thus anything that depends on
+  /// it on should be computed. By default mark all the input files.
+  void run([Iterable<String> paths]) {
+    if (paths == null) paths = files.keys;
+    barback.updateSources(paths.map(idFromString));
+  }
+
+  Future<String> operator [](String assetString){
+    return barback.getAssetById(idFromString(assetString))
+        .then((asset) => asset.readAsString());
+  }
+
+  Future check(String assetIdString, String content) {
+    return this[assetIdString].then((value) {
+      value = _removeTrailingWhitespace(value);
+      content = _removeTrailingWhitespace(content);
+      expect(value, content, reason: 'Final output of $assetIdString differs.');
+    });
+  }
+
+  Future checkAll(Map<String, String> files) {
+    return barback.results.first.then((_) {
+      if (files == null) return null;
+      var futures = [];
+      files.forEach((k, v) {
+        futures.add(check(k, v));
+      });
+      return Future.wait(futures);
+    }).then((_) {
+      // We only check messages when an expectation is provided.
+      if (messages == null) return;
+      expect(messages.length, messagesSeen,
+          reason: 'less messages than expected');
+    });
+  }
+}
diff --git a/pkg/code_transformers/lib/tests.dart b/pkg/code_transformers/lib/tests.dart
new file mode 100644
index 0000000..bd6886c
--- /dev/null
+++ b/pkg/code_transformers/lib/tests.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Collection of utilities which are useful for creating unit tests for
+/// Barback transformers.
+library code_transformers.tests;
+
+import 'dart:async' show Future;
+
+import 'package:barback/barback.dart' show Transformer;
+import 'package:unittest/unittest.dart';
+
+import 'src/test_harness.dart';
+
+/// Defines a test which invokes [applyTransformers].
+testPhases(String testName, List<List<Transformer>> phases,
+    Map<String, String> inputs, Map<String, String> results,
+    [List<String> messages]) {
+  test(testName,
+    () => applyTransformers(phases, inputs: inputs, results: results,
+        messages: messages));
+}
+
+/// Updates the provided transformers with [inputs] as asset inputs then
+/// validates that [results] were generated.
+///
+/// The keys for inputs and results are 'package_name|lib/file.dart'.
+/// Only files which are specified in results are validated.
+///
+/// If [messages] is non-null then this will validate that only the specified
+/// messages were generated, ignoring info messages.
+Future applyTransformers(List<List<Transformer>> phases,
+    {Map<String, String> inputs: const {},
+    Map<String, String> results: const {},
+    List<String> messages: const []}) {
+
+  var helper = new TestHelper(phases, inputs, messages)..run();
+  return helper.checkAll(results).then((_) => helper.tearDown());
+}
diff --git a/pkg/code_transformers/pubspec.yaml b/pkg/code_transformers/pubspec.yaml
new file mode 100644
index 0000000..c70470a
--- /dev/null
+++ b/pkg/code_transformers/pubspec.yaml
@@ -0,0 +1,14 @@
+name: code_transformers
+version: 0.0.1-dev
+author: "Dart Team <misc@dartlang.org>"
+description: Collection of utilities related to creating barback transformers.
+homepage: http://www.dartlang.org
+dependencies:
+  analyzer: ">=0.12.0 <0.13.0"
+  barback: ">=0.11.0 <0.12.0"
+  path: ">=0.9.0 <2.0.0"
+  source_maps: ">=0.9.0 <0.10.0"
+dev_dependencies:
+  unittest: ">=0.9.0 <0.10.0"
+environment:
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/code_transformers/test/resolver_test.dart b/pkg/code_transformers/test/resolver_test.dart
new file mode 100644
index 0000000..ab88291
--- /dev/null
+++ b/pkg/code_transformers/test/resolver_test.dart
@@ -0,0 +1,315 @@
+// 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 code_transformers.test.resolver_test;
+
+import 'dart:io' show File, Platform;
+
+import 'package:barback/barback.dart';
+import 'package:code_transformers/resolver.dart';
+import 'package:code_transformers/tests.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  useCompactVMConfiguration();
+
+  var sdkDir = dartSdkDirectory;
+  if (sdkDir == null) {
+    // If we cannot find the SDK dir, then assume this is being run from Dart's
+    // source directory and this script is the main script.
+    sdkDir = path.join(
+        path.dirname(path.fromUri(Platform.script)), '..', '..', '..', 'sdk');
+  }
+
+  var entryPoint = new AssetId('a', 'web/main.dart');
+  var transformer = new ResolverTransformer(sdkDir,
+      (asset) => asset.id == entryPoint);
+
+  var phases = [[transformer]];
+
+  group('Resolver', () {
+
+    test('should handle empty files', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var source = resolver.sources[entryPoint];
+            expect(source.modificationStamp, 1);
+
+            var lib = resolver.entryLibrary;
+            expect(lib, isNotNull);
+            expect(lib.entryPoint, isNull);
+          });
+    });
+
+    test('should update when sources change', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': ''' main() {} ''',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var source = resolver.sources[entryPoint];
+            expect(source.modificationStamp, 2);
+
+            var lib = resolver.entryLibrary;
+            expect(lib, isNotNull);
+            expect(lib.entryPoint, isNotNull);
+          });
+    });
+
+    test('should follow imports', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'a.dart';
+
+              main() {
+              } ''',
+            'a|web/a.dart': '''
+              library a;
+              ''',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var lib = resolver.entryLibrary;
+            expect(lib.importedLibraries.length, 2);
+            var libA = lib.importedLibraries.where((l) => l.name == 'a').single;
+            expect(libA.getType('Foo'), isNull);
+          });
+    });
+
+    test('should update changed imports', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'a.dart';
+
+              main() {
+              } ''',
+            'a|web/a.dart': '''
+              library a;
+              class Foo {}
+              ''',
+          }).then((_) {
+            var lib = transformer.getResolver(entryPoint).entryLibrary;
+            expect(lib.importedLibraries.length, 2);
+            var libA = lib.importedLibraries.where((l) => l.name == 'a').single;
+            expect(libA.getType('Foo'), isNotNull);
+          });
+    });
+
+    test('should follow package imports', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'package:b/b.dart';
+
+              main() {
+              } ''',
+            'b|lib/b.dart': '''
+              library b;
+              ''',
+          }).then((_) {
+            var lib = transformer.getResolver(entryPoint).entryLibrary;
+            expect(lib.importedLibraries.length, 2);
+            var libB = lib.importedLibraries.where((l) => l.name == 'b').single;
+            expect(libB.getType('Foo'), isNull);
+          });
+    });
+
+    test('should update on changed package imports', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'package:b/b.dart';
+
+              main() {
+              } ''',
+            'b|lib/b.dart': '''
+              library b;
+              class Bar {}
+              ''',
+          }).then((_) {
+            var lib = transformer.getResolver(entryPoint).entryLibrary;
+            expect(lib.importedLibraries.length, 2);
+            var libB = lib.importedLibraries.where((l) => l.name == 'b').single;
+            expect(libB.getType('Bar'), isNotNull);
+          });
+    });
+
+    test('should handle deleted files', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'package:b/b.dart';
+
+              main() {
+              } ''',
+          },
+          messages: [
+            'error: Unable to find asset for "package:b/b.dart"',
+            'error: Unable to find asset for "package:b/b.dart"',
+          ]).then((_) {
+            var lib = transformer.getResolver(entryPoint).entryLibrary;
+            expect(lib.importedLibraries.length, 1);
+          });
+    });
+
+    test('should fail on absolute URIs', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import '/b.dart';
+
+              main() {
+              } ''',
+          },
+          messages: [
+            // First from the AST walker
+            'error: absolute paths not allowed: "/b.dart" (main.dart 0 14)',
+            // Then two from the resolver.
+            'error: absolute paths not allowed: "/b.dart"',
+            'error: absolute paths not allowed: "/b.dart"',
+          ]).then((_) {
+            var lib = transformer.getResolver(entryPoint).entryLibrary;
+            expect(lib.importedLibraries.length, 1);
+          });
+    });
+
+    test('should list all libraries', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              library a.main;
+              import 'package:a/a.dart';
+              import 'package:a/b.dart';
+              ''',
+            'a|lib/a.dart': 'library a.a;\n import "package:a/c.dart";',
+            'a|lib/b.dart': 'library a.b;\n import "c.dart";',
+            'a|lib/c.dart': 'library a.c;'
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var libs = resolver.libraries.where((l) => !l.isInSdk);
+            expect(libs.map((l) => l.name), unorderedEquals([
+              'a.main',
+              'a.a',
+              'a.b',
+              'a.c',
+            ]));
+          });
+    });
+
+    test('should resolve types and library uris', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+              import 'dart:core';
+              import 'package:a/a.dart';
+              import 'package:a/b.dart';
+              import 'sub_dir/d.dart';
+              class Foo {}
+              ''',
+            'a|lib/a.dart': 'library a.a;\n import "package:a/c.dart";',
+            'a|lib/b.dart': 'library a.b;\n import "c.dart";',
+            'a|lib/c.dart': '''
+                library a.c;
+                class Bar {}
+                ''',
+            'a|web/sub_dir/d.dart': '''
+                library a.web.sub_dir.d;
+                class Baz{}
+                ''',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+
+            var a = resolver.getLibraryByName('a.a');
+            expect(a, isNotNull);
+            expect(resolver.getImportUri(a).toString(),
+                'package:a/a.dart');
+            expect(resolver.getLibraryByUri(Uri.parse('package:a/a.dart')), a);
+
+            var main = resolver.getLibraryByName('');
+            expect(main, isNotNull);
+            expect(resolver.getImportUri(main), isNull);
+
+            var fooType = resolver.getType('Foo');
+            expect(fooType, isNotNull);
+            expect(fooType.library, main);
+
+            var barType = resolver.getType('a.c.Bar');
+            expect(barType, isNotNull);
+            expect(resolver.getImportUri(barType.library).toString(),
+                'package:a/c.dart');
+            expect(resolver.getSourceAssetId(barType),
+                new AssetId('a', 'lib/c.dart'));
+
+            var bazType = resolver.getType('a.web.sub_dir.d.Baz');
+            expect(bazType, isNotNull);
+            expect(resolver.getImportUri(bazType.library), isNull);
+            expect(resolver
+                .getImportUri(bazType.library, from: entryPoint).toString(),
+                'sub_dir/d.dart');
+
+            var hashMap = resolver.getType('dart.collection.HashMap');
+            expect(resolver.getImportUri(hashMap.library).toString(),
+                'dart:collection');
+            expect(resolver.getLibraryByUri(Uri.parse('dart:collection')),
+                hashMap.library);
+
+          });
+    });
+
+    test('deleted files should be removed', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''import 'package:a/a.dart';''',
+            'a|lib/a.dart': '''import 'package:a/b.dart';''',
+            'a|lib/b.dart': '''class Engine{}''',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var engine = resolver.getType('Engine');
+            var uri = resolver.getImportUri(engine.library);
+            expect(uri.toString(), 'package:a/b.dart');
+          }).then((_) {
+            return applyTransformers(phases,
+              inputs: {
+                'a|web/main.dart': '''import 'package:a/a.dart';''',
+                'a|lib/a.dart': '''lib a;\n class Engine{}'''
+              });
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+            var engine = resolver.getType('Engine');
+            var uri = resolver.getImportUri(engine.library);
+            expect(uri.toString(), 'package:a/a.dart');
+
+            // Make sure that we haven't leaked any sources.
+            expect(resolver.sources.length, 2);
+          });
+    });
+
+    test('handles circular imports', () {
+      return applyTransformers(phases,
+          inputs: {
+            'a|web/main.dart': '''
+                library main;
+                import 'package:a/a.dart'; ''',
+            'a|lib/a.dart': '''
+                library a;
+                import 'package:a/b.dart'; ''',
+            'a|lib/b.dart': '''
+                library b;
+                import 'package:a/a.dart'; ''',
+          }).then((_) {
+            var resolver = transformer.getResolver(entryPoint);
+
+            var libs = resolver.libraries.map((lib) => lib.name);
+            expect(libs.contains('a'), isTrue);
+            expect(libs.contains('b'), isTrue);
+          });
+    });
+  });
+}
diff --git a/pkg/crypto/lib/src/crypto_utils.dart b/pkg/crypto/lib/src/crypto_utils.dart
index b593c0d..515c1e9 100644
--- a/pkg/crypto/lib/src/crypto_utils.dart
+++ b/pkg/crypto/lib/src/crypto_utils.dart
@@ -78,9 +78,9 @@
       out[j++] = lookup.codeUnitAt(x & 0x3f);
       // Add optional line separator for each 76 char output.
       if (addLineSeparator && ++c == 19 && j < outputLen - 2) {
-          out[j++] = CR;
-          out[j++] = LF;
-          c = 0;
+        out[j++] = CR;
+        out[j++] = LF;
+        c = 0;
       }
     }
 
@@ -117,7 +117,7 @@
       int c = _decodeTable[input.codeUnitAt(i)];
       if (c < 0) {
         extrasLen++;
-        if(c == -2) {
+        if (c == -2) {
           throw new FormatException('Invalid character: ${input[i]}');
         }
       }
@@ -138,10 +138,10 @@
     int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
     List<int> out = new List<int>(outputLen);
 
-    for (int i = 0, o = 0; o < outputLen;) {
+    for (int i = 0, o = 0; o < outputLen; ) {
       // Accumulate 4 valid 6 bit Base 64 characters into an int.
       int x = 0;
-      for (int j = 4; j > 0;) {
+      for (int j = 4; j > 0; ) {
         int c = _decodeTable[input.codeUnitAt(i++)];
         if (c >= 0) {
           x = ((x << 6) & 0xFFFFFF) | c;
diff --git a/pkg/crypto/lib/src/hash_utils.dart b/pkg/crypto/lib/src/hash_utils.dart
index 84df9d0..1d90e69 100644
--- a/pkg/crypto/lib/src/hash_utils.dart
+++ b/pkg/crypto/lib/src/hash_utils.dart
@@ -22,6 +22,15 @@
 // Base class encapsulating common behavior for cryptographic hash
 // functions.
 abstract class _HashBase implements Hash {
+  final int _chunkSizeInWords;
+  final int _digestSizeInWords;
+  final bool _bigEndianWords;
+  final List<int> _currentChunk;
+  final List<int> _h;
+  int _lengthInBytes = 0;
+  List<int> _pendingData;
+  bool _digestCalled = false;
+
   _HashBase(int chunkSizeInWords,
             int digestSizeInWords,
             bool this._bigEndianWords)
@@ -139,14 +148,4 @@
       _pendingData.addAll(_wordToBytes(0));
     }
   }
-
-  // Hasher state.
-  final int _chunkSizeInWords;
-  final int _digestSizeInWords;
-  final bool _bigEndianWords;
-  int _lengthInBytes = 0;
-  List<int> _pendingData;
-  final List<int> _currentChunk;
-  final List<int> _h;
-  bool _digestCalled = false;
 }
diff --git a/pkg/crypto/lib/src/hmac.dart b/pkg/crypto/lib/src/hmac.dart
index ba6cc11..a4ea193 100644
--- a/pkg/crypto/lib/src/hmac.dart
+++ b/pkg/crypto/lib/src/hmac.dart
@@ -12,12 +12,15 @@
  */
 // TODO(floitsch): make Hash implement Sink, EventSink or similar.
 class HMAC {
+  final List<int> _message;
+  Hash _hash;
+  List<int> _key;
   bool _isClosed = false;
 
   /**
    * Create an [HMAC] object from a [Hash] and a key.
    */
-  HMAC(Hash this._hash, List<int> this._key) : _message = [];
+  HMAC(Hash this._hash, List<int> this._key): _message = [];
 
   /**
    * Add a list of bytes to the message.
@@ -106,9 +109,4 @@
     }
     return result == 0;
   }
-
-  // HMAC internal state.
-  Hash _hash;
-  List<int> _key;
-  final List<int> _message;
 }
diff --git a/pkg/crypto/lib/src/md5.dart b/pkg/crypto/lib/src/md5.dart
index 6acf384..07b567e 100644
--- a/pkg/crypto/lib/src/md5.dart
+++ b/pkg/crypto/lib/src/md5.dart
@@ -11,7 +11,7 @@
  * required for backwards compatibility.
  */
 class MD5 extends _HashBase {
-  MD5() : super(16, 4, false) {
+  MD5(): super(16, 4, false) {
     _h[0] = 0x67452301;
     _h[1] = 0xefcdab89;
     _h[2] = 0x98badcfe;
diff --git a/pkg/crypto/lib/src/sha1.dart b/pkg/crypto/lib/src/sha1.dart
index f08c987..0b55b8d 100644
--- a/pkg/crypto/lib/src/sha1.dart
+++ b/pkg/crypto/lib/src/sha1.dart
@@ -8,6 +8,8 @@
  * SHA1 hash function implementation.
  */
 class SHA1 extends _HashBase {
+  final List<int> _w;
+
   // Construct a SHA1 hasher object.
   SHA1() : _w = new List(80), super(16, 5, true) {
     _h[0] = 0x67452301;
@@ -64,6 +66,4 @@
     _h[3] = _add32(d, _h[3]);
     _h[4] = _add32(e, _h[4]);
   }
-
-  List<int> _w;
 }
diff --git a/pkg/crypto/lib/src/sha256.dart b/pkg/crypto/lib/src/sha256.dart
index b429b8f..88b701e 100644
--- a/pkg/crypto/lib/src/sha256.dart
+++ b/pkg/crypto/lib/src/sha256.dart
@@ -8,6 +8,8 @@
  * SHA256 hash function implementation.
  */
 class SHA256 extends _HashBase {
+  final List<int> _w;
+
   // Construct a SHA256 hasher object.
   SHA256() : _w = new List(64), super(16, 8, true) {
     // Initial value of the hash parts. First 32 bits of the fractional parts
@@ -102,6 +104,4 @@
     _h[6] = _add32(g, _h[6]);
     _h[7] = _add32(h, _h[7]);
   }
-
-  final List<int> _w;
 }
diff --git a/pkg/crypto/pubspec.yaml b/pkg/crypto/pubspec.yaml
index f9d7d93..ff692ac 100644
--- a/pkg/crypto/pubspec.yaml
+++ b/pkg/crypto/pubspec.yaml
@@ -1,9 +1,10 @@
 name: crypto
-version: 0.9.0
-author: "Dart Team <misc@dartlang.org>"
+version: 0.9.1-dev
+author: Dart Team <misc@dartlang.org>
+description: Library of cryptographic functions.
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/crypto
-description: >
- Library of cryptographic functions.
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: '>=0.8.10+6 <2.0.0'
+documentation: http://api.dartlang.org/docs/pkg/crypto
+dev_dependencies:
+  unittest: '>=0.10.0 <0.11.0'
diff --git a/pkg/crypto/test/base64_test.dart b/pkg/crypto/test/base64_test.dart
index 9a58e3b..4215af99 100644
--- a/pkg/crypto/test/base64_test.dart
+++ b/pkg/crypto/test/base64_test.dart
@@ -5,27 +5,37 @@
 // Library tag to allow the test to run on Dartium.
 library base64_test;
 
-import "package:expect/expect.dart";
-import "package:crypto/crypto.dart";
 import 'dart:math';
 
+import "package:crypto/crypto.dart";
+import "package:unittest/unittest.dart";
+
+void main() {
+  test('encoder', _testEncoder);
+  test('decoder', _testDecoder);
+  test('decoder for malformed input', _testDecoderForMalformedInput);
+  test('encode decode lists', _testEncodeDecodeLists);
+  test('url safe encode-decode', _testUrlSafeEncodeDecode);
+  test('performance', _testPerformance);
+}
+
 // Data from http://tools.ietf.org/html/rfc4648.
-var inputs =
+const _INPUTS =
     const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar'];
-var results =
+const _RESULTS =
     const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy'];
 
 // Test data with only zeroes.
 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []];
-var resultsWithZeroes = ['AAAA', 'AAA=', 'AA==', ''];
+const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', ''];
 
-var longLine =
+const _LONG_LINE =
     "Man is distinguished, not only by his reason, but by this singular "
     "passion from other animals, which is a lust of the mind, that by a "
     "perseverance of delight in the continued and indefatigable generation "
     "of knowledge, exceeds the short vehemence of any carnal pleasure.";
 
-var longLineResult =
+const _LONG_LINE_RESULT =
     "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm"
     "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\r\n"
     "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci"
@@ -37,7 +47,7 @@
     "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm"
     "5hbCBwbGVhc3VyZS4=";
 
-var longLineResultNoBreak =
+const _LONG_LINE_RESULT_NO_BREAK =
     "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm"
     "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
     "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci"
@@ -49,55 +59,57 @@
     "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm"
     "5hbCBwbGVhc3VyZS4=";
 
-testEncoder() {
-  for (var i = 0; i < inputs.length; i++) {
-    Expect.equals(results[i], CryptoUtils.bytesToBase64(inputs[i].codeUnits));
+void _testEncoder() {
+  for (var i = 0; i < _INPUTS.length; i++) {
+    expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]);
   }
   for (var i = 0; i < inputsWithZeroes.length; i++) {
-    Expect.equals(resultsWithZeroes[i],
-        CryptoUtils.bytesToBase64(inputsWithZeroes[i]));
+    expect(CryptoUtils.bytesToBase64(inputsWithZeroes[i]),
+        _RESULTS_WITH_ZEROS[i]);
   }
-  Expect.equals(
-      CryptoUtils.bytesToBase64(longLine.codeUnits, addLineSeparator : true),
-      longLineResult);
-  Expect.equals(CryptoUtils.bytesToBase64(longLine.codeUnits),
-                longLineResultNoBreak);
+  expect(
+      CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits, addLineSeparator : true),
+      _LONG_LINE_RESULT);
+  expect(CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits),
+      _LONG_LINE_RESULT_NO_BREAK);
 }
 
-testDecoder() {
-  for (var i = 0; i < results.length; i++) {
-    Expect.equals(inputs[i],
-        new String.fromCharCodes(CryptoUtils.base64StringToBytes(results[i])));
+void _testDecoder() {
+  for (var i = 0; i < _RESULTS.length; i++) {
+    expect(
+        new String.fromCharCodes(CryptoUtils.base64StringToBytes(_RESULTS[i])),
+        _INPUTS[i]);
   }
-  for (var i = 0; i < resultsWithZeroes.length; i++) {
-    Expect.listEquals(inputsWithZeroes[i],
-        CryptoUtils.base64StringToBytes(resultsWithZeroes[i]));
+  for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) {
+    expect(CryptoUtils.base64StringToBytes(_RESULTS_WITH_ZEROS[i]),
+        inputsWithZeroes[i]);
   }
-  var longLineDecoded = CryptoUtils.base64StringToBytes(longLineResult);
-  Expect.equals(new String.fromCharCodes(longLineDecoded), longLine);
-  var longLineResultNoBreak = CryptoUtils.base64StringToBytes(longLineResult);
-  Expect.equals(new String.fromCharCodes(longLineResultNoBreak), longLine);
+  var longLineDecoded = CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT);
+  expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE);
+  var longLineResultNoBreak =
+      CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT);
+  expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE);
 }
 
-testDecoderForMalformedInput() {
-  Expect.throws(() {
-      CryptoUtils.base64StringToBytes('AB~');
-    }, (e) => e is FormatException);
+void _testDecoderForMalformedInput() {
+  expect(() {
+    CryptoUtils.base64StringToBytes('AB~');
+  }, throwsFormatException);
 
-  Expect.throws(() {
+  expect(() {
     CryptoUtils.base64StringToBytes('A');
-  }, (e) => e is FormatException);
+  }, throwsFormatException);
 }
 
-testUrlSafeEncodeDecode() {
+void _testUrlSafeEncodeDecode() {
   List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A=');
   List<int> dec = CryptoUtils.base64StringToBytes('+/A=');
-  Expect.listEquals(decUrlSafe, dec);
-  Expect.equals('-_A=', CryptoUtils.bytesToBase64(dec, urlSafe: true));
-  Expect.equals('+/A=', CryptoUtils.bytesToBase64(dec));
+  expect(decUrlSafe, dec);
+  expect(CryptoUtils.bytesToBase64(dec, urlSafe: true), '-_A=');
+  expect(CryptoUtils.bytesToBase64(dec), '+/A=');
 }
 
-testEncodeDecodeLists() {
+void _testEncodeDecodeLists() {
   for (int i = 0; i < 10; i++) {
     for (int j = 0; j < 256 - i; j++) {
       List<int> x = new List<int>(i);
@@ -106,22 +118,22 @@
       }
       var enc = CryptoUtils.bytesToBase64(x);
       var dec = CryptoUtils.base64StringToBytes(enc);
-      Expect.listEquals(x, dec);
+      expect(dec, x);
     }
   }
 }
 
-fillRandom(List<int> l) {
+void _fillRandom(List<int> l) {
   var random = new Random(0xBABE);
-  for(int j=0; j < l.length; j++) {
+  for (int j = 0; j < l.length; j++) {
     l[j] = random.nextInt(255);
   }
 }
 
-testPerformance() {
+void _testPerformance() {
     var l = new List<int>(1024);
     var iters = 5000;
-    fillRandom(l);
+    _fillRandom(l);
     String enc;
     var w = new Stopwatch()..start();
     for( int i = 0; i < iters; ++i ) {
@@ -139,12 +151,3 @@
     // print('''Decode into ${l.length} bytes for $iters
     //     times: $ms msec. $perSec b/s''');
 }
-
-void main() {
-  testEncoder();
-  testDecoder();
-  testDecoderForMalformedInput();
-  testEncodeDecodeLists();
-  testUrlSafeEncodeDecode();
-  testPerformance();
-}
diff --git a/pkg/crypto/test/hmac_md5_test.dart b/pkg/crypto/test/hmac_md5_test.dart
index 2d717b9..15b941f 100644
--- a/pkg/crypto/test/hmac_md5_test.dart
+++ b/pkg/crypto/test/hmac_md5_test.dart
@@ -5,11 +5,30 @@
 // Library tag to allow the test to run on Dartium.
 library hmac_md5_test;
 
-import "package:expect/expect.dart";
 import "package:crypto/crypto.dart";
+import "package:unittest/unittest.dart";
+
+void main() {
+  test('standard vectors', () {
+    _testStandardVectors(_HMAC_MD5_INPUTS, _HMAC_MD5_KEYS,
+        _HMAC_MD5_STRING_MACS, _HMAC_MD5_MACS);
+  });
+}
+
+void _testStandardVectors(inputs, keys, string_macs, macs) {
+  for (var i = 0; i < inputs.length; i++) {
+    var h = new HMAC(new MD5(), keys[i]);
+    h.add(inputs[i]);
+    var d = h.close();
+    expect(CryptoUtils.bytesToHex(d).startsWith(string_macs[i]), isTrue);
+    expect(h.verify(macs[i]), isTrue);
+    expect(h.verify(macs[(i + 1) % macs.length]), isFalse);
+    expect(() => h.verify([]), throws);
+  }
+}
 
 // Data from http://tools.ietf.org/html/rfc2202.
-var hmac_md5_inputs =
+const _HMAC_MD5_INPUTS =
     const [
       const [ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 ],
       const [ 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x79, 0x61,
@@ -42,7 +61,7 @@
               0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x44,
               0x61, 0x74, 0x61 ] ];
 
-var hmac_md5_keys =
+const _HMAC_MD5_KEYS =
     const [ const [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b],
             const [ 0x4a, 0x65, 0x66, 0x65 ],
@@ -72,7 +91,7 @@
                     0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                     0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa ] ];
 
-var hmac_md5_string_macs =
+const _HMAC_MD5_STRING_MACS =
     const [ '9294727a3638bb1c13f48ef8158bfc9d',
             '750c783e6ab0b503eaa86e310a5db738',
             '56be34521d144c88dbb8c733f0e8b3f6',
@@ -81,7 +100,7 @@
             '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd',
             '6f630fad67cda0ee1fb1f562db3aa53e' ];
 
-var hmac_md5_macs =
+const _HMAC_MD5_MACS =
     const [ const [0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4,
                    0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d],
             const [0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8,
@@ -96,20 +115,3 @@
                    0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd],
             const [0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1,
                    0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e]];
-
-void testStandardVectors(inputs, keys, string_macs, macs) {
-  for (var i = 0; i < inputs.length; i++) {
-    var h = new HMAC(new MD5(), keys[i]);
-    h.add(inputs[i]);
-    var d = h.close();
-    Expect.isTrue(CryptoUtils.bytesToHex(d).startsWith(string_macs[i]), '$i');
-    Expect.isTrue(h.verify(macs[i]));
-    Expect.isFalse(h.verify(macs[(i+1)%macs.length]));
-    Expect.throws(() => h.verify([]));
-  }
-}
-
-void main() {
-  testStandardVectors(hmac_md5_inputs, hmac_md5_keys,
-                      hmac_md5_string_macs, hmac_md5_macs);
-}
diff --git a/pkg/crypto/test/hmac_sha1_test.dart b/pkg/crypto/test/hmac_sha1_test.dart
index de79470..13ff34a 100644
--- a/pkg/crypto/test/hmac_sha1_test.dart
+++ b/pkg/crypto/test/hmac_sha1_test.dart
@@ -5,20 +5,23 @@
 // Library tag to allow the test to run on Dartium.
 library hmac_sha1_test;
 
-import "package:expect/expect.dart";
 import "package:crypto/crypto.dart";
+import "package:unittest/unittest.dart";
 
 part 'hmac_sha1_test_vectors.dart';
 
-void testStandardVectors(inputs, keys, macs) {
+
+void main() {
+  test('standard vectors', () {
+    _testStandardVectors(hmac_sha1_inputs, hmac_sha1_keys, hmac_sha1_macs);
+  });
+}
+
+void _testStandardVectors(inputs, keys, macs) {
   for (var i = 0; i < inputs.length; i++) {
     var hmac = new HMAC(new SHA1(), keys[i]);
     hmac.add(inputs[i]);
     var d = hmac.close();
-    Expect.isTrue(CryptoUtils.bytesToHex(d).startsWith(macs[i]), '$i');
+    expect(CryptoUtils.bytesToHex(d).startsWith(macs[i]), isTrue);
   }
 }
-
-void main() {
-  testStandardVectors(hmac_sha1_inputs, hmac_sha1_keys, hmac_sha1_macs);
-}
diff --git a/pkg/crypto/test/hmac_sha256_test.dart b/pkg/crypto/test/hmac_sha256_test.dart
index 73fa561..fa31420 100644
--- a/pkg/crypto/test/hmac_sha256_test.dart
+++ b/pkg/crypto/test/hmac_sha256_test.dart
@@ -5,20 +5,23 @@
 // Library tag to allow the test to run on Dartium.
 library hmac_sha256_test;
 
-import "package:expect/expect.dart";
+import "package:unittest/unittest.dart";
 import "package:crypto/crypto.dart";
 
 part 'hmac_sha256_test_vectors.dart';
 
-void testStandardVectors(inputs, keys, macs) {
+void main() {
+  test('standard vectors', () {
+    _testStandardVectors(hmac_sha256_inputs, hmac_sha256_keys,
+        hmac_sha256_macs);
+  });
+}
+
+void _testStandardVectors(inputs, keys, macs) {
   for (var i = 0; i < inputs.length; i++) {
     var hmac = new HMAC(new SHA256(), keys[i]);
     hmac.add(inputs[i]);
     var d = hmac.close();
-    Expect.isTrue(CryptoUtils.bytesToHex(d).startsWith(macs[i]), '$i');
+    expect(CryptoUtils.bytesToHex(d).startsWith(macs[i]), isTrue);
   }
 }
-
-void main() {
-  testStandardVectors(hmac_sha256_inputs, hmac_sha256_keys, hmac_sha256_macs);
-}
diff --git a/pkg/crypto/test/sha1_test.dart b/pkg/crypto/test/sha1_test.dart
index 7ce49c3..acfdad8 100644
--- a/pkg/crypto/test/sha1_test.dart
+++ b/pkg/crypto/test/sha1_test.dart
@@ -5,22 +5,27 @@
 // Library tag to allow dartium to run the test.
 library sha1_test;
 
-import "package:expect/expect.dart";
 import "package:crypto/crypto.dart";
+import "package:unittest/unittest.dart";
 
 part 'sha1_long_test_vectors.dart';
 part 'sha1_short_test_vectors.dart';
 
-List<int> createTestArr(int len) {
-  var arr = new List<int>(len);
-  for (var i = 0; i < len; i++) {
-    arr[i] = i;
-  }
-  return arr;
+
+void main() {
+  test('expected values', _testExpectedValues);
+  test('invalid use', _testInvalidUse);
+  test('repeated digest', _testRepeatedDigest);
+  test('long inputs', () {
+    _testStandardVectors(sha1_long_inputs, sha1_long_mds);
+  });
+  test('short inputs', () {
+    _testStandardVectors(sha1_short_inputs, sha1_short_mds);
+  });
 }
 
-void test() {
-  final expected_values = const [
+void _testExpectedValues() {
+  var expectedValues = const [
     "da39a3ee5e6b4b0d3255bfef95601890afd80709",
     "5ba93c9db0cff93f52b521d7420e43f6eda2784f",
     "3f29546453678b855931c174a97d6c0894b8f546",
@@ -534,39 +539,31 @@
     "3dce8306f3c1810d5d81ed5ebb0ccea947277a61",
     "11bca5b61fc1f6d59078ec5354bc6d9adecc0c5d",
   ];
-  for (var i = 0; i < expected_values.length; i++) {
+  for (var i = 0; i < expectedValues.length; i++) {
     var hash = new SHA1();
-    hash.add(createTestArr(i));
+    hash.add(new List<int>.generate(i, (j) => j, growable: false));
     var digest = hash.close();
-    Expect.equals(expected_values[i], CryptoUtils.bytesToHex(digest));
+    expect(expectedValues[i], CryptoUtils.bytesToHex(digest));
   }
 }
 
-void testInvalidUse() {
+void _testInvalidUse() {
   var sha = new SHA1();
   sha.close();
-  Expect.throws(() => sha.add([0]), (e) => e is StateError);
+  expect(() => sha.add([0]), throwsStateError);
 }
 
-void testRepeatedDigest() {
+void _testRepeatedDigest() {
   var sha = new SHA1();
   var digest = sha.close();
-  Expect.listEquals(digest, sha.close());
+  expect(digest, sha.close());
 }
 
-void testStandardVectors(inputs, mds) {
+void _testStandardVectors(inputs, mds) {
   for (var i = 0; i < inputs.length; i++) {
     var hash = new SHA1();
     hash.add(inputs[i]);
     var d = hash.close();
-    Expect.equals(mds[i], CryptoUtils.bytesToHex(d), '$i');
+    expect(mds[i], CryptoUtils.bytesToHex(d), reason: '$i');
   }
 }
-
-void main() {
-  test();
-  testInvalidUse();
-  testRepeatedDigest();
-  testStandardVectors(sha1_long_inputs, sha1_long_mds);
-  testStandardVectors(sha1_short_inputs, sha1_short_mds);
-}
diff --git a/pkg/crypto/test/sha256_test.dart b/pkg/crypto/test/sha256_test.dart
index 01bb4b8..e86a322 100644
--- a/pkg/crypto/test/sha256_test.dart
+++ b/pkg/crypto/test/sha256_test.dart
@@ -5,22 +5,25 @@
 // Library tag to allow Dartium to run the tests.
 library sha256_test;
 
-import "package:expect/expect.dart";
+import "package:unittest/unittest.dart";
 import "package:crypto/crypto.dart";
 
 part 'sha256_long_test_vectors.dart';
 part 'sha256_short_test_vectors.dart';
 
-List<int> createTestArr(int len) {
-  var arr = new List<int>(len);
-  for (var i = 0; i < len; i++) {
-    arr[i] = i;
-  }
-  return arr;
+
+void main() {
+  test('expected values', _testExpectedValues);
+  test('invalid use', _testInvalidUse);
+  test('repeated digest', _testRepeatedDigest);
+  test('long inputs',
+      () => _testStandardVectors(sha256_long_inputs, sha256_long_mds));
+  test('short inputs',
+      () => _testStandardVectors(sha256_short_inputs, sha256_short_mds));
 }
 
-void test() {
-  final expected_values = const [
+void _testExpectedValues() {
+  var expectedValues = const [
       'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
       '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d',
       'b413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2',
@@ -278,40 +281,31 @@
       'd6a8bdb01e763fb64f3a02512e7be905679a5add6bb408f8750d679d17cad92f',
       '3f8591112c6bbe5c963965954e293108b7208ed2af893e500d859368c654eabe' ];
 
-  for (var i = 0; i < expected_values.length; i++) {
+  for (var i = 0; i < expectedValues.length; i++) {
     var hash = new SHA256();
-    hash.add(createTestArr(i));
+    hash.add(new List<int>.generate(i, (j) => j, growable: false));
     var d = hash.close();
-    Expect.equals(expected_values[i], CryptoUtils.bytesToHex(d), '$i');
+    expect(expectedValues[i], CryptoUtils.bytesToHex(d), reason: '$i');
   }
 }
 
-void testInvalidUse() {
+void _testInvalidUse() {
   var sha = new SHA256();
   sha.close();
-  Expect.throws(() => sha.add([0]), (e) => e is StateError);
+  expect(() => sha.add([0]), throwsStateError);
 }
 
-void testRepeatedDigest() {
+void _testRepeatedDigest() {
   var sha = new SHA256();
   var digest = sha.close();
-  Expect.listEquals(digest, sha.close());
+  expect(digest, sha.close());
 }
 
-void testStandardVectors(inputs, mds) {
+void _testStandardVectors(inputs, mds) {
   for (var i = 0; i < inputs.length; i++) {
     var hash = new SHA256();
     hash.add(inputs[i]);
     var d = hash.close();
-    Expect.equals(mds[i], CryptoUtils.bytesToHex(d), '$i');
+    expect(mds[i], CryptoUtils.bytesToHex(d), reason: '$i');
   }
 }
-
-void main() {
-  test();
-  testInvalidUse();
-  testRepeatedDigest();
-  testStandardVectors(sha256_long_inputs, sha256_long_mds);
-  testStandardVectors(sha256_short_inputs, sha256_short_mds);
-}
-
diff --git a/pkg/docgen/bin/dartdoc.py b/pkg/docgen/bin/dartdoc.py
deleted file mode 100644
index 98955df..0000000
--- a/pkg/docgen/bin/dartdoc.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-# Run this script to generate documentation for a directory and serve
-# the results to localhost for viewing in the browser.
-
-import optparse
-import os
-from os.path import join, dirname, abspath, exists
-import platform
-import subprocess
-import sys
-sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
-import utils
-
-DIRECTORY = abspath(dirname(__file__))
-DART_DIR = dirname(dirname(dirname(DIRECTORY)))
-DART_EXECUTABLE = join(DART_DIR,
-    '%s/%s/dart-sdk/bin/dart' % (utils.BUILD_ROOT[utils.GuessOS()],
-    utils.GetBuildConf('release', utils.GuessArchitecture())))
-PUB = join(DART_DIR, 'sdk/bin/pub')
-DART2JS = join(DART_DIR, 'sdk/bin/dart2js')
-PACKAGE_ROOT = join(dirname(dirname(dirname(DART_EXECUTABLE[:-(len('dart'))]))),
-    'packages/')
-EXCLUDED_PACKAGES = ['browser', 'mutation_observer', 'pkg.xcodeproj']
-APPSERVER_EXECUTABLE = 'dev_appserver.py'
-
-
-def SetPackageRoot(path):
-  global PACKAGE_ROOT
-  if exists(path):
-    PACKAGE_ROOT = abspath(path)
-
-
-def ParseArgs():
-  parser = optparse.OptionParser(description='Generate documentation and '
-    'display the resulting documentation in the browser.')
-  parser.add_option('--full-docs-only', '-d', dest='just_docs',
-      action='store_true', default=False,
-      help='Only generate documentation, no html output. (If no other '
-      'options are specified, will document the SDK and all packages in the '
-      'repository.)')
-  parser.add_option('--package-root', '-p', dest='pkg_root',
-      help='The package root for dart (default is in the build directory).',
-      action='store', default=PACKAGE_ROOT)
-  parser.add_option('--docgen-options', '-o',
-      dest='docgen_options', help='Options to pass to docgen. If no file to '
-      'document is specified, by default we generate all documenation for the '
-      'SDK and all packages in the dart repository in JSON.',
-      default='--json')
-  parser.add_option('--gae-sdk',
-      help='The path to the Google App Engine SDK. Defaults to finding the '
-      'script in the PATH.', default='')
-  options, _ = parser.parse_args()
-  SetPackageRoot(options.pkg_root)
-  return options
-
-
-def AddUserDocgenOptions(sdk_cmd, docgen_options, all_docs=False):
-  '''Expand the command with user specified docgen options.'''
-  specified_pkg = False
-  remove_append = False
-  append = '--append'
-  for option in docgen_options:
-    if '--package-root' in option:
-      specified_pkg = True
-    if option == append and all_docs:
-      remove_append = True
-  if remove_append:
-    docgen_options.remove(append)
-  if not specified_pkg:
-    sdk_cmd.extend(['--package-root=%s' % PACKAGE_ROOT])
-  sdk_cmd.extend(docgen_options)
-  return sdk_cmd
-
-
-def GenerateAllDocs(docgen_options):
-  '''Generate all documentation for the SDK and all packages in the repository.
-  We first attempt to run the quickest path to generate all docs, but if that
-  fails, we fall back on a slower option.'''
-# TODO(alanknight): The --append option doesn't work properly. It overwrites
-# existing files with new information. Known symptom is that it loses subclasses
-# from the SDK and includes only the ones from pkg. So right now our only option
-# is to do everything in one pass.
-  doc_dir = join(DART_DIR, 'pkg')
-  cmd_lst = [DART_EXECUTABLE,
-      '--package-root=%s' % PACKAGE_ROOT, 'docgen.dart', '--include-sdk' ]
-  cmd_str = ' '.join(AddUserDocgenOptions(cmd_lst, docgen_options, True))
-  # Try to run all pkg docs together at once as it's fastest.
-  (return_code, _) = ExecuteCommandString('%s %s' % (cmd_str, doc_dir))
-  if return_code != 0:
-    # We failed to run all the pkg docs, so try to generate docs for each pkg
-    # individually.
-    failed_pkgs = []
-    for directory in os.listdir(join(DART_DIR, 'pkg')):
-      doc_dir = join(DART_DIR, 'pkg', directory)
-      if (directory not in EXCLUDED_PACKAGES and
-          os.path.isdir(doc_dir)):
-        (return_code, output) = ExecuteCommandString('%s %s' % (cmd_str,
-            doc_dir))
-        if return_code != 0:
-          failed_pkgs += [directory]
-    print ('Generated documentation, but failed to generate documentation for '
-        'the following packages, please investigate: %r' % failed_pkgs)
-
-
-def ExecuteCommandString(cmd):
-  '''A variant of the ExecuteCommand function that specifically executes a
-  particular command string in the shell context. When you execute a string, you
-  must execute in the shell.'''
-  print 'Executing: %s ' % cmd
-  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-      shell=True)
-  output = pipe.communicate()
-  return (pipe.returncode, output)
-
-
-def main():
-  options = ParseArgs()
-  generate_all_docs = True
-  docgen_options = []
-  if options.docgen_options:
-    # If the user specified particular files to generate docs for, then don't
-    # generate docs for everything.
-    docgen_options = options.docgen_options.split()
-    last_option = docgen_options[-1]
-    if '=' not in last_option and exists(last_option):
-      generate_all_docs = False
-      docgen = [DART_EXECUTABLE, '--checked',
-          '--package-root=' + PACKAGE_ROOT, join(DIRECTORY, 'docgen.dart')]
-      docgen.extend(options.options.split())
-      utils.ExecuteCommand(docgen)
-  if generate_all_docs:
-    GenerateAllDocs(docgen_options)
-  if not options.just_docs:
-    cwd = os.getcwd()
-    try:
-      utils.ExecuteCommand(['git', 'clone', '-b', 'master',
-       'git://github.com/dart-lang/dartdoc-viewer.git'])
-      utils.ExecuteCommand(['mv', 'docs', 'dartdoc-viewer/client/local'])
-      os.chdir('dartdoc-viewer/client/')
-      subprocess.call([PUB, 'install'])
-      subprocess.call([DART_EXECUTABLE, 'deploy.dart'])
-      if options.gae_sdk == '':
-        server = subprocess.Popen(' '.join([APPSERVER_EXECUTABLE, '..']),
-            shell=True)
-      else:
-        path_to_gae = options.gae_sdk
-        if not path_to_gae.endswith(APPSERVER_EXECUTABLE):
-          path_to_gae = join(path_to_gae, APPSERVER_EXECUTABLE)
-        server = subprocess.Popen(join(['python', path_to_gae, '..']))
-      print (
-        "\nPoint your browser to the address of the 'default' server below.")
-      raw_input("Press <RETURN> to terminate the server.\n\n")
-      server.terminate()
-    finally:
-      os.chdir(cwd)
-      subprocess.call(['rm', '-rf', 'dartdoc-viewer'])
-
-if __name__ == '__main__':
-  main()
diff --git a/pkg/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
index f89162a..fb506d5 100644
--- a/pkg/docgen/bin/docgen.dart
+++ b/pkg/docgen/bin/docgen.dart
@@ -6,16 +6,9 @@
 
 import 'package:args/args.dart';
 import 'package:logging/logging.dart';
-
-import '../lib/docgen.dart';
 import 'package:path/path.dart' as path;
 
-List<String> excludedLibraries = [];
-
-/**
- * The files/directories that we're being asked to document.
- */
-List<String> _files;
+import '../lib/docgen.dart';
 
 /**
  * Analyzes Dart files and generates a representation of included libraries,
@@ -23,11 +16,11 @@
  */
 void main(List<String> arguments) {
   var options = _initArgParser().parse(arguments);
-  _files = options.rest.map(path.normalize).toList();
-  if (_files.isEmpty) _printHelpAndExit();
+  var files = options.rest.map(path.normalize).toList();
+  if (files.isEmpty) _printHelpAndExit();
   var startPage = options['start-page'];
-  if (_singlePackage(_files) && startPage == null) {
-    startPage = _defaultStartPage;
+  if (_singlePackage(files) && startPage == null) {
+    startPage = _defaultStartPageFor(files);
     print("Using default options for documenting a single package: "
         "--start-page=$startPage");
   }
@@ -35,13 +28,16 @@
   var scriptDir = path.dirname(Platform.script.toFilePath());
   var introduction = includeSdk ? '' : options['introduction'];
 
-  var pubScript = options['sdk'] != null ? 
+  var pubScript = options['sdk'] != null ?
       path.join(options['sdk'], 'bin', 'pub') : 'pub';
 
-  var dartBinary = options['sdk'] != null ? 
+  var dartBinary = options['sdk'] != null ?
       path.join(options['sdk'], 'bin', 'dart') : 'dart';
 
-  docgen(_files,
+  var excludedLibraries = options['exclude-lib'];
+  if(excludedLibraries == null) excludedLibraries = [];
+
+  docgen(files,
       packageRoot: options['package-root'],
       outputToYaml: !options['json'],
       includePrivate: options['include-private'],
@@ -84,10 +80,10 @@
  * If we've specified just a package and no other command-line options,
  * use the single package name as the start page.
  */
-String get _defaultStartPage {
-    var pubspec = new File(path.join(_files.first, 'pubspec.yaml'));
-    if (!pubspec.existsSync()) return null;
-    return Library.packageNameFor(_files.first);
+String _defaultStartPageFor(files) {
+  var pubspec = new File(path.join(files.first, 'pubspec.yaml'));
+  if (!pubspec.existsSync()) return null;
+  return Library.packageNameFor(files.first);
 }
 
 /**
@@ -107,9 +103,9 @@
         if (verbose) Logger.root.level = Level.FINEST;
       });
   parser.addFlag('json', abbr: 'j',
-      help: 'Outputs to JSON. Files are outputted to YAML by default. '
+      help: 'Outputs to JSON. If negated, outputs to YAML. '
         'If --append is used, it takes the file-format of the previous '
-        'run stated in library_list.json ignoring the flag.',
+        'run stated in library_list.json, ignoring the flag.',
       negatable: true, defaultsTo: true);
   parser.addFlag('include-private',
       help: 'Flag to include private declarations.', negatable: false);
@@ -142,8 +138,7 @@
       defaultsTo: 'docs');
   parser.addOption('exclude-lib',
       help: 'Exclude the library by this name from the documentation',
-      allowMultiple: true,
-      callback: (libs) => excludedLibraries.addAll(libs));
+      allowMultiple: true);
   parser.addFlag('include-dependent-packages',
       help: 'Assumes we are documenting a single package and are running '
         'in the directory with its pubspec. Includes documentation for all '
@@ -153,7 +148,7 @@
       help: 'SDK directory',
       defaultsTo: null);
   parser.addOption('start-page',
-      help: 'By default the viewer will start at the SDK introduction page.'
+      help: 'By default the viewer will start at the SDK introduction page. '
         'To start at some other page, e.g. for a package, provide the name '
         'of the package in this argument, e.g. --start-page=intl will make '
         'the start page of the viewer be the intl package.',
diff --git a/pkg/docgen/bin/upload_docgen.py b/pkg/docgen/bin/upload_docgen.py
deleted file mode 100644
index c376dad..0000000
--- a/pkg/docgen/bin/upload_docgen.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/python
-#
-# 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 file will run docgen.dart on the SDK libraries, and upload them to
-  Google Cloud Storage for the documentation viewer.
-"""
-
-import optparse
-import os
-from os.path import join, dirname, abspath, exists
-import platform
-import subprocess
-import sys
-sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
-import utils
-
-
-DART = abspath(join(dirname(__file__), '../../../%s/%s/dart-sdk/bin/dart'
-    % (utils.BUILD_ROOT[utils.GuessOS()], utils.GetBuildConf('release',
-    utils.GuessArchitecture()))))
-PACKAGE_ROOT = abspath(join(dirname(__file__), '../../../%s/%s/packages/'
-    % (utils.BUILD_ROOT[utils.GuessOS()], utils.GetBuildConf('release',
-    utils.GuessArchitecture()))))
-GSUTIL = utils.GetBuildbotGSUtilPath()
-GS_SITE = 'gs://dartlang-docgen'
-DESCRIPTION='Runs docgen.dart on the SDK libraries, and uploads them to Google \
-    Cloud Storage for the dartdoc-viewer. '
-# Allow us to override checking SVN's revision number. Useful for development
-# so we can upload docs from a branch using an SDK that was built on a
-# revision newer than when the branch was forked.
-trustSVN = None
-
-def GetOptions():
-  parser = optparse.OptionParser(description=DESCRIPTION)
-  parser.add_option('--package-root', dest='pkg_root',
-    help='The package root for dart. (Default is in the build directory.)',
-    action='store', default=PACKAGE_ROOT)
-  parser.add_option('--dontTrustSVN', dest='dontTrustSVN', default=False,
-    help='Don''t rely on the SVN revision number, check the DART SDK instead',
-    action='store_true')
-  (options, args) = parser.parse_args()
-  SetPackageRoot(options.pkg_root)
-  trustSVN = not options.dontTrustSVN
-
-def SetPackageRoot(path):
-  global PACKAGE_ROOT
-  if exists(path):
-    PACKAGE_ROOT = abspath(path)
-
-
-def SetGsutil():
-  """ If not on buildbots, find gsutil relative to docgen. """
-  global GSUTIL
-  if not exists(GSUTIL):
-    GSUTIL = abspath(join(dirname(__file__),
-        '../../../third_party/gsutil/gsutil'))
-
-
-def Upload(source, target):
-  """ Upload files to Google Storage. """
-  cmd = [GSUTIL, '-m', 'cp', '-q', '-a', 'public-read', '-r', source, target]
-  (status, output) = utils.ExecuteCommand(cmd)
-  return status
-
-
-def main():
-  GetOptions()
-
-  SetGsutil()
-
-  # Execute Docgen.dart on the SDK.
-  utils.ExecuteCommand(['python', 'dartdoc.py', '-d'])
-
-  # Use SVN Revision to get the revision number.
-  revision = None
-  if trustSVN:
-    revision = utils.GetSVNRevision()
-
-  if revision is None:
-    # Try to find the version from the dart-sdk folder.
-    revision_file_location = abspath(join(dirname(__file__),
-        '../../../%s/%s/dart-sdk/revision' % (utils.BUILD_ROOT[utils.GuessOS()],
-        utils.GetBuildConf('release', utils.GuessArchitecture()))))
-    with open(revision_file_location, 'r') as revision_file:
-      revision = revision_file.readline(5)
-      revision_file.close()
-
-    if revision is None:
-      raise Exception("Unable to find revision. ")
-
-  # Upload the all files in Docs into a folder based off Revision number on
-  # Cloud Storage.
-  # TODO(alanknight): If we give it ./docs/* it fails to upload files in the
-  # subdirectory, probably due to escaping. Work around it by changing dir.
-  # Better, generalize this to be less dependent on the working directory.
-  os.chdir('docs')
-  Upload('.', GS_SITE + '/' + revision + '/')
-  os.chdir('..')
-
-  # Update VERSION file in Cloud Storage.
-  with open('VERSION', 'w') as version_file:
-    version_file.write(revision)
-    version_file.close()
-  Upload('./VERSION', GS_SITE + '/VERSION')
-  Upload('./VERSION', GS_SITE + '/' + revision + '/' + 'VERSION')
-
-  # Clean up the files it creates.
-  utils.ExecuteCommand(['rm', '-rf', './docs'])
-  utils.ExecuteCommand(['rm', '-f', './VERSION'])
-
-
-if __name__ == '__main__':
-  main()
diff --git a/pkg/docgen/doc/README.txt b/pkg/docgen/doc/README.txt
deleted file mode 100644
index e2af2a6..0000000
--- a/pkg/docgen/doc/README.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-The sdk-introduction.md file formerly in this directory has been moved 
-into the code in lib/docgen.dart so that it isn't dependent on this 
-directory struture. Any edits should be done to the DEFAULT_SDK_INTRODUCTION
-constant in that file.
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 541a8ac..2ec9f60 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -113,12 +113,13 @@
 ///
 /// Returned Future completes with true if document generation is successful.
 Future<bool> docgen(List<String> files, {String packageRoot,
-    bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
+    bool outputToYaml: false, bool includePrivate: false, bool includeSdk: false,
     bool parseSdk: false, bool append: false, String introFileName: '',
-    out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
-    bool includeDependentPackages: false, bool compile: false, bool serve: false,
-    bool noDocs: false, String startPage, 
-    String pubScript, String dartBinary}) {
+    String out: _DEFAULT_OUTPUT_DIRECTORY,
+    List<String> excludeLibraries : const [],
+    bool includeDependentPackages: false, bool compile: false,
+    bool serve: false, bool noDocs: false, String startPage, String pubScript,
+    String dartBinary}) {
   var result;
   if (!noDocs) {
     _Viewer.ensureMovedViewerCode();
@@ -136,7 +137,7 @@
           _createViewer(serve);
         }
       });
-    } 
+    }
   } else if (compile || serve) {
     _createViewer(serve);
   }
@@ -149,7 +150,7 @@
   if (serve) {
      _Viewer._runServer();
    }
-} 
+}
 
 /// Analyzes set of libraries by getting a mirror system and triggers the
 /// documentation of the libraries.
@@ -224,7 +225,7 @@
   DeclarationMirror get mirror;
 
   /// Returns a list of meta annotations assocated with a mirror.
-  List<Annotation> _createAnnotations(DeclarationMirror mirror,
+  static List<Annotation> _createAnnotations(DeclarationMirror mirror,
       Library owningLibrary) {
     var annotationMirrors = mirror.metadata.where((e) =>
         e is dart2js_mirrors.Dart2JsConstructedConstantMirror);
@@ -663,6 +664,37 @@
   static Directory _webDocsDir;
   static bool movedViewerCode = false;
 
+  static String _viewerCodePath;
+
+  /*
+   * dartdoc-viewer currently has the web app code under a 'client' directory
+   *
+   * This is confusing for folks that want to clone and modify the code.
+   * It also includes a number of python files and other content related to
+   * app engine hosting that are not needed.
+   *
+   * This logic exists to support the current model and a (future) updated
+   * dartdoc-viewer repo where the 'client' content exists at the root of the
+   * project and the other content is removed.
+   */
+  static String get viewerCodePath {
+    if(_viewerCodePath == null) {
+      var pubspecFileName = 'pubspec.yaml';
+
+      var thePath = _dartdocViewerDir.path;
+
+      if(!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) {
+        thePath = path.join(thePath, 'client');
+        if (!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) {
+          throw new StateError('Could not find a pubspec file');
+        }
+      }
+
+      _viewerCodePath = thePath;
+    }
+    return _viewerCodePath;
+  }
+
   /// If our dartdoc-viewer code is already checked out, move it to a temporary
   /// directory outside of the package directory, so we don't try to process it
   /// for documentation.
@@ -696,15 +728,14 @@
         /// Move the generated json/yaml docs directory to the dartdoc-viewer
         /// directory, to run as a webpage.
         var processResult = Process.runSync(_Generator._pubScript,
-            ['upgrade'], runInShell: true, 
-            workingDirectory: path.join(_dartdocViewerDir.path, 'client'));
+            ['upgrade'], runInShell: true,
+            workingDirectory: viewerCodePath);
         print('process output: ${processResult.stdout}');
         print('process stderr: ${processResult.stderr}');
 
         var dir = new Directory(_Generator._outputDirectory == null? 'docs' :
             _Generator._outputDirectory);
-        _webDocsDir = new Directory(path.join(_dartdocViewerDir.path, 'client',
-            'web', 'docs'));
+        _webDocsDir = new Directory(path.join(viewerCodePath, 'web', 'docs'));
         if (dir.existsSync()) {
           // Move the docs folder to dartdoc-viewer/client/web/docs
           dir.renameSync(_webDocsDir.path);
@@ -722,11 +753,10 @@
       // Compile the code to JavaScript so we can run on any browser.
       print('Compile app to JavaScript for viewing.');
       var processResult = Process.runSync(_Generator._dartBinary,
-          ['deploy.dart'], workingDirectory : path.join(_dartdocViewerDir.path,
-          'client'), runInShell: true);
+          ['deploy.dart'], workingDirectory: viewerCodePath, runInShell: true);
       print('process output: ${processResult.stdout}');
       print('process stderr: ${processResult.stderr}');
-      var outputDir = path.join(_dartdocViewerDir.path, 'client', 'out', 'web');
+      var outputDir = path.join(viewerCodePath, 'out', 'web');
       print('Docs are available at $outputDir');
     }
   }
@@ -735,13 +765,12 @@
   /// so it shouldn't have any external dependencies.
   static void _runServer() {
     // Launch a server to serve out of the directory dartdoc-viewer/client/web.
-    HttpServer.bind('localhost', 8080).then((HttpServer httpServer) {
+    HttpServer.bind(InternetAddress.ANY_IP_V6, 8080).then((HttpServer httpServer) {
       print('Server launched. Navigate your browser to: '
           'http://localhost:${httpServer.port}');
       httpServer.listen((HttpRequest request) {
         var response = request.response;
-        var basePath = path.join(_dartdocViewerDir.path, 'client', 'out',
-            'web');
+        var basePath = path.join(viewerCodePath, 'out', 'web');
         var requestPath = path.join(basePath, request.uri.path.substring(1));
         bool found = true;
         var file = new File(requestPath);
@@ -960,7 +989,9 @@
     var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
     if (comment != '') {
       var index = comment.indexOf('</p>');
-      finalMap['preview'] = '${comment.substring(0, index)}</p>';
+      finalMap['preview'] = index > 0 ?
+          '${comment.substring(0, index)}</p>' :
+          '<p><i>Comment preview not available</i></p>';
     }
     return finalMap;
   }
@@ -1388,16 +1419,16 @@
     if (_hasBeenCheckedForPackage) return packageName;
     _hasBeenCheckedForPackage = true;
     if (mirror.uri.scheme != 'file') return '';
-    // We assume that we are documenting only libraries under package/lib
     packageName = _packageName(mirror);
     // Associate the package readme with all the libraries. This is a bit
     // wasteful, but easier than trying to figure out which partial match
     // is best.
-    packageIntro = _packageIntro(_getRootdir(mirror));
+    packageIntro = _packageIntro(_getPackageDirectory(mirror));
     return packageName;
   }
 
   String _packageIntro(packageDir) {
+    if (packageDir == null) return null;
     var dir = new Directory(packageDir);
     var files = dir.listSync();
     var readmes = files.where((FileSystemEntity each) => (each is File &&
@@ -1415,17 +1446,49 @@
   }
 
   /// Given a LibraryMirror that is a library, return the name of the directory
-  /// holding that library.
-  static String _getRootdir(LibraryMirror mirror) =>
-      path.dirname(path.dirname(mirror.uri.toFilePath()));
+  /// holding the package information for that library. If the library is not
+  /// part of a package, return null.
+  static String _getPackageDirectory(LibraryMirror mirror) {
+    var file = mirror.uri.toFilePath();
+    // Any file that's in a package will be in a directory of the form
+    // packagename/lib/.../filename.dart, so we know that a possible
+    // package directory is at least in the directory above the one containing
+    // [file]
+    var directoryAbove = path.dirname(path.dirname(file));
+    var possiblePackage = _packageDirectoryFor(directoryAbove);
+    // We only want components that are somewhere underneath the lib directory.
+    var subPath = path.relative(file, from: possiblePackage);
+    var subPathComponents = path.split(subPath);
+    if (subPathComponents.isNotEmpty && subPathComponents.first == 'lib') {
+      return possiblePackage;
+    } else {
+      return null;
+    }
+  }
 
   /// Read a pubspec and return the library name given a [LibraryMirror].
   static String _packageName(LibraryMirror mirror) {
     if (mirror.uri.scheme != 'file') return '';
-    var rootdir = _getRootdir(mirror);
+    var rootdir = _getPackageDirectory(mirror);
+    if (rootdir == null) return '';
     return packageNameFor(rootdir);
   }
 
+  /// Recursively walk up from directory name looking for a pubspec. Return
+  /// the directory that contains it, or null if none is found.
+  static String _packageDirectoryFor(String directoryName) {
+    var dir = directoryName;
+    while (!_pubspecFor(dir).existsSync()) {
+      var newDir = path.dirname(dir);
+      if (newDir == dir) return null;
+      dir = newDir;
+    }
+    return dir;
+  }
+
+  static File _pubspecFor(String directoryName) =>
+      new File(path.join(directoryName, 'pubspec.yaml'));
+
   /// Read a pubspec and return the library name, given a directory
   static String packageNameFor(String directoryName) {
     var pubspecName = path.join(directoryName, 'pubspec.yaml');
@@ -1587,6 +1650,8 @@
     var parts = domName.split('.');
     if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
     if (parts.length == 1) return _mdnTypeComment(parts[0]);
+
+    throw new StateError('More than two items is not supported: $parts');
   }
 
   String get packagePrefix => owner.packagePrefix;
@@ -1665,7 +1730,7 @@
         dart2js_util.variablesOf(classMirror.declarations), this);
     methods = _createMethods(classMirror.declarations.values.where(
         (mirror) => mirror is MethodMirror), this);
-    annotations = _createAnnotations(classMirror, _getOwningLibrary(owner));
+    annotations = MirrorBased._createAnnotations(classMirror, _getOwningLibrary(owner));
     generics = _createGenerics(classMirror);
     isAbstract = classMirror.isAbstract;
     inheritedMethods = new Map<String, Method>();
@@ -1848,7 +1913,7 @@
     returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName;
     generics = _createGenerics(mirror);
     parameters = _createParameters(mirror.referent.parameters, owningLibrary);
-    annotations = _createAnnotations(mirror, owningLibrary);
+    annotations = MirrorBased._createAnnotations(mirror, owningLibrary);
   }
 
   Map toMap() => {
@@ -1892,7 +1957,7 @@
     isStatic = mirror.isStatic;
     isConst = mirror.isConst;
     type = new Type(mirror.type, _getOwningLibrary(owner));
-    annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
+    annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner));
   }
 
   String get name => _variableName;
@@ -1902,9 +1967,9 @@
     'name': name,
     'qualifiedName': qualifiedName,
     'comment': comment,
-    'final': isFinal.toString(),
-    'static': isStatic.toString(),
-    'constant': isConst.toString(),
+    'final': isFinal,
+    'static': isStatic,
+    'constant': isConst,
     'type': new List.filled(1, type.toMap()),
     'annotations': annotations.map((a) => a.toMap()).toList()
   };
@@ -1971,7 +2036,7 @@
     isConst = mirror.isConstConstructor;
     returnType = new Type(mirror.returnType, _getOwningLibrary(owner));
     parameters = _createParameters(mirror.parameters, owner);
-    annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
+    annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner));
   }
 
   Method get originallyInheritedFrom => methodInheritedFrom == null ?
@@ -2037,9 +2102,9 @@
         : commentInheritedFrom),
     'inheritedFrom': (methodInheritedFrom == null? '' :
         originallyInheritedFrom.docName),
-    'static': isStatic.toString(),
-    'abstract': isAbstract.toString(),
-    'constant': isConst.toString(),
+    'static': isStatic,
+    'abstract': isAbstract,
+    'constant': isConst,
     'return': new List.filled(1, returnType.toMap()),
     'parameters': recurseMap(parameters),
     'annotations': annotations.map((a) => a.toMap()).toList()
@@ -2082,32 +2147,32 @@
 /// Docgen wrapper around the dart2js mirror for a Dart
 /// method/function parameter.
 class Parameter extends MirrorBased {
-  ParameterMirror mirror;
-  String name;
-  bool isOptional;
-  bool isNamed;
-  bool hasDefaultValue;
-  Type type;
-  String defaultValue;
+  final ParameterMirror mirror;
+  final String name;
+  final bool isOptional;
+  final bool isNamed;
+  final bool hasDefaultValue;
+  final Type type;
+  final String defaultValue;
   /// List of the meta annotations on the parameter.
-  List<Annotation> annotations;
+  final List<Annotation> annotations;
 
-  Parameter(this.mirror, Library owningLibrary) {
-    name = dart2js_util.nameOf(mirror);
-    isOptional = mirror.isOptional;
-    isNamed = mirror.isNamed;
-    hasDefaultValue = mirror.hasDefaultValue;
-    defaultValue = '${mirror.defaultValue}';
-    type = new Type(mirror.type, owningLibrary);
-    annotations = _createAnnotations(mirror, owningLibrary);
-  }
+  Parameter(ParameterMirror mirror, Library owningLibrary)
+      : this.mirror = mirror,
+        name = dart2js_util.nameOf(mirror),
+        isOptional = mirror.isOptional,
+        isNamed = mirror.isNamed,
+        hasDefaultValue = mirror.hasDefaultValue,
+        defaultValue = '${mirror.defaultValue}',
+        type = new Type(mirror.type, owningLibrary),
+        annotations = MirrorBased._createAnnotations(mirror, owningLibrary);
 
   /// Generates a map describing the [Parameter] object.
   Map toMap() => {
     'name': name,
-    'optional': isOptional.toString(),
-    'named': isNamed.toString(),
-    'default': hasDefaultValue.toString(),
+    'optional': isOptional,
+    'named': isNamed,
+    'default': hasDefaultValue,
     'type': new List.filled(1, type.toMap()),
     'value': defaultValue,
     'annotations': annotations.map((a) => a.toMap()).toList()
@@ -2116,7 +2181,7 @@
 
 /// A Docgen wrapper around the dart2js mirror for a generic type.
 class Generic extends MirrorBased {
-  TypeVariableMirror mirror;
+  final TypeVariableMirror mirror;
   Generic(this.mirror);
   Map toMap() => {
     'name': dart2js_util.nameOf(mirror),
@@ -2154,8 +2219,8 @@
 ///                    - "outer" : "dart-core.int"
 ///                      "inner" :
 class Type extends MirrorBased {
-  TypeMirror mirror;
-  Library owningLibrary;
+  final TypeMirror mirror;
+  final Library owningLibrary;
 
   Type(this.mirror, this.owningLibrary);
 
@@ -2184,13 +2249,13 @@
 
 /// Holds the name of the annotation, and its parameters.
 class Annotation extends MirrorBased {
-  List<String> parameters;
   /// The class of this annotation.
-  ClassMirror mirror;
-  Library owningLibrary;
+  final ClassMirror mirror;
+  final Library owningLibrary;
+  List<String> parameters;
 
-  Annotation(InstanceMirror originalMirror, this.owningLibrary) {
-    mirror = originalMirror.type;
+  Annotation(InstanceMirror originalMirror, this.owningLibrary)
+      : mirror = originalMirror.type {
     parameters = dart2js_util.variablesOf(originalMirror.type.declarations)
         .where((e) => e.isFinal)
         .map((e) => originalMirror.getField(e.simpleName).reflectee)
diff --git a/pkg/docgen/pubspec.yaml b/pkg/docgen/pubspec.yaml
index 01d6d5e..78554ae 100644
--- a/pkg/docgen/pubspec.yaml
+++ b/pkg/docgen/pubspec.yaml
@@ -1,18 +1,19 @@
 name: docgen
-version: 0.9.1
-author: "Dart Team <misc@dartlang.org>"
-homepage: https://github.com/dart-lang/dartdoc-viewer
+version: 0.9.2-dev
+author: Dart Team <misc@dartlang.org>
 description: A documentation generator for the Dart repository.
+homepage: https://github.com/dart-lang/dartdoc-viewer
+environment:
+  sdk: '>=0.8.10+6 <2.0.0'
 dependencies:
-  args: ">=0.9.0 <0.10.0"
-  logging: ">=0.9.0 <0.10.0"
+  args: '>=0.9.0 <0.11.0'
+  logging: '>=0.9.0 <0.10.0'
   markdown:
     git:
       ref: emilysEdits
       url: https://github.com/efortuna/dart-markdown
-  path: ">=0.9.0 <2.0.0"
-  yaml: ">=0.9.0 <0.10.0"
+  path: '>=0.9.0 <2.0.0'
+  yaml: '>=0.9.0 <0.10.0'
 dev_dependencies:
-  unittest: ">=0.9.0 <0.10.0"
-environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  scheduled_test: '>=0.9.3 <0.10.0'
+  unittest: '>=0.9.0 <0.11.0'
diff --git a/pkg/docgen/test/generate_json_test.dart b/pkg/docgen/test/generate_json_test.dart
new file mode 100644
index 0000000..7b603ee
--- /dev/null
+++ b/pkg/docgen/test/generate_json_test.dart
@@ -0,0 +1,61 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:scheduled_test/descriptor.dart' as d;
+import 'package:scheduled_test/scheduled_test.dart';
+
+import 'util.dart';
+import '../lib/docgen.dart' as dg;
+
+void main() {
+
+  setUp(() {
+     var tempDir;
+     schedule(() {
+       return Directory.systemTemp
+           .createTemp('docgen_test-')
+           .then((dir) {
+         tempDir = dir;
+         d.defaultRoot = tempDir.path;
+       });
+     });
+
+     currentSchedule.onComplete.schedule(() {
+       d.defaultRoot = null;
+       return tempDir.delete(recursive: true);
+     });
+   });
+
+  test('json output', () {
+    print(d.defaultRoot);
+
+    schedule(() {
+      var codeDir = getMultiLibraryCodePath();
+      expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
+      return dg.docgen(['$codeDir/'], out: p.join(d.defaultRoot, 'docs'));
+    });
+
+    d.dir('docs', [
+        d.matcherFile('index.json', _isJsonMap),
+        d.matcherFile('index.txt', isNotNull),
+        d.matcherFile('library_list.json', _isJsonMap),
+        d.matcherFile('testLib-bar.C.json', _isJsonMap),
+        d.matcherFile('testLib-bar.json', _isJsonMap),
+        d.matcherFile('testLib.A.json', _isJsonMap),
+        d.matcherFile('testLib.B.json', _isJsonMap),
+        d.matcherFile('testLib.C.json', _isJsonMap),
+        d.matcherFile('testLib.json', _isJsonMap),
+        d.matcherFile('testLib2-foo.B.json', _isJsonMap),
+        d.matcherFile('testLib2-foo.json', _isJsonMap)
+    ]).validate();
+  });
+}
+
+final Matcher _isJsonMap = predicate((input) {
+  try {
+    return JSON.decode(input) is Map;
+  } catch (e) {
+    return false;
+  }
+}, 'Output is JSON encoded Map');
diff --git a/pkg/docgen/test/multi_library_code/lib/temp.dart b/pkg/docgen/test/multi_library_code/lib/temp.dart
new file mode 100644
index 0000000..694a8a7
--- /dev/null
+++ b/pkg/docgen/test/multi_library_code/lib/temp.dart
@@ -0,0 +1,36 @@
+library testLib;
+import 'temp2.dart';
+import 'temp3.dart';
+export 'temp2.dart';
+export 'temp3.dart';
+
+/**
+ * Doc comment for class [A].
+ *
+ * Multiline Test
+ */
+/*
+ * Normal comment for class A.
+ */
+class A {
+
+  int _someNumber;
+
+  A() {
+    _someNumber = 12;
+  }
+
+  A.customConstructor();
+
+  /**
+   * Test for linking to parameter [A]
+   */
+  void doThis(int A) {
+    print(A);
+  }
+}
+
+// A trivial use of `B` and `C` to eliminate import warnings
+B sampleMethod(C cInstance) {
+  throw new UnimplementedError();
+}
diff --git a/pkg/docgen/test/multi_library_code/lib/temp2.dart b/pkg/docgen/test/multi_library_code/lib/temp2.dart
new file mode 100644
index 0000000..ad62c09
--- /dev/null
+++ b/pkg/docgen/test/multi_library_code/lib/temp2.dart
@@ -0,0 +1,36 @@
+library testLib2.foo;
+import 'temp.dart';
+
+/**
+ * Doc comment for class [B].
+ *
+ * Multiline Test
+ */
+
+/*
+ * Normal comment for class B.
+ */
+class B extends A {
+
+  B();
+  B.fooBar();
+
+  /**
+   * Test for linking to super
+   */
+  int doElse(int b) {
+    print(b);
+    return b;
+  }
+
+  /**
+   * Test for linking to parameter [c]
+   */
+  void doThis(int c) {
+    print(c);
+  }
+}
+
+int testFunc(int a) {
+  return a;
+}
diff --git a/pkg/docgen/test/multi_library_code/lib/temp3.dart b/pkg/docgen/test/multi_library_code/lib/temp3.dart
new file mode 100644
index 0000000..01137e7
--- /dev/null
+++ b/pkg/docgen/test/multi_library_code/lib/temp3.dart
@@ -0,0 +1,13 @@
+library testLib.bar;
+import 'temp.dart';
+
+/*
+ * Normal comment for class C.
+ */
+class C {
+}
+
+// A trivial use of `A` to eliminate import warnings
+A usingImport() {
+  throw new UnimplementedError();
+}
diff --git a/pkg/docgen/test/multi_library_test.dart b/pkg/docgen/test/multi_library_test.dart
index 79a1431..7cb6fab 100644
--- a/pkg/docgen/test/multi_library_test.dart
+++ b/pkg/docgen/test/multi_library_test.dart
@@ -1,122 +1,31 @@
 library single_library_test;
 
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
+import 'package:path/path.dart' as p;
 import 'package:unittest/unittest.dart';
 
 import '../lib/docgen.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart'
     as dart2js_util;
 
-const String DART_LIBRARY_1 = '''
-  library testLib;
-  import 'temp2.dart';
-  import 'temp3.dart';
-  export 'temp2.dart';
-  export 'temp3.dart';
+import 'util.dart';
 
-  /**
-   * Doc comment for class [A].
-   *
-   * Multiline Test
-   */
-  /*
-   * Normal comment for class A.
-   */
-  class A {
+List<Uri> _writeLibFiles() {
+  var codePath = getMultiLibraryCodePath();
 
-    int _someNumber;
+  codePath = p.join(codePath, 'lib');
 
-    A() {
-      _someNumber = 12;
-    }
-
-    A.customConstructor();
-
-    /**
-     * Test for linking to parameter [A]
-     */
-    void doThis(int A) {
-      print(A);
-    }
-  }
-''';
-
-const String DART_LIBRARY_2 = '''
-  library testLib2.foo;
-  import 'temp.dart';
-
-  /**
-   * Doc comment for class [B].
-   *
-   * Multiline Test
-   */
-
-  /*
-   * Normal comment for class B.
-   */
-  class B extends A {
-
-    B();
-    B.fooBar();
-
-    /**
-     * Test for linking to super
-     */
-    int doElse(int b) {
-      print(b);
-    }
-
-    /**
-     * Test for linking to parameter [c]
-     */
-    void doThis(int c) {
-      print(a);
-    }
-  }
-
-  int testFunc(int a) {
-  }
-''';
-
-const String DART_LIBRARY_3 = '''
-  library testLib.bar;
-  import 'temp.dart';
-
-  /*
-   * Normal comment for class C.
-   */
-  class C {
-  }
-''';
-
-Directory TEMP_DIRNAME;
-
-List writeLibFiles() {
-  TEMP_DIRNAME = Directory.systemTemp.createTempSync('single_library_');
-  var fileName = path.join(TEMP_DIRNAME.path, 'temp.dart');
-  var file = new File(fileName);
-  file.writeAsStringSync(DART_LIBRARY_1);
-
-  var fileName2 = path.join(TEMP_DIRNAME.path, 'temp2.dart');
-  file = new File(fileName2);
-  file.writeAsStringSync(DART_LIBRARY_2);
-
-  var fileName3 = path.join(TEMP_DIRNAME.path, 'temp3.dart');
-  file = new File(fileName3);
-  file.writeAsStringSync(DART_LIBRARY_3);
-  return [new Uri.file(fileName, windows: Platform.isWindows),
-          new Uri.file(fileName2, windows: Platform.isWindows),
-          new Uri.file(fileName3, windows: Platform.isWindows)];
+  return ['temp.dart', 'temp2.dart', 'temp3.dart']
+      .map((name) => p.join(codePath, name))
+      .map(p.toUri)
+      .toList();
 }
 
-main() {
+void main() {
   group('Generate docs for', () {
     test('multiple libraries.', () {
-      var files = writeLibFiles();
-      getMirrorSystem(files)
-        .then(expectAsync1((mirrorSystem) {
+      var files = _writeLibFiles();
+      return getMirrorSystem(files)
+        .then((mirrorSystem) {
           var testLibraryUri = files[0];
           var library = new Library(mirrorSystem.libraries[testLibraryUri]);
 
@@ -175,7 +84,7 @@
               'testFunc').children.first.text;
           expect(methodParameterDocComment, 'testLib.testFunc');
 
-        })).whenComplete(() => TEMP_DIRNAME.deleteSync(recursive: true));
+        });
     });
   });
 }
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index ea5ad6b..1d7ded5 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -48,8 +48,9 @@
       var fileName = path.join(temporaryDir.path, 'temp.dart');
       var file = new File(fileName);
       file.writeAsStringSync(DART_LIBRARY);
-      getMirrorSystem([new Uri.file(fileName)])
-        .then(expectAsync1((mirrorSystem) {
+
+      return getMirrorSystem([new Uri.file(fileName)])
+        .then((mirrorSystem) {
           var testLibraryUri = new Uri.file(path.absolute(fileName),
                                             windows: Platform.isWindows);
           var library = new Library(mirrorSystem.libraries[testLibraryUri]);
@@ -121,7 +122,7 @@
           // Testing something with no reference
           var libraryDocComment = method.fixReference('foobar').text;
           expect(libraryDocComment, 'foobar');
-        })).whenComplete(() => temporaryDir.deleteSync(recursive: true));
+        }).whenComplete(() => temporaryDir.deleteSync(recursive: true));
     });
   });
 }
diff --git a/pkg/docgen/test/util.dart b/pkg/docgen/test/util.dart
new file mode 100644
index 0000000..fad786d
--- /dev/null
+++ b/pkg/docgen/test/util.dart
@@ -0,0 +1,11 @@
+import 'dart:io';
+import 'package:path/path.dart' as p;
+
+String getMultiLibraryCodePath() {
+  var currentScript = p.fromUri(Platform.script);
+  var codeDir = p.join(p.dirname(currentScript), 'multi_library_code');
+
+  assert(FileSystemEntity.isDirectorySync(codeDir));
+
+  return codeDir;
+}
diff --git a/pkg/intl/example/basic/messages_all.dart b/pkg/intl/example/basic/messages_all.dart
index 9265784..75f6d02 100644
--- a/pkg/intl/example/basic/messages_all.dart
+++ b/pkg/intl/example/basic/messages_all.dart
@@ -32,7 +32,8 @@
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
-  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
+  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null,
+      onFailure: (_) => null);
   if (actualLocale == null) return null;
   return _findExact(actualLocale);
 }
diff --git a/pkg/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
index aca18da..328b18d 100644
--- a/pkg/intl/lib/extract_messages.dart
+++ b/pkg/intl/lib/extract_messages.dart
@@ -282,8 +282,6 @@
     void setAttribute(MainMessage msg, String fieldName, String fieldValue) {
       if (["name", "desc", "examples", "args"].contains(fieldName)) {
         msg[fieldName] = fieldValue;
-      } else {
-        pluralOrGender[fieldName] = fieldValue;
       }
     }
     return _messageFromNode(node, extractFromPluralOrGender, setAttribute);
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 0dbd4bc..b5ccd28 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -107,7 +107,7 @@
       a.originalMessage.name.compareTo(b.originalMessage.name));
   for (var translation in usableTranslations) {
     result
-        .write("  ")
+        ..write("  ")
         ..write(translation.originalMessage.toCodeForLocale(locale))
         ..write("\n\n");
   }
@@ -226,7 +226,8 @@
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
-  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
+  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null,
+      onFailure: (_) => null);
   if (actualLocale == null) return null;
   return _findExact(actualLocale);
 }
diff --git a/pkg/intl/lib/intl.dart b/pkg/intl/lib/intl.dart
index 281d2fd..e6a3c7c 100644
--- a/pkg/intl/lib/intl.dart
+++ b/pkg/intl/lib/intl.dart
@@ -192,7 +192,10 @@
     // difficult. As a result, we call this more often. Consider keeping
     // verified locales for each purpose if it turns out to be a performance
     // issue.
-    if (newLocale == null) return getCurrentLocale();
+    if (newLocale == null) {
+      return verifiedLocale(getCurrentLocale(), localeExists,
+          onFailure: onFailure);
+    }
     if (localeExists(newLocale)) {
       return newLocale;
     }
@@ -269,7 +272,7 @@
       case 1 : return (one == null) ? other : one;
       case 2: return (two == null) ? ((few == null) ? other : few) : two;
       default:
-        if (howMany == 3 || howMany == 4 && few != null) return few;
+        if ((howMany == 3 || howMany == 4) && few != null) return few;
         if (howMany > 10 && howMany < 100 && many != null) return many;
         return other;
     }
diff --git a/pkg/intl/lib/src/intl_message.dart b/pkg/intl/lib/src/intl_message.dart
index a502326..b21c0b8 100644
--- a/pkg/intl/lib/src/intl_message.dart
+++ b/pkg/intl/lib/src/intl_message.dart
@@ -89,6 +89,11 @@
       return "The 'name' argument for Intl.message must be a simple string "
           "literal.";
     }
+    if (outerName != null && outerName != messageName.expression.value) {
+      return "The 'name' argument for Intl.message must match "
+          "the name of the containing function ("
+          "'${messageName.expression.value}' vs. '$outerName')";
+    }
     var simpleArguments = arguments.where(
         (each) => each is NamedExpression
         && ["desc", "name"].contains(each.name.label.name));
@@ -99,6 +104,7 @@
             "a simple string literal";
       }
     }
+    return null;
   }
 
   /**
@@ -351,7 +357,7 @@
    * the name.
    */
   String get name => _name == null ? computeName() : _name;
-  void set name(x) {_name = x;}
+  set name(String newName) { _name = newName; }
 
   String computeName() => name = expanded((msg, chunk) => "");
 
@@ -369,7 +375,7 @@
    * Record the translation for this message in the given locale, after
    * suitably escaping it.
    */
-  String addTranslation(String locale, Message translated) {
+  void addTranslation(String locale, Message translated) {
       translated.parent = this;
       translations[locale] = translated.toCode();
   }
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index 0b84918..448be7f 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,5 +1,5 @@
 name: intl
-version: 0.9.4
+version: 0.9.6
 author: Dart Team <misc@dartlang.org>
 description: Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
 homepage: http://www.dartlang.org
@@ -9,6 +9,6 @@
   path: ">=0.9.0 <2.0.0"
 dev_dependencies:
   serialization: ">=0.9.0 <0.10.0"
-  unittest: ">=0.9.0 <0.10.0"
+  unittest: ">=0.9.0 <0.11.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/intl/test/intl_test.dart b/pkg/intl/test/intl_test.dart
index d357188..268d765 100644
--- a/pkg/intl/test/intl_test.dart
+++ b/pkg/intl/test/intl_test.dart
@@ -34,4 +34,48 @@
     expect(Intl.canonicalizedLocale('xx_YYY'), 'xx_YYY');
     expect(Intl.canonicalizedLocale('C'), 'en_ISO');
   });
+
+  test("Verifying locale fallback for numbers", () {
+    expect(Intl.verifiedLocale('en-us', NumberFormat.localeExists), 'en_US');
+    expect(Intl.verifiedLocale('en_us', NumberFormat.localeExists), 'en_US');
+    expect(Intl.verifiedLocale('es-419', NumberFormat.localeExists), 'es_419');
+    expect(Intl.verifiedLocale('en-ZZ', NumberFormat.localeExists), 'en');
+    expect(Intl.verifiedLocale('es-999', NumberFormat.localeExists), 'es');
+
+    void checkAsNumberDefault(String locale, String expected) {
+      var oldDefault = Intl.defaultLocale;
+      Intl.defaultLocale = locale;
+      var format = new NumberFormat();
+      expect(format.locale, expected);
+      Intl.defaultLocale = oldDefault;
+    }
+
+    checkAsNumberDefault('en-us', 'en_US');
+    checkAsNumberDefault('en_us', 'en_US');
+    checkAsNumberDefault('es-419', 'es_419');
+    checkAsNumberDefault('en-ZZ', 'en');
+    checkAsNumberDefault('es-999', 'es');
+  });
+
+  test("Verifying locale fallback for dates", () {
+    expect(Intl.verifiedLocale('en-us', DateFormat.localeExists), 'en_US');
+    expect(Intl.verifiedLocale('en_us', DateFormat.localeExists), 'en_US');
+    expect(Intl.verifiedLocale('es-419', DateFormat.localeExists), 'es_419');
+    expect(Intl.verifiedLocale('en-ZZ', DateFormat.localeExists), 'en');
+    expect(Intl.verifiedLocale('es-999', DateFormat.localeExists), 'es');
+
+    void checkAsDateDefault(String locale, String expected) {
+      var oldDefault = Intl.defaultLocale;
+      Intl.defaultLocale = locale;
+      var format = new DateFormat();
+      expect(format.locale, expected);
+      Intl.defaultLocale = oldDefault;
+    }
+
+    checkAsDateDefault('en-us', 'en_US');
+    checkAsDateDefault('en_us', 'en_US');
+    checkAsDateDefault('es-419', 'es_419');
+    checkAsDateDefault('en-ZZ', 'en');
+    checkAsDateDefault('es-999', 'es');
+  });
 }
diff --git a/pkg/intl/test/message_extraction/foo_messages_all.dart b/pkg/intl/test/message_extraction/foo_messages_all.dart
index 1568a64..98e47e8 100644
--- a/pkg/intl/test/message_extraction/foo_messages_all.dart
+++ b/pkg/intl/test/message_extraction/foo_messages_all.dart
@@ -34,7 +34,8 @@
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
-  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
+  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null,
+      onFailure: (_) => null);
   if (actualLocale == null) return null;
   return _findExact(actualLocale);
 }
diff --git a/pkg/intl/test/message_extraction/foo_messages_de_DE.dart b/pkg/intl/test/message_extraction/foo_messages_de_DE.dart
index c790ed5..b561a3c 100644
--- a/pkg/intl/test/message_extraction/foo_messages_de_DE.dart
+++ b/pkg/intl/test/message_extraction/foo_messages_de_DE.dart
@@ -46,6 +46,8 @@
 
   static outerSelect(currency, amount) => "${Intl.select(currency, {'CDN': '$amount Kanadischen dollar', 'other': '$amount einige Währung oder anderen.', })}";
 
+  static pluralThatFailsParsing(noOfThings) => "${Intl.plural(noOfThings, one: 'eins:', other: '$noOfThings Dinge:')}";
+
   static plurals(num) => "${Intl.plural(num, zero: 'Ist Null Plural?', one: 'Dies ist einmalig', other: 'Dies ist Plural ($num).')}";
 
   static staticMessage() => "Dies ergibt sich aus einer statischen Methode";
@@ -74,10 +76,11 @@
     "outerGender" : outerGender,
     "outerPlural" : outerPlural,
     "outerSelect" : outerSelect,
+    "pluralThatFailsParsing" : pluralThatFailsParsing,
     "plurals" : plurals,
     "staticMessage" : staticMessage,
     "trickyInterpolation" : trickyInterpolation,
     "types" : types,
     "whereTheyWentMessage" : whereTheyWentMessage
   };
-}
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/foo_messages_fr.dart b/pkg/intl/test/message_extraction/foo_messages_fr.dart
index 58c71ce..b57a251 100644
--- a/pkg/intl/test/message_extraction/foo_messages_fr.dart
+++ b/pkg/intl/test/message_extraction/foo_messages_fr.dart
@@ -48,6 +48,8 @@
 
   static outerSelect(currency, amount) => "${Intl.select(currency, {'CDN': '$amount dollars Canadiens', 'other': '$amount certaine devise ou autre.', })}";
 
+  static pluralThatFailsParsing(noOfThings) => "${Intl.plural(noOfThings, one: '1 chose:', other: '$noOfThings choses:')}";
+
   static plurals(num) => "${Intl.plural(num, zero: 'Est-ce que nulle est pluriel?', one: 'C\'est singulier', other: 'C\'est pluriel ($num).')}";
 
   static staticMessage() => "Cela vient d\'une méthode statique";
@@ -77,10 +79,11 @@
     "outerGender" : outerGender,
     "outerPlural" : outerPlural,
     "outerSelect" : outerSelect,
+    "pluralThatFailsParsing" : pluralThatFailsParsing,
     "plurals" : plurals,
     "staticMessage" : staticMessage,
     "trickyInterpolation" : trickyInterpolation,
     "types" : types,
     "whereTheyWentMessage" : whereTheyWentMessage
   };
-}
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
index e958564..543ed6c 100644
--- a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
+++ b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
@@ -97,6 +97,11 @@
         ['female', 'femme'],
         ['other', 'autre'],
       ], null)),
+  "pluralThatFailsParsing" : writer.write(new Plural.from("noOfThings",
+      [
+        ['one', '1 chose:'],
+        ['other', '\$noOfThings choses:']
+      ], null)),
   "nestedOuter" : writer.write ( new Plural.from("number",
       [
         ['other', new Gender.from("gen",
@@ -183,6 +188,11 @@
         ['female', 'Frau'],
         ['other', 'andere'],
       ], null)),
+  "pluralThatFailsParsing" : writer.write(new Plural.from("noOfThings",
+      [
+        ['one', 'eins:'],
+        ['other', '\$noOfThings Dinge:']
+      ], null)),
   "nestedOuter" : writer.write (new Plural.from("number",
       [
         ['other', new Gender.from("gen",
diff --git a/pkg/intl/test/message_extraction/sample_with_messages.dart b/pkg/intl/test/message_extraction/sample_with_messages.dart
index e1a9ac3..ede88969 100644
--- a/pkg/intl/test/message_extraction/sample_with_messages.dart
+++ b/pkg/intl/test/message_extraction/sample_with_messages.dart
@@ -73,6 +73,13 @@
 outerGender(g) => Intl.gender(g, male: 'm', female: 'f', other: 'o',
     name: 'outerGender', desc: 'A gender with no enclosing message', args: [g]);
 
+pluralThatFailsParsing(noOfThings) => Intl.plural(noOfThings,
+    one: "1 thing:",
+    other: "$noOfThings things:",
+    name: "pluralThatFailsParsing",
+    args: [noOfThings],
+    desc: "How many things are there?");
+
 // A standalone gender message where we don't provide name or args. This should
 // be rejected by validation code.
 invalidOuterGender(g) => Intl.gender(g, other: 'o');
@@ -150,6 +157,19 @@
     printOut(thing.plurals(0));
     printOut(thing.plurals(1));
     printOut(thing.plurals(2));
+    printOut(thing.plurals(3));
+    printOut(thing.plurals(4));
+    printOut(thing.plurals(5));
+    printOut(thing.plurals(6));
+    printOut(thing.plurals(7));
+    printOut(thing.plurals(8));
+    printOut(thing.plurals(9));
+    printOut(thing.plurals(10));
+    printOut(thing.plurals(11));
+    printOut(thing.plurals(20));
+    printOut(thing.plurals(100));
+    printOut(thing.plurals(101));
+    printOut(thing.plurals(100000));
     var alice = new Person("Alice", "female");
     var bob = new Person("Bob", "male");
     var cat = new Person("cat", null);
@@ -171,6 +191,8 @@
     printOut(outerSelect("EUR", 5));
     printOut(nestedSelect("CDN", 1));
     printOut(nestedSelect("CDN", 2));
+    printOut(pluralThatFailsParsing(1));
+    printOut(pluralThatFailsParsing(2));
   });
 }
 
diff --git a/pkg/intl/test/message_extraction/verify_messages.dart b/pkg/intl/test/message_extraction/verify_messages.dart
index d368c36..f7be491 100644
--- a/pkg/intl/test/message_extraction/verify_messages.dart
+++ b/pkg/intl/test/message_extraction/verify_messages.dart
@@ -34,6 +34,19 @@
   verify('Is zero plural?');
   verify('This is singular.');
   verify('This is plural (2).');
+  verify('This is plural (3).');
+  verify('This is plural (4).');
+  verify('This is plural (5).');
+  verify('This is plural (6).');
+  verify('This is plural (7).');
+  verify('This is plural (8).');
+  verify('This is plural (9).');
+  verify('This is plural (10).');
+  verify('This is plural (11).');
+  verify('This is plural (20).');
+  verify('This is plural (100).');
+  verify('This is plural (101).');
+  verify('This is plural (100000).');
   verify('Alice went to her house');
   verify('Bob went to his house');
   verify('cat went to its litter box');
@@ -51,6 +64,8 @@
   verify('5 some currency or other.');
   verify('1 Canadian dollar');
   verify('2 Canadian dollars');
+  verify('1 thing:');
+  verify('2 things:');
 
   var fr_lines = expanded.skip(1).skipWhile(
       (line) => !line.contains('----')).toList();
@@ -81,6 +96,19 @@
   verify('Est-ce que nulle est pluriel?');
   verify('C\'est singulier');
   verify('C\'est pluriel (2).');
+  verify('C\'est pluriel (3).');
+  verify('C\'est pluriel (4).');
+  verify('C\'est pluriel (5).');
+  verify('C\'est pluriel (6).');
+  verify('C\'est pluriel (7).');
+  verify('C\'est pluriel (8).');
+  verify('C\'est pluriel (9).');
+  verify('C\'est pluriel (10).');
+  verify('C\'est pluriel (11).');
+  verify('C\'est pluriel (20).');
+  verify('C\'est pluriel (100).');
+  verify('C\'est pluriel (101).');
+  verify('C\'est pluriel (100000).');
   verify('Alice est allée à sa house');
   verify('Bob est allé à sa house');
   verify('cat est allé à sa litter box');
@@ -98,6 +126,8 @@
   verify('5 certaine devise ou autre.');
   verify('1 dollar Canadien');
   verify('2 dollars Canadiens');
+  verify('1 chose:');
+  verify('2 choses:');
 
   var de_lines = fr_lines.skip(1).skipWhile(
       (line) => !line.contains('----')).toList();
@@ -128,6 +158,19 @@
   verify('Ist Null Plural?');
   verify('Dies ist einmalig');
   verify('Dies ist Plural (2).');
+  verify('Dies ist Plural (3).');
+  verify('Dies ist Plural (4).');
+  verify('Dies ist Plural (5).');
+  verify('Dies ist Plural (6).');
+  verify('Dies ist Plural (7).');
+  verify('Dies ist Plural (8).');
+  verify('Dies ist Plural (9).');
+  verify('Dies ist Plural (10).');
+  verify('Dies ist Plural (11).');
+  verify('Dies ist Plural (20).');
+  verify('Dies ist Plural (100).');
+  verify('Dies ist Plural (101).');
+  verify('Dies ist Plural (100000).');
   verify('Alice ging zu ihrem house');
   verify('Bob ging zu seinem house');
   verify('cat ging zu seinem litter box');
@@ -145,4 +188,6 @@
   verify('5 einige Währung oder anderen.');
   verify('1 Kanadischer dollar');
   verify('2 Kanadischen dollar');
+  verify('eins:');
+  verify('2 Dinge:');
 }
diff --git a/pkg/oauth2/lib/src/handle_access_token_response.dart b/pkg/oauth2/lib/src/handle_access_token_response.dart
index 129f259..11a6fb9 100644
--- a/pkg/oauth2/lib/src/handle_access_token_response.dart
+++ b/pkg/oauth2/lib/src/handle_access_token_response.dart
@@ -34,7 +34,12 @@
   if (contentType != null) {
     contentType = ContentType.parse(contentType);
   }
-  validate(contentType != null && contentType.value == "application/json",
+
+  // The spec requires a content-type of application/json, but some endpoints
+  // (e.g. Dropbox) serve it as text/javascript instead.
+  validate(contentType != null &&
+      (contentType.value == "application/json" ||
+       contentType.value == "text/javascript"),
       'content-type was "$contentType", expected "application/json"');
 
   var parameters;
diff --git a/pkg/oauth2/test/handle_access_token_response_test.dart b/pkg/oauth2/test/handle_access_token_response_test.dart
index a99d8ea..c362868 100644
--- a/pkg/oauth2/test/handle_access_token_response_test.dart
+++ b/pkg/oauth2/test/handle_access_token_response_test.dart
@@ -138,6 +138,11 @@
       expect(credentials.accessToken, equals('access token'));
     });
 
+    test('with a JavScript content-type returns the correct credentials', () {
+      var credentials = handleSuccess(contentType: 'text/javascript');
+      expect(credentials.accessToken, equals('access token'));
+    });
+
     test('with a null access token throws a FormatException', () {
       expect(() => handleSuccess(accessToken: null), throwsFormatException);
     });
diff --git a/pkg/observe/lib/html.dart b/pkg/observe/lib/html.dart
index 2627531..07b4aff 100644
--- a/pkg/observe/lib/html.dart
+++ b/pkg/observe/lib/html.dart
@@ -6,14 +6,14 @@
 // In general, it seems like we want a convenient way to take a Stream plus a
 // getter and convert this into an Observable.
 
-/** Helpers for exposing dart:html as observable data. */
+/// Helpers for exposing dart:html as observable data.
 library observe.html;
 
 import 'dart:html';
 
 import 'observe.dart';
 
-/** An observable version of [window.location.hash]. */
+/// An observable version of [window.location.hash].
 final ObservableLocationHash windowLocation = new ObservableLocationHash._();
 
 class ObservableLocationHash extends ChangeNotifier {
@@ -33,10 +33,8 @@
 
   @reflectable String get hash => window.location.hash;
 
-  /**
-   * Pushes a new URL state, similar to the affect of clicking a link.
-   * Has no effect if the [value] already equals [window.location.hash].
-   */
+  /// Pushes a new URL state, similar to the affect of clicking a link.
+  /// Has no effect if the [value] already equals [window.location.hash].
   @reflectable void set hash(String value) {
     if (value == hash) return;
 
@@ -51,11 +49,9 @@
   }
 }
 
-/**
- * *Deprecated* use [CssClassSet.toggle] instead.
- *
- * Add or remove CSS class [className] based on the [value].
- */
+/// *Deprecated* use [CssClassSet.toggle] instead.
+///
+/// Add or remove CSS class [className] based on the [value].
 @deprecated
 void updateCssClass(Element element, String className, bool value) {
   if (value == true) {
@@ -65,12 +61,10 @@
   }
 }
 
-/**
- * *Deprecated* use `class="{{ binding }}"` in your HTML instead. It will also
- * work on a `<polymer-element>`.
- *
- * Bind a CSS class to the observable [object] and property [path].
- */
+/// *Deprecated* use `class="{{ binding }}"` in your HTML instead. It will also
+/// work on a `<polymer-element>`.
+///
+/// Bind a CSS class to the observable [object] and property [path].
 @deprecated
 PathObserver bindCssClass(Element element, String className,
     Observable object, String path) {
diff --git a/pkg/observe/lib/observe.dart b/pkg/observe/lib/observe.dart
index 1dd83b8..3b7c138 100644
--- a/pkg/observe/lib/observe.dart
+++ b/pkg/observe/lib/observe.dart
@@ -2,79 +2,77 @@
 // for 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 observing changes in model-view architectures.
- *
- * **Warning:** This library is experimental, and APIs are subject to change.
- *
- * This library is used to observe changes to [Observable] types. It also
- * has helpers to make implementing and using [Observable] objects easy.
- *
- * You can provide an observable object in two ways. The simplest way is to
- * use dirty checking to discover changes automatically:
- *
- *     class Monster extends Unit with Observable {
- *       @observable int health = 100;
- *
- *       void damage(int amount) {
- *         print('$this takes $amount damage!');
- *         health -= amount;
- *       }
- *
- *       toString() => 'Monster with $health hit points';
- *     }
- *
- *     main() {
- *       var obj = new Monster();
- *       obj.changes.listen((records) {
- *         print('Changes to $obj were: $records');
- *       });
- *       // No changes are delivered until we check for them
- *       obj.damage(10);
- *       obj.damage(20);
- *       print('dirty checking!');
- *       Observable.dirtyCheck();
- *       print('done!');
- *     }
- *
- * A more sophisticated approach is to implement the change notification
- * manually. This avoids the potentially expensive [Observable.dirtyCheck]
- * operation, but requires more work in the object:
- *
- *     class Monster extends Unit with ChangeNotifier {
- *       int _health = 100;
- *       @reflectable get health => _health;
- *       @reflectable set health(val) {
- *         _health = notifyPropertyChange(#health, _health, val);
- *       }
- *
- *       void damage(int amount) {
- *         print('$this takes $amount damage!');
- *         health -= amount;
- *       }
- *
- *       toString() => 'Monster with $health hit points';
- *     }
- *
- *     main() {
- *       var obj = new Monster();
- *       obj.changes.listen((records) {
- *         print('Changes to $obj were: $records');
- *       });
- *       // Schedules asynchronous delivery of these changes
- *       obj.damage(10);
- *       obj.damage(20);
- *       print('done!');
- *     }
- *
- * *Note*: it is good practice to keep `@reflectable` annotation on
- * getters/setters so they are accessible via reflection. This will preserve
- * them from tree-shaking. You can also put this annotation on the class and it
- * preserve all of its members for reflection.
- *
- * [Tools](https://www.dartlang.org/polymer-dart/) exist to convert the first
- * form into the second form automatically, to get the best of both worlds.
- */
+/// Support for observing changes in model-view architectures.
+///
+/// **Warning:** This library is experimental, and APIs are subject to change.
+///
+/// This library is used to observe changes to [Observable] types. It also
+/// has helpers to make implementing and using [Observable] objects easy.
+///
+/// You can provide an observable object in two ways. The simplest way is to
+/// use dirty checking to discover changes automatically:
+///
+///     class Monster extends Unit with Observable {
+///       @observable int health = 100;
+///
+///       void damage(int amount) {
+///         print('$this takes $amount damage!');
+///         health -= amount;
+///       }
+///
+///       toString() => 'Monster with $health hit points';
+///     }
+///
+///     main() {
+///       var obj = new Monster();
+///       obj.changes.listen((records) {
+///         print('Changes to $obj were: $records');
+///       });
+///       // No changes are delivered until we check for them
+///       obj.damage(10);
+///       obj.damage(20);
+///       print('dirty checking!');
+///       Observable.dirtyCheck();
+///       print('done!');
+///     }
+///
+/// A more sophisticated approach is to implement the change notification
+/// manually. This avoids the potentially expensive [Observable.dirtyCheck]
+/// operation, but requires more work in the object:
+///
+///     class Monster extends Unit with ChangeNotifier {
+///       int _health = 100;
+///       @reflectable get health => _health;
+///       @reflectable set health(val) {
+///         _health = notifyPropertyChange(#health, _health, val);
+///       }
+///
+///       void damage(int amount) {
+///         print('$this takes $amount damage!');
+///         health -= amount;
+///       }
+///
+///       toString() => 'Monster with $health hit points';
+///     }
+///
+///     main() {
+///       var obj = new Monster();
+///       obj.changes.listen((records) {
+///         print('Changes to $obj were: $records');
+///       });
+///       // Schedules asynchronous delivery of these changes
+///       obj.damage(10);
+///       obj.damage(20);
+///       print('done!');
+///     }
+///
+/// *Note*: it is good practice to keep `@reflectable` annotation on
+/// getters/setters so they are accessible via reflection. This will preserve
+/// them from tree-shaking. You can also put this annotation on the class and it
+/// preserve all of its members for reflection.
+///
+/// [Tools](https://www.dartlang.org/polymer-dart/) exist to convert the first
+/// form into the second form automatically, to get the best of both worlds.
 library observe;
 
 // This library contains code ported from observe-js:
diff --git a/pkg/observe/lib/src/bind_property.dart b/pkg/observe/lib/src/bind_property.dart
index 59f867f..b1d8918 100644
--- a/pkg/observe/lib/src/bind_property.dart
+++ b/pkg/observe/lib/src/bind_property.dart
@@ -7,25 +7,23 @@
 import 'dart:async';
 import 'package:observe/observe.dart';
 
-/**
- * Forwards an observable property from one object to another. For example:
- *
- *     class MyModel extends Observable {
- *       StreamSubscription _sub;
- *       MyOtherModel _otherModel;
- *
- *       MyModel() {
- *         ...
- *         _sub = onPropertyChange(_otherModel, #value,
- *             () => notifyProperty(this, #prop);
- *       }
- *
- *       String get prop => _otherModel.value;
- *       set prop(String value) { _otherModel.value = value; }
- *     }
- *
- * See also [notifyProperty].
- */
+/// Forwards an observable property from one object to another. For example:
+///
+///     class MyModel extends Observable {
+///       StreamSubscription _sub;
+///       MyOtherModel _otherModel;
+///
+///       MyModel() {
+///         ...
+///         _sub = onPropertyChange(_otherModel, #value,
+///             () => notifyProperty(this, #prop);
+///       }
+///
+///       String get prop => _otherModel.value;
+///       set prop(String value) { _otherModel.value = value; }
+///     }
+///
+/// See also [notifyProperty].
 // TODO(jmesserly): make this an instance method?
 StreamSubscription onPropertyChange(Observable source, Symbol sourceName,
     void callback()) {
diff --git a/pkg/observe/lib/src/change_notifier.dart b/pkg/observe/lib/src/change_notifier.dart
index 54653e9..7febee5 100644
--- a/pkg/observe/lib/src/change_notifier.dart
+++ b/pkg/observe/lib/src/change_notifier.dart
@@ -9,14 +9,12 @@
 import 'package:observe/observe.dart';
 import 'package:observe/src/observable.dart' show notifyPropertyChangeHelper;
 
-/**
- * Mixin and base class for implementing an [Observable] object that performs
- * its own change notifications, and does not need to be considered by
- * [Observable.dirtyCheck].
- *
- * When a field, property, or indexable item is changed, a derived class should
- * call [notifyPropertyChange]. See that method for an example.
- */
+/// Mixin and base class for implementing an [Observable] object that performs
+/// its own change notifications, and does not need to be considered by
+/// [Observable.dirtyCheck].
+///
+/// When a field, property, or indexable item is changed, a derived class should
+/// call [notifyPropertyChange]. See that method for an example.
 abstract class ChangeNotifier implements Observable {
   StreamController _changes;
   List<ChangeRecord> _records;
@@ -31,15 +29,11 @@
 
   // TODO(jmesserly): should these be public? They're useful lifecycle methods
   // for subclasses. Ideally they'd be protected.
-  /**
-   * Override this method to be called when the [changes] are first observed.
-   */
+  /// Override this method to be called when the [changes] are first observed.
   void observed() {}
 
-  /**
-   * Override this method to be called when the [changes] are no longer being
-   * observed.
-   */
+  /// Override this method to be called when the [changes] are no longer being
+  /// observed.
   void unobserved() {
     // Free some memory
     _changes = null;
@@ -55,27 +49,23 @@
     return false;
   }
 
-  /**
-   * True if this object has any observers, and should call
-   * [notifyPropertyChange] for changes.
-   */
+  /// True if this object has any observers, and should call
+  /// [notifyPropertyChange] for changes.
   bool get hasObservers => _changes != null && _changes.hasListener;
 
-  /**
-   * Notify that the field [name] of this object has been changed.
-   *
-   * The [oldValue] and [newValue] are also recorded. If the two values are
-   * equal, no change will be recorded.
-   *
-   * For convenience this returns [newValue]. This makes it easy to use in a
-   * setter:
-   *
-   *     var _myField;
-   *     @reflectable get myField => _myField;
-   *     @reflectable set myField(value) {
-   *       _myField = notifyPropertyChange(#myField, _myField, value);
-   *     }
-   */
+  /// Notify that the field [name] of this object has been changed.
+  ///
+  /// The [oldValue] and [newValue] are also recorded. If the two values are
+  /// equal, no change will be recorded.
+  ///
+  /// For convenience this returns [newValue]. This makes it easy to use in a
+  /// setter:
+  ///
+  ///     var _myField;
+  ///     @reflectable get myField => _myField;
+  ///     @reflectable set myField(value) {
+  ///       _myField = notifyPropertyChange(#myField, _myField, value);
+  ///     }
   notifyPropertyChange(Symbol field, Object oldValue, Object newValue)
       => notifyPropertyChangeHelper(this, field, oldValue, newValue);
 
diff --git a/pkg/observe/lib/src/change_record.dart b/pkg/observe/lib/src/change_record.dart
index 985e372..576a173 100644
--- a/pkg/observe/lib/src/change_record.dart
+++ b/pkg/observe/lib/src/change_record.dart
@@ -7,22 +7,22 @@
 import 'package:observe/observe.dart';
 
 
-/** Records a change to an [Observable]. */
+/// Records a change to an [Observable].
 // TODO(jmesserly): remove this type
 abstract class ChangeRecord {}
 
-/** A change record to a field of an observable object. */
+/// A change record to a field of an observable object.
 class PropertyChangeRecord<T> extends ChangeRecord {
-  /** The object that changed. */
+  /// The object that changed.
   final object;
 
-  /** The name of the property that changed. */
+  /// The name of the property that changed.
   final Symbol name;
 
-  /** The previous value of the property. */
+  /// The previous value of the property.
   final T oldValue;
 
-  /** The new value of the property. */
+  /// The new value of the property.
   final T newValue;
 
   PropertyChangeRecord(this.object, this.name, this.oldValue, this.newValue);
diff --git a/pkg/observe/lib/src/dirty_check.dart b/pkg/observe/lib/src/dirty_check.dart
index 8ab8c30..2084f22 100644
--- a/pkg/observe/lib/src/dirty_check.dart
+++ b/pkg/observe/lib/src/dirty_check.dart
@@ -2,22 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * *Warning*: this library is **internal**, and APIs are subject to change.
- *
- * Tracks observable objects for dirty checking and testing purposes.
- *
- * It can collect all observed objects, which can be used to trigger predictable
- * delivery of all pending changes in a test, including objects allocated
- * internally to another library, such as those in `package:template_binding`.
- */
+/// *Warning*: this library is **internal**, and APIs are subject to change.
+///
+/// Tracks observable objects for dirty checking and testing purposes.
+///
+/// It can collect all observed objects, which can be used to trigger
+/// predictable delivery of all pending changes in a test, including objects
+/// allocated internally to another library, such as those in
+/// `package:template_binding`.
 library observe.src.dirty_check;
 
 import 'dart:async';
 import 'package:logging/logging.dart';
 import 'package:observe/observe.dart' show Observable;
 
-/** The number of active observables in the system. */
+/// The number of active observables in the system.
 int get allObservablesCount => _allObservablesCount;
 
 int _allObservablesCount = 0;
@@ -32,12 +31,10 @@
   _allObservablesCount++;
 }
 
-/**
- * Synchronously deliver all change records for known observables.
- *
- * This will execute [Observable.deliverChanges] on objects that inherit from
- * [Observable].
- */
+/// Synchronously deliver all change records for known observables.
+///
+/// This will execute [Observable.deliverChanges] on objects that inherit from
+/// [Observable].
 // Note: this is called performMicrotaskCheckpoint in change_summary.js.
 void dirtyCheckObservables() {
   if (_delivering) return;
@@ -85,17 +82,13 @@
 
 const MAX_DIRTY_CHECK_CYCLES = 1000;
 
-/**
- * Log for messages produced at runtime by this library. Logging can be
- * configured by accessing Logger.root from the logging library.
- */
+/// Log for messages produced at runtime by this library. Logging can be
+/// configured by accessing Logger.root from the logging library.
 final Logger _logger = new Logger('Observable.dirtyCheck');
 
-/**
- * Creates a [ZoneSpecification] to set up automatic dirty checking after each
- * batch of async operations. This ensures that change notifications are always
- * delivered. Typically used via [dirtyCheckZone].
- */
+/// Creates a [ZoneSpecification] to set up automatic dirty checking after each
+/// batch of async operations. This ensures that change notifications are always
+/// delivered. Typically used via [dirtyCheckZone].
 ZoneSpecification dirtyCheckZoneSpec() {
   bool pending = false;
 
@@ -133,10 +126,8 @@
       registerUnaryCallback: wrapUnaryCallback);
 }
 
-/**
- * Forks a [Zone] off the current one that does dirty-checking automatically
- * after each batch of async operations. Equivalent to:
- *
- *     Zone.current.fork(specification: dirtyCheckZoneSpec());
- */
+/// Forks a [Zone] off the current one that does dirty-checking automatically
+/// after each batch of async operations. Equivalent to:
+///
+///     Zone.current.fork(specification: dirtyCheckZoneSpec());
 Zone dirtyCheckZone() => Zone.current.fork(specification: dirtyCheckZoneSpec());
diff --git a/pkg/observe/lib/src/list_diff.dart b/pkg/observe/lib/src/list_diff.dart
index 67a9ff1..59a9698 100644
--- a/pkg/observe/lib/src/list_diff.dart
+++ b/pkg/observe/lib/src/list_diff.dart
@@ -7,30 +7,26 @@
 import 'dart:math' as math;
 import 'dart:collection' show UnmodifiableListView;
 
-/**
- * A summary of an individual change to a [List].
- *
- * Each delta represents that at the [index], [removed] sequence of items were
- * removed, and counting forward from [index], [addedCount] items were added.
- */
+/// A summary of an individual change to a [List].
+///
+/// Each delta represents that at the [index], [removed] sequence of items were
+/// removed, and counting forward from [index], [addedCount] items were added.
 class ListChangeRecord {
-  /** The list that changed. */
+  /// The list that changed.
   final List object;
 
-  /** The index of the change. */
+  /// The index of the change.
   int get index => _index;
 
-  /** The items removed, if any. Otherwise this will be an empty list. */
+  /// The items removed, if any. Otherwise this will be an empty list.
   List get removed => _unmodifiableRemoved;
   UnmodifiableListView _unmodifiableRemoved;
 
-  /**
-   * Mutable version of [removed], used during the algorithms as they are
-   * constructing the object.
-   */
+  /// Mutable version of [removed], used during the algorithms as they are
+  /// constructing the object.
   List _removed;
 
-  /** The number of items added. */
+  /// The number of items added.
   int get addedCount => _addedCount;
 
   // Note: conceptually these are final, but for convenience we increment it as
@@ -50,7 +46,7 @@
     return new ListChangeRecord._(object, index, removed, addedCount);
   }
 
-  /** Returns true if the provided index was changed by this operation. */
+  /// Returns true if the provided index was changed by this operation.
   bool indexChanged(key) {
     // If key isn't an int, or before the index, then it wasn't changed.
     if (key is! int || key < index) return false;
@@ -182,16 +178,14 @@
   return count;
 }
 
-/**
- * Lacking individual splice mutation information, the minimal set of
- * splices can be synthesized given the previous state and final state of an
- * array. The basic approach is to calculate the edit distance matrix and
- * choose the shortest path through it.
- *
- * Complexity: O(l * p)
- *   l: The length of the current array
- *   p: The length of the old array
- */
+/// Lacking individual splice mutation information, the minimal set of
+/// splices can be synthesized given the previous state and final state of an
+/// array. The basic approach is to calculate the edit distance matrix and
+/// choose the shortest path through it.
+///
+/// Complexity: O(l * p)
+///   l: The length of the current array
+///   p: The length of the old array
 List<ListChangeRecord> calcSplices(List current, int currentStart,
     int currentEnd, List old, int oldStart, int oldEnd) {
 
@@ -363,22 +357,20 @@
   return splices;
 }
 
-/**
- * We need to summarize change records. Consumers of these records want to
- * apply the batch sequentially, and ensure that they can find inserted
- * items by looking at that position in the list. This property does not
- * hold in our record-as-you-go records. Consider:
- *
- *     var model = toObservable(['a', 'b']);
- *     model.removeAt(1);
- *     model.insertAll(0, ['c', 'd', 'e']);
- *     model.removeRange(1, 3);
- *     model.insert(1, 'f');
- *
- * Here, we inserted some records and then removed some of them.
- * If someone processed these records naively, they would "play back" the
- * insert incorrectly, because those items will be shifted.
- */
+/// We need to summarize change records. Consumers of these records want to
+/// apply the batch sequentially, and ensure that they can find inserted
+/// items by looking at that position in the list. This property does not
+/// hold in our record-as-you-go records. Consider:
+///
+///     var model = toObservable(['a', 'b']);
+///     model.removeAt(1);
+///     model.insertAll(0, ['c', 'd', 'e']);
+///     model.removeRange(1, 3);
+///     model.insert(1, 'f');
+///
+/// Here, we inserted some records and then removed some of them.
+/// If someone processed these records naively, they would "play back" the
+/// insert incorrectly, because those items will be shifted.
 List<ListChangeRecord> projectListSplices(List list,
     List<ListChangeRecord> records) {
   if (records.length <= 1) return records;
diff --git a/pkg/observe/lib/src/list_path_observer.dart b/pkg/observe/lib/src/list_path_observer.dart
index 5c7f1be..44b2759 100644
--- a/pkg/observe/lib/src/list_path_observer.dart
+++ b/pkg/observe/lib/src/list_path_observer.dart
@@ -11,9 +11,7 @@
 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js
 // The main difference is we support anything on the rich Dart Iterable API.
 
-/**
- * Observes a path starting from each item in the list.
- */
+/// Observes a path starting from each item in the list.
 class ListPathObserver<E, P> extends ChangeNotifier {
   final ObservableList<E> list;
   final String _itemPath;
diff --git a/pkg/observe/lib/src/metadata.dart b/pkg/observe/lib/src/metadata.dart
index a1e4e15..16c6cca 100644
--- a/pkg/observe/lib/src/metadata.dart
+++ b/pkg/observe/lib/src/metadata.dart
@@ -4,51 +4,43 @@
 
 library observe.src.metadata;
 
-/**
- * Use `@observable` to make a field automatically observable, or to indicate
- * that a property is observable.
- */
+/// Use `@observable` to make a field automatically observable, or to indicate
+/// that a property is observable.
 const ObservableProperty observable = const ObservableProperty();
 
-/**
- * An annotation that is used to make a property observable.
- * Normally this is used via the [observable] constant, for example:
- *
- *     class Monster {
- *       @observable int health;
- *     }
- *
- * If needed, you can subclass this to create another annotation that will also
- * be treated as observable.
- */
+/// An annotation that is used to make a property observable.
+/// Normally this is used via the [observable] constant, for example:
+///
+///     class Monster {
+///       @observable int health;
+///     }
+///
+/// If needed, you can subclass this to create another annotation that will also
+/// be treated as observable.
 // Note: observable properties imply reflectable.
 class ObservableProperty {
   const ObservableProperty();
 }
 
 
-/**
- * Use `@reflectable` to make a type or member available to reflection in the
- * observe package. This is necessary to make the member visible to
- * [PathObserver], or similar systems, once the code is deployed.
- */
+/// Use `@reflectable` to make a type or member available to reflection in the
+/// observe package. This is necessary to make the member visible to
+/// [PathObserver], or similar systems, once the code is deployed.
 const Reflectable reflectable = const Reflectable();
 
-/**
- * An annotation that is used to make a type or member reflectable. This makes
- * it available to [PathObserver] at runtime. For example:
- *
- *     @reflectable
- *     class Monster extends ChangeNotifier {
- *       int _health;
- *       int get health => _health;
- *       ...
- *     }
- *     ...
- *       // This will work even if the code has been tree-shaken/minified:
- *       final monster = new Monster();
- *       new PathObserver(monster, 'health').changes.listen(...);
- */
+/// An annotation that is used to make a type or member reflectable. This makes
+/// it available to [PathObserver] at runtime. For example:
+///
+///     @reflectable
+///     class Monster extends ChangeNotifier {
+///       int _health;
+///       int get health => _health;
+///       ...
+///     }
+///     ...
+///       // This will work even if the code has been tree-shaken/minified:
+///       final monster = new Monster();
+///       new PathObserver(monster, 'health').changes.listen(...);
 class Reflectable {
   const Reflectable();
 }
diff --git a/pkg/observe/lib/src/observable.dart b/pkg/observe/lib/src/observable.dart
index 35e91c8..a1c7b65 100644
--- a/pkg/observe/lib/src/observable.dart
+++ b/pkg/observe/lib/src/observable.dart
@@ -7,14 +7,15 @@
 import 'dart:async';
 import 'dart:collection';
 
+// TODO(sigmund): figure out how to remove this annotation entirely
 // Note: ObservableProperty is in this list only for the unusual use case of
 // dart2js without deploy tool. The deploy tool (see "transformer.dart") will
 // add the @reflectable annotation, which makes it work with Polymer's
 // @published.
 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
-    override: 'observe.src.observable')
-import 'dart:mirrors';
-
+    override: 'smoke.mirrors')
+import 'dart:mirrors' show MirrorsUsed;
+import 'package:smoke/smoke.dart' as smoke;
 import 'package:observe/observe.dart';
 
 // Note: this is an internal library so we can import it from tests.
@@ -23,40 +24,33 @@
 // above.
 import 'dirty_check.dart';
 
-/**
- * Represents an object with observable properties. This is used by data in
- * model-view architectures to notify interested parties of [changes] to the
- * object's properties (fields or getter/setter pairs).
- *
- * The interface does not require any specific technique to implement
- * observability. You can implement it in the following ways:
- *
- * - extend or mixin this class, and let the application call [dirtyCheck]
- *   periodically to check for changes to your object.
- * - extend or mixin [ChangeNotifier], and implement change notifications
- *   manually by calling [notifyPropertyChange] from your setters.
- * - implement this interface and provide your own implementation.
- */
+/// Represents an object with observable properties. This is used by data in
+/// model-view architectures to notify interested parties of [changes] to the
+/// object's properties (fields or getter/setter pairs).
+///
+/// The interface does not require any specific technique to implement
+/// observability. You can implement it in the following ways:
+///
+/// - extend or mixin this class, and let the application call [dirtyCheck]
+///   periodically to check for changes to your object.
+/// - extend or mixin [ChangeNotifier], and implement change notifications
+///   manually by calling [notifyPropertyChange] from your setters.
+/// - implement this interface and provide your own implementation.
 abstract class Observable {
-  /**
-   * Performs dirty checking of objects that inherit from [Observable].
-   * This scans all observed objects using mirrors and determines if any fields
-   * have changed. If they have, it delivers the changes for the object.
-   */
+  /// Performs dirty checking of objects that inherit from [Observable].
+  /// This scans all observed objects using mirrors and determines if any fields
+  /// have changed. If they have, it delivers the changes for the object.
   static void dirtyCheck() => dirtyCheckObservables();
 
   StreamController _changes;
-  InstanceMirror _mirror;
 
   Map<Symbol, Object> _values;
   List<ChangeRecord> _records;
 
-  /**
-   * The stream of change records to this object. Records will be delivered
-   * asynchronously.
-   *
-   * [deliverChanges] can be called to force synchronous delivery.
-   */
+  /// The stream of change records to this object. Records will be delivered
+  /// asynchronously.
+  ///
+  /// [deliverChanges] can be called to force synchronous delivery.
   Stream<List<ChangeRecord>> get changes {
     if (_changes == null) {
       _changes = new StreamController.broadcast(sync: true,
@@ -65,59 +59,42 @@
     return _changes.stream;
   }
 
-  /**
-   * True if this object has any observers, and should call
-   * [notifyChange] for changes.
-   */
+  /// True if this object has any observers, and should call
+  /// [notifyChange] for changes.
   bool get hasObservers => _changes != null && _changes.hasListener;
 
   void _observed() {
     // Register this object for dirty checking purposes.
     registerObservable(this);
 
-    var mirror = reflect(this);
     var values = new Map<Symbol, Object>();
 
     // Note: we scan for @observable regardless of whether the base type
     // actually includes this mixin. While perhaps too inclusive, it lets us
     // avoid complex logic that walks "with" and "implements" clauses.
-    for (var type = mirror.type; type != objectType; type = type.superclass) {
-      for (var field in type.declarations.values) {
-        if (field is! VariableMirror ||
-            field.isFinal ||
-            field.isStatic ||
-            field.isPrivate) continue;
-
-        for (var meta in field.metadata) {
-          if (meta.reflectee is ObservableProperty) {
-            var name = field.simpleName;
-            // Note: since this is a field, getting the value shouldn't execute
-            // user code, so we don't need to worry about errors.
-            values[name] = mirror.getField(name).reflectee;
-            break;
-          }
-        }
-      }
+    var queryOptions = new smoke.QueryOptions(includeInherited: true,
+        includeProperties: false, withAnnotations: const [ObservableProperty]);
+    for (var decl in smoke.query(this.runtimeType, queryOptions)) {
+      var name = decl.name;
+      // Note: since this is a field, getting the value shouldn't execute
+      // user code, so we don't need to worry about errors.
+      values[name] = smoke.read(this, name);
     }
 
-    _mirror = mirror;
     _values = values;
   }
 
-  /** Release data associated with observation. */
+  /// Release data associated with observation.
   void _unobserved() {
     // Note: we don't need to explicitly unregister from the dirty check list.
     // This will happen automatically at the next call to dirtyCheck.
     if (_values != null) {
-      _mirror = null;
       _values = null;
     }
   }
 
-  /**
-   * Synchronously deliver pending [changes]. Returns true if any records were
-   * delivered, otherwise false.
-   */
+  /// Synchronously deliver pending [changes]. Returns true if any records were
+  /// delivered, otherwise false.
   // TODO(jmesserly): this is a bit different from the ES Harmony version, which
   // allows delivery of changes to a particular observer:
   // http://wiki.ecmascript.org/doku.php?id=harmony:observe#object.deliverchangerecords
@@ -145,7 +122,7 @@
     _records = null;
 
     _values.forEach((name, oldValue) {
-      var newValue = _mirror.getField(name).reflectee;
+      var newValue = smoke.read(this, name);
       if (oldValue != newValue) {
         if (records == null) records = [];
         records.add(new PropertyChangeRecord(this, name, oldValue, newValue));
@@ -159,30 +136,26 @@
     return true;
   }
 
-  /**
-   * Notify that the field [name] of this object has been changed.
-   *
-   * The [oldValue] and [newValue] are also recorded. If the two values are
-   * equal, no change will be recorded.
-   *
-   * For convenience this returns [newValue].
-   */
+  /// Notify that the field [name] of this object has been changed.
+  ///
+  /// The [oldValue] and [newValue] are also recorded. If the two values are
+  /// equal, no change will be recorded.
+  ///
+  /// For convenience this returns [newValue].
   notifyPropertyChange(Symbol field, Object oldValue, Object newValue)
       => notifyPropertyChangeHelper(this, field, oldValue, newValue);
 
-  /**
-   * Notify observers of a change.
-   *
-   * For most objects [Observable.notifyPropertyChange] is more convenient, but
-   * collections sometimes deliver other types of changes such as a
-   * [ListChangeRecord].
-   *
-   * Notes:
-   * - This is *not* required for fields if you mixin or extend [Observable],
-   *   but you can use it for computed properties.
-   * - Unlike [ChangeNotifier] this will not schedule [deliverChanges]; use
-   *   [Observable.dirtyCheck] instead.
-   */
+  /// Notify observers of a change.
+  ///
+  /// For most objects [Observable.notifyPropertyChange] is more convenient, but
+  /// collections sometimes deliver other types of changes such as a
+  /// [ListChangeRecord].
+  ///
+  /// Notes:
+  /// - This is *not* required for fields if you mixin or extend [Observable],
+  ///   but you can use it for computed properties.
+  /// - Unlike [ChangeNotifier] this will not schedule [deliverChanges]; use
+  ///   [Observable.dirtyCheck] instead.
   void notifyChange(ChangeRecord record) {
     if (!hasObservers) return;
 
@@ -202,6 +175,3 @@
   }
   return newValue;
 }
-
-// NOTE: this is not exported publically.
-final objectType = reflectClass(Object);
diff --git a/pkg/observe/lib/src/observable_box.dart b/pkg/observe/lib/src/observable_box.dart
index 9455dbd..dfaf7ff 100644
--- a/pkg/observe/lib/src/observable_box.dart
+++ b/pkg/observe/lib/src/observable_box.dart
@@ -8,12 +8,10 @@
 
 // TODO(jmesserly): should the property name be configurable?
 // That would be more convenient.
-/**
- * An observable box that holds a value. Use this if you want to store a single
- * value. For other cases, it is better to use [ObservableList],
- * [ObservableMap], or a custom [Observable] implementation based on
- * [Observable]. The property name for changes is "value".
- */
+/// An observable box that holds a value. Use this if you want to store a single
+/// value. For other cases, it is better to use [ObservableList],
+/// [ObservableMap], or a custom [Observable] implementation based on
+/// [Observable]. The property name for changes is "value".
 class ObservableBox<T> extends ChangeNotifier {
   T _value;
 
diff --git a/pkg/observe/lib/src/observable_list.dart b/pkg/observe/lib/src/observable_list.dart
index f7052ff..4a6b56a 100644
--- a/pkg/observe/lib/src/observable_list.dart
+++ b/pkg/observe/lib/src/observable_list.dart
@@ -9,60 +9,52 @@
 import 'package:observe/observe.dart';
 import 'list_diff.dart' show projectListSplices, calcSplices;
 
-/**
- * Represents an observable list of model values. If any items are added,
- * removed, or replaced, then observers that are listening to [changes]
- * will be notified.
- */
+/// Represents an observable list of model values. If any items are added,
+/// removed, or replaced, then observers that are listening to [changes]
+/// will be notified.
 class ObservableList<E> extends ListBase<E> with ChangeNotifier {
   List<ListChangeRecord> _listRecords;
 
   StreamController _listChanges;
 
-  /** The inner [List<E>] with the actual storage. */
+  /// The inner [List<E>] with the actual storage.
   final List<E> _list;
 
-  /**
-   * Creates an observable list of the given [length].
-   *
-   * If no [length] argument is supplied an extendable list of
-   * length 0 is created.
-   *
-   * If a [length] argument is supplied, a fixed size list of that
-   * length is created.
-   */
+  /// Creates an observable list of the given [length].
+  ///
+  /// If no [length] argument is supplied an extendable list of
+  /// length 0 is created.
+  ///
+  /// If a [length] argument is supplied, a fixed size list of that
+  /// length is created.
   ObservableList([int length])
       : _list = length != null ? new List<E>(length) : <E>[];
 
-  /**
-   * Creates an observable list with the elements of [other]. The order in
-   * the list will be the order provided by the iterator of [other].
-   */
+  /// Creates an observable list with the elements of [other]. The order in
+  /// the list will be the order provided by the iterator of [other].
   factory ObservableList.from(Iterable<E> other) =>
       new ObservableList<E>()..addAll(other);
 
-  /**
-   * The stream of summarized list changes, delivered asynchronously.
-   *
-   * Each list change record contains information about an individual mutation.
-   * The records are projected so they can be applied sequentially. For example,
-   * this set of mutations:
-   *
-   *     var model = new ObservableList.from(['a', 'b']);
-   *     model.listChanges.listen((records) => records.forEach(print));
-   *     model.removeAt(1);
-   *     model.insertAll(0, ['c', 'd', 'e']);
-   *     model.removeRange(1, 3);
-   *     model.insert(1, 'f');
-   *
-   * The change records will be summarized so they can be "played back", using
-   * the final list positions to figure out which item was added:
-   *
-   *     #<ListChangeRecord index: 0, removed: [], addedCount: 2>
-   *     #<ListChangeRecord index: 3, removed: [b], addedCount: 0>
-   *
-   * [deliverChanges] can be called to force synchronous delivery.
-   */
+  /// The stream of summarized list changes, delivered asynchronously.
+  ///
+  /// Each list change record contains information about an individual mutation.
+  /// The records are projected so they can be applied sequentially. For
+  /// example, this set of mutations:
+  ///
+  ///     var model = new ObservableList.from(['a', 'b']);
+  ///     model.listChanges.listen((records) => records.forEach(print));
+  ///     model.removeAt(1);
+  ///     model.insertAll(0, ['c', 'd', 'e']);
+  ///     model.removeRange(1, 3);
+  ///     model.insert(1, 'f');
+  ///
+  /// The change records will be summarized so they can be "played back", using
+  /// the final list positions to figure out which item was added:
+  ///
+  ///     #<ListChangeRecord index: 0, removed: [], addedCount: 2>
+  ///     #<ListChangeRecord index: 3, removed: [b], addedCount: 0>
+  ///
+  /// [deliverChanges] can be called to force synchronous delivery.
   Stream<List<ListChangeRecord>> get listChanges {
     if (_listChanges == null) {
       // TODO(jmesserly): split observed/unobserved notions?
@@ -272,28 +264,24 @@
     return false;
   }
 
-  /**
-   * Calculates the changes to the list, if lacking individual splice mutation
-   * information.
-   *
-   * This is not needed for change records produced by [ObservableList] itself,
-   * but it can be used if the list instance was replaced by another list.
-   *
-   * The minimal set of splices can be synthesized given the previous state and
-   * final state of a list. The basic approach is to calculate the edit distance
-   * matrix and choose the shortest path through it.
-   *
-   * Complexity is `O(l * p)` where `l` is the length of the current list and
-   * `p` is the length of the old list.
-   */
+  /// Calculates the changes to the list, if lacking individual splice mutation
+  /// information.
+  ///
+  /// This is not needed for change records produced by [ObservableList] itself,
+  /// but it can be used if the list instance was replaced by another list.
+  ///
+  /// The minimal set of splices can be synthesized given the previous state and
+  /// final state of a list. The basic approach is to calculate the edit
+  /// distance matrix and choose the shortest path through it.
+  ///
+  /// Complexity is `O(l * p)` where `l` is the length of the current list and
+  /// `p` is the length of the old list.
   static List<ListChangeRecord> calculateChangeRecords(
       List<Object> oldValue, List<Object> newValue) =>
       calcSplices(newValue, 0, newValue.length, oldValue, 0, oldValue.length);
 
-  /**
-   * Updates the [previous] list using the change [records]. For added items,
-   * the [current] list is used to find the current value.
-   */
+  /// Updates the [previous] list using the change [records]. For added items,
+  /// the [current] list is used to find the current value.
   static void applyChangeRecords(List<Object> previous, List<Object> current,
       List<ListChangeRecord> changeRecords) {
 
diff --git a/pkg/observe/lib/src/observable_map.dart b/pkg/observe/lib/src/observable_map.dart
index 27e25da..c3a216f 100644
--- a/pkg/observe/lib/src/observable_map.dart
+++ b/pkg/observe/lib/src/observable_map.dart
@@ -19,19 +19,19 @@
   // TODO(jmesserly): we could store this more compactly if it matters, with
   // subtypes for inserted and removed.
 
-  /** The map key that changed. */
+  /// The map key that changed.
   final K key;
 
-  /** The previous value associated with this key. */
+  /// The previous value associated with this key.
   final V oldValue;
 
-  /** The new value associated with this key. */
+  /// The new value associated with this key.
   final V newValue;
 
-  /** True if this key was inserted. */
+  /// True if this key was inserted.
   final bool isInsert;
 
-  /** True if this key was removed. */
+  /// True if this key was removed.
   final bool isRemove;
 
   MapChangeRecord(this.key, this.oldValue, this.newValue)
@@ -49,37 +49,33 @@
   }
 }
 
-/**
- * Represents an observable map of model values. If any items are added,
- * removed, or replaced, then observers that are listening to [changes]
- * will be notified.
- */
+/// Represents an observable map of model values. If any items are added,
+/// removed, or replaced, then observers that are listening to [changes]
+/// will be notified.
 class ObservableMap<K, V> extends ChangeNotifier implements Map<K, V> {
   final Map<K, V> _map;
 
-  /** Creates an observable map. */
+  /// Creates an observable map.
   ObservableMap() : _map = new HashMap<K, V>();
 
-  /** Creates a new observable map using a [LinkedHashMap]. */
+  /// Creates a new observable map using a [LinkedHashMap].
   ObservableMap.linked() : _map = new LinkedHashMap<K, V>();
 
-  /** Creates a new observable map using a [SplayTreeMap]. */
+  /// Creates a new observable map using a [SplayTreeMap].
   ObservableMap.sorted() : _map = new SplayTreeMap<K, V>();
 
-  /**
-   * Creates an observable map that contains all key value pairs of [other].
-   * It will attempt to use the same backing map type if the other map is a
-   * [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it defaults to
-   * [HashMap].
-   *
-   * Note this will perform a shallow conversion. If you want a deep conversion
-   * you should use [toObservable].
-   */
+  /// Creates an observable map that contains all key value pairs of [other].
+  /// It will attempt to use the same backing map type if the other map is a
+  /// [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it defaults to
+  /// [HashMap].
+  ///
+  /// Note this will perform a shallow conversion. If you want a deep conversion
+  /// you should use [toObservable].
   factory ObservableMap.from(Map<K, V> other) {
     return new ObservableMap<K, V>.createFromType(other)..addAll(other);
   }
 
-  /** Like [ObservableMap.from], but creates an empty map. */
+  /// Like [ObservableMap.from], but creates an empty map.
   factory ObservableMap.createFromType(Map<K, V> other) {
     ObservableMap result;
     if (other is SplayTreeMap) {
diff --git a/pkg/observe/lib/src/path_observer.dart b/pkg/observe/lib/src/path_observer.dart
index 8054a3a..be55102 100644
--- a/pkg/observe/lib/src/path_observer.dart
+++ b/pkg/observe/lib/src/path_observer.dart
@@ -8,11 +8,13 @@
 import 'dart:collection';
 import 'dart:math' show min;
 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
-    override: 'observe.src.path_observer')
-import 'dart:mirrors';
+    override: 'smoke.mirrors')
+import 'dart:mirrors' show MirrorsUsed;
+
 import 'package:logging/logging.dart' show Logger, Level;
 import 'package:observe/observe.dart';
 import 'package:observe/src/observable.dart' show objectType;
+import 'package:smoke/smoke.dart' as smoke;
 
 /// A data-bound path starting from a view-model or model object, for example
 /// `foo.bar.baz`.
@@ -41,7 +43,7 @@
   bool get _isClosed => _path == null;
 
   /// Sets the value at this path.
-  @reflectable void set value(Object newValue) {
+  void set value(Object newValue) {
     if (_path != null) _path.setValueFrom(_object, newValue);
   }
 
@@ -148,7 +150,7 @@
   String toString() {
     if (!isValid) return '<invalid path>';
     return _segments
-        .map((s) => s is Symbol ? MirrorSystem.getName(s) : s)
+        .map((s) => s is Symbol ? smoke.symbolToName(s) : s)
         .join('.');
   }
 
@@ -229,7 +231,7 @@
     return (record as PropertyChangeRecord).name == key;
   }
   if (record is MapChangeRecord) {
-    if (key is Symbol) key = MirrorSystem.getName(key);
+    if (key is Symbol) key = smoke.symbolToName(key);
     return (record as MapChangeRecord).key == key;
   }
   return false;
@@ -243,22 +245,21 @@
       return object[property];
     }
   } else if (property is Symbol) {
-    var mirror = reflect(object);
-    final type = mirror.type;
+    final type = object.runtimeType;
     try {
-      if (_maybeHasGetter(type, property)) {
-        return mirror.getField(property).reflectee;
+      if (smoke.hasGetter(type, property) || smoke.hasNoSuchMethod(type)) {
+        return smoke.read(object, property);
       }
       // Support indexer if available, e.g. Maps or polymer_expressions Scope.
       // This is the default syntax used by polymer/nodebind and
       // polymer/observe-js PathObserver.
-      if (_hasMethod(type, const Symbol('[]'))) {
-        return object[MirrorSystem.getName(property)];
+      if (smoke.hasInstanceMethod(type, const Symbol('[]'))) {
+        return object[smoke.symbolToName(property)];
       }
     } on NoSuchMethodError catch (e) {
       // Rethrow, unless the type implements noSuchMethod, in which case we
       // interpret the exception as a signal that the method was not found.
-      if (!_hasMethod(type, #noSuchMethod)) rethrow;
+      if (!smoke.hasNoSuchMethod(type)) rethrow;
     }
   }
 
@@ -277,20 +278,19 @@
       return true;
     }
   } else if (property is Symbol) {
-    var mirror = reflect(object);
-    final type = mirror.type;
+    final type = object.runtimeType;
     try {
-      if (_maybeHasSetter(type, property)) {
-        mirror.setField(property, value);
+      if (smoke.hasSetter(type, property) || smoke.hasNoSuchMethod(type)) {
+        smoke.write(object, property, value);
         return true;
       }
       // Support indexer if available, e.g. Maps or polymer_expressions Scope.
-      if (_hasMethod(type, const Symbol('[]='))) {
-        object[MirrorSystem.getName(property)] = value;
+      if (smoke.hasInstanceMethod(type, const Symbol('[]='))) {
+        object[smoke.symbolToName(property)] = value;
         return true;
       }
     } on NoSuchMethodError catch (e) {
-      if (!_hasMethod(type, #noSuchMethod)) rethrow;
+      if (!smoke.hasNoSuchMethod(type)) rethrow;
     }
   }
 
@@ -300,57 +300,6 @@
   return false;
 }
 
-bool _maybeHasGetter(ClassMirror type, Symbol name) {
-  while (type != objectType) {
-    final members = type.declarations;
-    if (members.containsKey(name)) return true;
-    if (members.containsKey(#noSuchMethod)) return true;
-    type = _safeSuperclass(type);
-  }
-  return false;
-}
-
-// TODO(jmesserly): workaround for:
-// https://code.google.com/p/dart/issues/detail?id=10029
-Symbol _setterName(Symbol getter) =>
-    new Symbol('${MirrorSystem.getName(getter)}=');
-
-bool _maybeHasSetter(ClassMirror type, Symbol name) {
-  var setterName = _setterName(name);
-  while (type != objectType) {
-    final members = type.declarations;
-    if (members[name] is VariableMirror) return true;
-    if (members.containsKey(setterName)) return true;
-    if (members.containsKey(#noSuchMethod)) return true;
-    type = _safeSuperclass(type);
-  }
-  return false;
-}
-
-/// True if the type has a method, other than on Object.
-/// Doesn't consider noSuchMethod, unless [name] is `#noSuchMethod`.
-bool _hasMethod(ClassMirror type, Symbol name) {
-  while (type != objectType) {
-    final member = type.declarations[name];
-    if (member is MethodMirror && member.isRegularMethod) return true;
-    type = _safeSuperclass(type);
-  }
-  return false;
-}
-
-ClassMirror _safeSuperclass(ClassMirror type) {
-  try {
-    return type.superclass;
-  } /*on UnsupportedError*/ catch (e) {
-    // Note: dart2js throws UnsupportedError when the type is not
-    // reflectable.
-    // TODO(jmesserly): dart2js also throws a NoSuchMethodError if the `type` is
-    // a bound generic, because they are not fully implemented. See
-    // https://code.google.com/p/dart/issues/detail?id=15573
-    return objectType;
-  }
-}
-
 // From: https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
 
 final _pathRegExp = () {
@@ -557,20 +506,19 @@
       throw new StateError('Observer has already been opened.');
     }
 
-    if (_minArgumentCount(callback) > _reportArgumentCount) {
+    if (smoke.minArgs(callback) > _reportArgumentCount) {
       throw new ArgumentError('callback should take $_reportArgumentCount or '
           'fewer arguments');
     }
 
     _notifyCallback = callback;
-    _notifyArgumentCount = min(_reportArgumentCount,
-        _maxArgumentCount(callback));
+    _notifyArgumentCount = min(_reportArgumentCount, smoke.maxArgs(callback));
 
     _connect();
     return _value;
   }
 
-  @reflectable get value {
+  get value {
     _check(skipChanges: true);
     return _value;
   }
@@ -611,27 +559,6 @@
   }
 }
 
-typedef _Func0();
-typedef _Func1(a);
-typedef _Func2(a, b);
-typedef _Func3(a, b, c);
-
-int _minArgumentCount(fn) {
-  if (fn is _Func0) return 0;
-  if (fn is _Func1) return 1;
-  if (fn is _Func2) return 2;
-  if (fn is _Func3) return 3;
-  return 4; // at least 4 arguments are required.
-}
-
-int _maxArgumentCount(fn) {
-  if (fn is _Func3) return 3;
-  if (fn is _Func2) return 2;
-  if (fn is _Func1) return 1;
-  if (fn is _Func0) return 0;
-  return -1;
-}
-
 class _ObservedSet {
   /// To prevent sequential [PathObserver]s and [CompoundObserver]s from
   /// observing the same object, we check if they are observing the same root
diff --git a/pkg/observe/lib/src/to_observable.dart b/pkg/observe/lib/src/to_observable.dart
index 4684935..931fb04 100644
--- a/pkg/observe/lib/src/to_observable.dart
+++ b/pkg/observe/lib/src/to_observable.dart
@@ -6,22 +6,20 @@
 
 import 'package:observe/observe.dart';
 
-/**
- * Converts the [Iterable] or [Map] to an [ObservableList] or [ObservableMap],
- * respectively. This is a convenience function to make it easier to convert
- * literals into the corresponding observable collection type.
- *
- * If [value] is not one of those collection types, or is already [Observable],
- * it will be returned unmodified.
- *
- * If [value] is a [Map], the resulting value will use the appropriate kind of
- * backing map: either [HashMap], [LinkedHashMap], or [SplayTreeMap].
- *
- * By default this performs a deep conversion, but you can set [deep] to false
- * for a shallow conversion. This does not handle circular data structures.
- * If a conversion is peformed, mutations are only observed to the result of
- * this function. Changing the original collection will not affect it.
- */
+/// Converts the [Iterable] or [Map] to an [ObservableList] or [ObservableMap],
+/// respectively. This is a convenience function to make it easier to convert
+/// literals into the corresponding observable collection type.
+///
+/// If [value] is not one of those collection types, or is already [Observable],
+/// it will be returned unmodified.
+///
+/// If [value] is a [Map], the resulting value will use the appropriate kind of
+/// backing map: either [HashMap], [LinkedHashMap], or [SplayTreeMap].
+///
+/// By default this performs a deep conversion, but you can set [deep] to false
+/// for a shallow conversion. This does not handle circular data structures.
+/// If a conversion is peformed, mutations are only observed to the result of
+/// this function. Changing the original collection will not affect it.
 // TODO(jmesserly): ObservableSet?
 toObservable(value, {bool deep: true}) =>
     deep ? _toObservableDeep(value) : _toObservableShallow(value);
diff --git a/pkg/observe/lib/transform.dart b/pkg/observe/lib/transform.dart
index 4be227f..c62b2ef 100644
--- a/pkg/observe/lib/transform.dart
+++ b/pkg/observe/lib/transform.dart
@@ -2,10 +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.
 
-/**
- * Code transform for @observable. This library will be removed soon, it simply
- * reexports `observe.transformer`.
- */
+/// Code transform for @observable. This library will be removed soon, it simply
+/// reexports `observe.transformer`.
 // TODO(sigmund): deprecate and delete.
 library observe.transform;
 
diff --git a/pkg/observe/lib/transformer.dart b/pkg/observe/lib/transformer.dart
index 035cff5..18173bc 100644
--- a/pkg/observe/lib/transformer.dart
+++ b/pkg/observe/lib/transformer.dart
@@ -2,10 +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.
 
-/**
- * Code transform for @observable. The core transformation is relatively
- * straightforward, and essentially like an editor refactoring.
- */
+/// Code transform for @observable. The core transformation is relatively
+/// straightforward, and essentially like an editor refactoring.
 library observe.transformer;
 
 import 'dart:async';
@@ -18,17 +16,15 @@
 import 'package:source_maps/refactor.dart';
 import 'package:source_maps/span.dart' show SourceFile;
 
-/**
- * A [Transformer] that replaces observables based on dirty-checking with an
- * implementation based on change notifications.
- *
- * The transformation adds hooks for field setters and notifies the observation
- * system of the change.
- */
+/// A [Transformer] that replaces observables based on dirty-checking with an
+/// implementation based on change notifications.
+///
+/// The transformation adds hooks for field setters and notifies the observation
+/// system of the change.
 class ObservableTransformer extends Transformer {
 
   final List<String> _files;
-  ObservableTransformer() : _files = null;
+  ObservableTransformer([List<String> files]) : _files = files;
   ObservableTransformer.asPlugin(BarbackSettings settings)
       : _files = _readFiles(settings.configuration['files']);
 
@@ -112,7 +108,7 @@
   return code;
 }
 
-/** Parse [code] using analyzer. */
+/// Parse [code] using analyzer.
 CompilationUnit _parseCompilationUnit(String code) {
   var errorListener = new _ErrorCollector();
   var reader = new CharSequenceReader(code);
@@ -129,7 +125,7 @@
 
 _getSpan(SourceFile file, ASTNode node) => file.span(node.offset, node.end);
 
-/** True if the node has the `@observable` or `@published` annotation. */
+/// True if the node has the `@observable` or `@published` annotation.
 // TODO(jmesserly): it is not good to be hard coding Polymer support here.
 bool _hasObservable(AnnotatedNode node) =>
     node.metadata.any(_isObservableAnnotation);
@@ -262,7 +258,7 @@
   }
 }
 
-/** Adds "with ChangeNotifier" and associated implementation. */
+/// Adds "with ChangeNotifier" and associated implementation.
 void _mixinObservable(ClassDeclaration cls, TextEditTransaction code) {
   // Note: we need to be careful to put the with clause after extends, but
   // before implements clause.
diff --git a/pkg/observe/pubspec.yaml b/pkg/observe/pubspec.yaml
index 3b0407c..b50f4bc8 100644
--- a/pkg/observe/pubspec.yaml
+++ b/pkg/observe/pubspec.yaml
@@ -10,9 +10,10 @@
 homepage: https://www.dartlang.org/polymer-dart/
 dependencies:
   analyzer: ">=0.10.1 <0.11.0"
-  barback: ">=0.9.0 <0.12.0"
+  barback: ">=0.9.0 <0.13.0"
   logging: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <2.0.0"
+  smoke: ">=0.1.0-dev <0.2.0"
   source_maps: ">=0.9.0 <0.10.0"
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
diff --git a/pkg/observe/test/transformer_test.dart b/pkg/observe/test/transformer_test.dart
index a2f6b5b..159cf49 100644
--- a/pkg/observe/test/transformer_test.dart
+++ b/pkg/observe/test/transformer_test.dart
@@ -125,7 +125,7 @@
   });
 }
 
-/** Helper that applies the transform by creating mock assets. */
+/// Helper that applies the transform by creating mock assets.
 Future<String> _transform(String code) {
   var id = new AssetId('foo', 'a/b/c.dart');
   var asset = new Asset.fromString(id, code);
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 8edee0d..a942c07 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -19,10 +19,6 @@
 
 polymer/test/event_path_test: Pass, Fail # Issue 15766
 
-# Skip test not runnable via test.dart
-third_party/html5lib/test/dom_compat_test: Skip
-third_party/html5lib/test/browser/browser_test: Skip
-
 [ $compiler == dart2js ]
 collection/test/equality_test/01: Fail # Issue 1533
 collection/test/equality_test/02: Fail # Issue 1533
@@ -32,6 +28,8 @@
 collection/test/equality_test/none: Pass, Fail # Issue 14348
 third_party/angular_tests/browser_test: Pass, Slow # Large dart2js compile time
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
+docgen/test/multi_library_test: Slow, Pass # issue 17060
+third_party/angular_tests/browser_test/core/parser/parser: RuntimeError # Issue 17073
 
 [ $compiler == dart2js && $checked ]
 crypto/test/base64_test: Slow, Pass
@@ -53,6 +51,7 @@
 stack_trace/test/chain_test: Fail # Issues 15171 and 15105
 async/test/stream_zip_test: RuntimeError, OK # Timers are not supported.
 unittest/test/missing_tick_test: Fail # Timer interface not supported: dartbug.com/7728.
+scheduled_test/test/unittest_compatibility_test: RuntimeError # Issue 17134
 
 [ $runtime == vm || $runtime == d8 || $runtime == jsshell ]
 polymer/example: Skip # Uses dart:html
@@ -88,7 +87,7 @@
 source_maps/test/vlq_test: RuntimeError # A VLQ test checks for large numbers that
                                 # overflow in JS (numbers slightly larger than
                                 # 32 bits where we do bitwise operations).
-[ $runtime == ff && $system != windows ]
+[ ($runtime == ff || $runtime == jsshell) && $system != windows ]
 # Bug in Spidermonkey's Uint8ClampedArray on x64 (non-Win FF is x64, Win is x86)
 # See https://bugzilla.mozilla.org/show_bug.cgi?id=940972
 # Likely to get patched only on some versions of Firefox.
@@ -191,6 +190,7 @@
 analyzer/test/services/formatter_test: Fail, OK # Uses dart:io.
 analyzer/test/parse_compilation_unit_test: Fail, OK # Uses dart:io.
 barback/test/*: Fail, OK # Uses dart:io.
+code_transformers/test/*: Skip # Uses dart:io.
 http/test/client_test: Fail, OK # Uses dart:io.
 http/test/http_test: Fail, OK # Uses dart:io.
 http/test/mock_client_test: Fail, OK # Uses dart:io.
@@ -246,6 +246,7 @@
 [ $arch == simarm || $arch == simmips ]
 barback/test/too_many_open_files_test: Skip # 14220
 third_party/html5lib/test/tokenizer_test: Pass, Slow
+docgen/test/generate_json_test: Skip # Issue 17003
 
 [ $arch == simarm && $checked ]
 watcher/test/directory_watcher/linux_test: Skip # Issue 16118
@@ -287,8 +288,10 @@
 [ $compiler == none && ( $runtime == dartium || $runtime == drt ) && $checked ]
 polymer/test/custom_event_test: Skip # http://dartbug.com/15517
 
-# Skip tests on the VM if the package depends on dart:html
 [ $runtime == vm ]
+intl/test/message_extraction/message_extraction_test: Skip # Issue 17130
+
+# Skip tests on the VM if the package depends on dart:html
 custom_element: Skip
 template_binding: Skip
 mutation_observer: Skip
@@ -301,6 +304,7 @@
 polymer_expressions/test/globals_test: Fail # Issue 16568
 
 [ $runtime == safari || $runtime == chrome || $runtime == ie9 || $runtime == ff || $runtime == dartium || $runtime == drt ]
+docgen/test/generate_json_test: Skip  # Uses dart:io
 docgen/test/single_library_test: Skip # Uses dart:io
 docgen/test/multi_library_test: Skip # Uses dart:io
 scheduled_test/test/scheduled_server_test: Skip # Uses dart:io
@@ -313,8 +317,9 @@
 source_maps/test/parser_test: Pass, Timeout # Issue 13719: Please triage this failure.
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
-docgen/test/single_library_test: StaticWarning
-docgen/test/multi_library_test: StaticWarning
+docgen/test/generate_json_test: StaticWarning # Issue 16950
+docgen/test/single_library_test: StaticWarning # Issue 16950
+docgen/test/multi_library_test: StaticWarning # Issue 16950
 unittest/test/matchers_test: StaticWarning, OK # testing error creating abstract class
 
 [ $runtime == vm && ($system == windows || $system == macos) ]
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index eeaf35d..25f0abf 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -12,14 +12,13 @@
 [ $use_repository_packages ]
 pkg/analyzer: PubGetError
 pkg/args: PubGetError
-pkg/stack_trace: PubGetError
 pkg/unittest: PubGetError
 
 [ $use_public_packages ]
-pkg/watcher: PubGetError # Issue 16026
 pkg/template_binding: Pass, PubGetError # Issue 16026
 pkg/polymer: PubGetError # Issue 16026
 pkg/polymer_expressions: PubGetError # Issue 16026
+pkg/observe: Pass, PubGetError # Issue 16026
 
 [ $builder_tag == russian ]
 samples/third_party/pop-pop-win: Fail # Issue 16356
diff --git a/pkg/polymer/example/canonicalization/test/deploy2_test.dart b/pkg/polymer/example/canonicalization/test/deploy2_test.dart
index e2de77d..2b66dbb 100644
--- a/pkg/polymer/example/canonicalization/test/deploy2_test.dart
+++ b/pkg/polymer/example/canonicalization/test/deploy2_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.deploy2_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/deploy3_test.dart b/pkg/polymer/example/canonicalization/test/deploy3_test.dart
index 705abc8..8c963b6 100644
--- a/pkg/polymer/example/canonicalization/test/deploy3_test.dart
+++ b/pkg/polymer/example/canonicalization/test/deploy3_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.deploy3_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/deploy_test.dart b/pkg/polymer/example/canonicalization/test/deploy_test.dart
index 61dde5c..cae44d6 100644
--- a/pkg/polymer/example/canonicalization/test/deploy_test.dart
+++ b/pkg/polymer/example/canonicalization/test/deploy_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.deploy_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dev2_test.dart b/pkg/polymer/example/canonicalization/test/dev2_test.dart
index cbb75d7..dfaebff 100644
--- a/pkg/polymer/example/canonicalization/test/dev2_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dev2_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.
 
-/** Tests how canonicalization works during development. */
+/// Tests how canonicalization works during development.
 library canonicalization.dev2_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dev3_test.dart b/pkg/polymer/example/canonicalization/test/dev3_test.dart
index 874e8ef..15d1dbc 100644
--- a/pkg/polymer/example/canonicalization/test/dev3_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dev3_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.
 
-/** Tests how canonicalization works during development. */
+/// Tests how canonicalization works during development.
 library canonicalization.dev3_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dev_test.dart b/pkg/polymer/example/canonicalization/test/dev_test.dart
index a2c54c2..0d13d6d 100644
--- a/pkg/polymer/example/canonicalization/test/dev_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dev_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.
 
-/** Tests how canonicalization works during development. */
+/// Tests how canonicalization works during development.
 library canonicalization.dev_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dir/deploy2_test.dart b/pkg/polymer/example/canonicalization/test/dir/deploy2_test.dart
index 0be4dd6..65c1cc1 100644
--- a/pkg/polymer/example/canonicalization/test/dir/deploy2_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dir/deploy2_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.
 
-/** Tests canonicalization at deployment time from a subdir. */
+/// Tests canonicalization at deployment time from a subdir.
 library canonicalization.dir.deploy2_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dir/deploy_test.dart b/pkg/polymer/example/canonicalization/test/dir/deploy_test.dart
index bff91d6..65b1b28 100644
--- a/pkg/polymer/example/canonicalization/test/dir/deploy_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dir/deploy_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.
 
-/** Tests canonicalization at deployment time from a subdir. */
+/// Tests canonicalization at deployment time from a subdir.
 library canonicalization.dir.deploy_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dir/dev2_test.dart b/pkg/polymer/example/canonicalization/test/dir/dev2_test.dart
index c8a34fe..4bac334 100644
--- a/pkg/polymer/example/canonicalization/test/dir/dev2_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dir/dev2_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.
 
-/** Tests canonicalization during development from a subdir. */
+/// Tests canonicalization during development from a subdir.
 library canonicalization.dir.dev2_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization/test/dir/dev_test.dart b/pkg/polymer/example/canonicalization/test/dir/dev_test.dart
index 884a30b..305d57d 100644
--- a/pkg/polymer/example/canonicalization/test/dir/dev_test.dart
+++ b/pkg/polymer/example/canonicalization/test/dir/dev_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.
 
-/** Tests canonicalization during development from a subdir. */
+/// Tests canonicalization during development from a subdir.
 library canonicalization.dir.dev_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization2/test/bad_lib_import2_negative_test.dart b/pkg/polymer/example/canonicalization2/test/bad_lib_import2_negative_test.dart
index 2976e6a..d467d03 100644
--- a/pkg/polymer/example/canonicalization2/test/bad_lib_import2_negative_test.dart
+++ b/pkg/polymer/example/canonicalization2/test/bad_lib_import2_negative_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.dev3_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization2/test/bad_lib_import_negative_test.dart b/pkg/polymer/example/canonicalization2/test/bad_lib_import_negative_test.dart
index 0b1bb97..3d6f1fe 100644
--- a/pkg/polymer/example/canonicalization2/test/bad_lib_import_negative_test.dart
+++ b/pkg/polymer/example/canonicalization2/test/bad_lib_import_negative_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.bad_lib_import_negative;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization3/test/bad_lib_import2_negative_test.dart b/pkg/polymer/example/canonicalization3/test/bad_lib_import2_negative_test.dart
index 2976e6a..d467d03 100644
--- a/pkg/polymer/example/canonicalization3/test/bad_lib_import2_negative_test.dart
+++ b/pkg/polymer/example/canonicalization3/test/bad_lib_import2_negative_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.dev3_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/canonicalization3/test/bad_lib_import_negative_test.dart b/pkg/polymer/example/canonicalization3/test/bad_lib_import_negative_test.dart
index 0b1bb97..3d6f1fe 100644
--- a/pkg/polymer/example/canonicalization3/test/bad_lib_import_negative_test.dart
+++ b/pkg/polymer/example/canonicalization3/test/bad_lib_import_negative_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.
 
-/** Tests how canonicalization works when using the deployed app. */
+/// Tests how canonicalization works when using the deployed app.
 library canonicalization.bad_lib_import_negative;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/example/component/news/test/news_index_test.dart b/pkg/polymer/example/component/news/test/news_index_test.dart
index 034894b..4825b83 100644
--- a/pkg/polymer/example/component/news/test/news_index_test.dart
+++ b/pkg/polymer/example/component/news/test/news_index_test.dart
@@ -7,9 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 
-/**
- * This test runs the news example and checks the state of the initial page.
- */
+/// This test runs the news example and checks the state of the initial page.
 main() {
   initPolymer();
   useHtmlConfiguration();
diff --git a/pkg/polymer/lib/builder.dart b/pkg/polymer/lib/builder.dart
index 12b8a93..a2eb80f 100644
--- a/pkg/polymer/lib/builder.dart
+++ b/pkg/polymer/lib/builder.dart
@@ -2,83 +2,81 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Common logic to make it easy to run the polymer linter and deploy tool.
- *
- * The functions in this library are designed to make it easier to create
- * `build.dart` files. A `build.dart` file is a Dart script that can be invoked
- * from the command line, but that can also invoked automatically by the Dart
- * Editor whenever a file in your project changes or when selecting some menu
- * options, such as 'Reanalyze Sources'.
- *
- * To work correctly, place the `build.dart` in the root of your project (where
- * pubspec.yaml lives). The file must be named exactly `build.dart`.
- *
- * It's quite likely that in the near future `build.dart` will be replaced with
- * something else.  For example, `pub deploy` will deal with deploying
- * applications automatically, and the Dart Editor might provide other
- * mechanisms to hook linters.
- *
- * There are three important functions exposed by this library [build], [lint],
- * and [deploy]. The following examples show common uses of these functions when
- * writing a `build.dart` file.
- *
- * **Example 1**: Uses build.dart to run the linter tool.
- *
- *     import 'dart:io';
- *     import 'package:polymer/builder.dart';
- *
- *     main() {
- *        lint();
- *     }
- *
- * **Example 2**: Runs the linter and creates a deployable version of the app
- * every time.
- *
- *     import 'dart:io';
- *     import 'package:polymer/builder.dart';
- *
- *     main() {
- *        deploy(); // deploy also calls the linter internally.
- *     }
- *
- * **Example 3**: Always run the linter, but conditionally build a deployable
- * version. See [parseOptions] for a description of options parsed automatically
- * by this helper library.
- *
- *     import 'dart:io';
- *     import 'package:polymer/builder.dart';
- *
- *     main(args) {
- *        var options = parseOptions(args);
- *        if (options.forceDeploy) {
- *          deploy();
- *        } else {
- *          lint();
- *        }
- *     }
- *
- * **Example 4**: Same as above, but uses [build] (which internally calls either
- * [lint] or [deploy]).
- *
- *     import 'dart:io';
- *     import 'package:polymer/builder.dart';
- *
- *     main(args) {
- *        build(options: parseOptions(args));
- *     }
- *
- * **Example 5**: Like the previous example, but indicates to the linter and
- * deploy tool which files are actually used as entry point files. See the
- * documentation of [build] below for more details.
- *
- *     import 'dart:io';
- *     import 'package:polymer/builder.dart';
- *
- *     main(args) {
- *        build(entryPoints: ['web/index.html'], options: parseOptions(args));
- *     }
- */
+/// Common logic to make it easy to run the polymer linter and deploy tool.
+///
+/// The functions in this library are designed to make it easier to create
+/// `build.dart` files. A `build.dart` file is a Dart script that can be invoked
+/// from the command line, but that can also invoked automatically by the Dart
+/// Editor whenever a file in your project changes or when selecting some menu
+/// options, such as 'Reanalyze Sources'.
+///
+/// To work correctly, place the `build.dart` in the root of your project (where
+/// pubspec.yaml lives). The file must be named exactly `build.dart`.
+///
+/// It's quite likely that in the near future `build.dart` will be replaced with
+/// something else.  For example, `pub deploy` will deal with deploying
+/// applications automatically, and the Dart Editor might provide other
+/// mechanisms to hook linters.
+///
+/// There are three important functions exposed by this library [build], [lint],
+/// and [deploy]. The following examples show common uses of these functions
+/// when writing a `build.dart` file.
+///
+/// **Example 1**: Uses build.dart to run the linter tool.
+///
+///     import 'dart:io';
+///     import 'package:polymer/builder.dart';
+///
+///     main() {
+///        lint();
+///     }
+///
+/// **Example 2**: Runs the linter and creates a deployable version of the app
+/// every time.
+///
+///     import 'dart:io';
+///     import 'package:polymer/builder.dart';
+///
+///     main() {
+///        deploy(); // deploy also calls the linter internally.
+///     }
+///
+/// **Example 3**: Always run the linter, but conditionally build a deployable
+/// version. See [parseOptions] for a description of options parsed
+/// automatically by this helper library.
+///
+///     import 'dart:io';
+///     import 'package:polymer/builder.dart';
+///
+///     main(args) {
+///        var options = parseOptions(args);
+///        if (options.forceDeploy) {
+///          deploy();
+///        } else {
+///          lint();
+///        }
+///     }
+///
+/// **Example 4**: Same as above, but uses [build] (which internally calls
+/// either [lint] or [deploy]).
+///
+///     import 'dart:io';
+///     import 'package:polymer/builder.dart';
+///
+///     main(args) {
+///        build(options: parseOptions(args));
+///     }
+///
+/// **Example 5**: Like the previous example, but indicates to the linter and
+/// deploy tool which files are actually used as entry point files. See the
+/// documentation of [build] below for more details.
+///
+///     import 'dart:io';
+///     import 'package:polymer/builder.dart';
+///
+///     main(args) {
+///        build(entryPoints: ['web/index.html'], options: parseOptions(args));
+///     }
 library polymer.builder;
 
 import 'dart:async';
@@ -93,26 +91,24 @@
 import 'transformer.dart';
 
 
-/**
- * Runs the polymer linter on any relevant file in your package, such as any
- * .html file under 'lib/', 'asset/', and 'web/'. And, if requested, creates a
- * directory suitable for deploying a Polymer application to a server.
- *
- * The [entryPoints] list contains files under web/ that should be treated as
- * entry points. Each entry on this list is a relative path from the package
- * root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
- *
- * Options must be passed by
- * passing the [options] argument. The deploy operation is run only when the
- * command-line argument `--deploy` is present, or equivalently when
- * `options.forceDeploy` is true.
- *
- * The linter and deploy steps needs to know the name of the [currentPackage]
- * and the location where to find the code for any package it depends on
- * ([packageDirs]). This is inferred automatically, but can be overriden if
- * those arguments are provided.
- */
+/// Runs the polymer linter on any relevant file in your package, such as any
+/// .html file under 'lib/', 'asset/', and 'web/'. And, if requested, creates a
+/// directory suitable for deploying a Polymer application to a server.
+///
+/// The [entryPoints] list contains files under web/ that should be treated as
+/// entry points. Each entry on this list is a relative path from the package
+/// root (for example 'web/index.html'). If null, all files under 'web/' are
+/// treated as possible entry points.
+///
+/// Options must be passed by
+/// passing the [options] argument. The deploy operation is run only when the
+/// command-line argument `--deploy` is present, or equivalently when
+/// `options.forceDeploy` is true.
+///
+/// The linter and deploy steps needs to know the name of the [currentPackage]
+/// and the location where to find the code for any package it depends on
+/// ([packageDirs]). This is inferred automatically, but can be overriden if
+/// those arguments are provided.
 Future build({List<String> entryPoints, CommandLineOptions options,
     String currentPackage, Map<String, String> packageDirs}) {
   if (options == null) {
@@ -128,21 +124,19 @@
 }
 
 
-/**
- * Runs the polymer linter on any relevant file in your package,
- * such as any .html file under 'lib/', 'asset/', and 'web/'.
- *
- * The [entryPoints] list contains files under web/ that should be treated as
- * entry points. Each entry on this list is a relative path from the package
- * root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
- *
- * Options must be passed by passing the [options] argument.
- *
- * The linter needs to know the name of the [currentPackage] and the location
- * where to find the code for any package it depends on ([packageDirs]). This is
- * inferred automatically, but can be overriden if those arguments are provided.
- */
+/// Runs the polymer linter on any relevant file in your package,
+/// such as any .html file under 'lib/', 'asset/', and 'web/'.
+///
+/// The [entryPoints] list contains files under web/ that should be treated as
+/// entry points. Each entry on this list is a relative path from the package
+/// root (for example 'web/index.html'). If null, all files under 'web/' are
+/// treated as possible entry points.
+///
+/// Options must be passed by passing the [options] argument.
+///
+/// The linter needs to know the name of the [currentPackage] and the location
+/// where to find the code for any package it depends on ([packageDirs]). This
+/// is inferred automatically, but can be overriden by passing the arguments.
 Future lint({List<String> entryPoints, CommandLineOptions options,
     String currentPackage, Map<String, String> packageDirs}) {
   if (options == null) {
@@ -158,24 +152,23 @@
       machineFormat: options.machineFormat));
 }
 
-/**
- * Creates a directory suitable for deploying a Polymer application to a server.
- *
- * **Note**: this function will be replaced in the future by the `pub deploy`
- * command.
- *
- * The [entryPoints] list contains files under web/ that should be treated as
- * entry points. Each entry on this list is a relative path from the package
- * root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
- *
- * Options must be passed by passing the [options] list.
- *
- * The deploy step needs to know the name of the [currentPackage] and the
- * location where to find the code for any package it depends on
- * ([packageDirs]). This is inferred automatically, but can be overriden if
- * those arguments are provided.
- */
+/// Creates a directory suitable for deploying a Polymer application to a
+/// server.
+///
+/// **Note**: this function will be replaced in the future by the `pub deploy`
+/// command.
+///
+/// The [entryPoints] list contains files under web/ that should be treated as
+/// entry points. Each entry on this list is a relative path from the package
+/// root (for example 'web/index.html'). If null, all files under 'web/' are
+/// treated as possible entry points.
+///
+/// Options must be passed by passing the [options] list.
+///
+/// The deploy step needs to know the name of the [currentPackage] and the
+/// location where to find the code for any package it depends on
+/// ([packageDirs]). This is inferred automatically, but can be overriden if
+/// those arguments are provided.
 Future deploy({List<String> entryPoints, CommandLineOptions options,
     String currentPackage, Map<String, String> packageDirs}) {
   if (options == null) {
@@ -191,54 +184,51 @@
       contentSecurityPolicy: options.contentSecurityPolicy,
       releaseMode: options.releaseMode);
 
+  var phases = new PolymerTransformerGroup(transformOptions).phases;
   var barbackOptions = new BarbackOptions(
-      new PolymerTransformerGroup(transformOptions).phases,
-      options.outDir, currentPackage: currentPackage,
-      packageDirs: packageDirs, machineFormat: options.machineFormat);
+      phases, options.outDir, currentPackage: currentPackage,
+      packageDirs: packageDirs, machineFormat: options.machineFormat,
+      // TODO(sigmund): include here also smoke transformer when it's on by
+      // default.
+      packagePhases: {'polymer': phasesForPolymer});
   return runBarback(barbackOptions)
       .then((_) => print('Done! All files written to "${options.outDir}"'));
 }
 
 
-/**
- * Options that may be used either in build.dart or by the linter and deploy
- * tools.
- */
+/// Options that may be used either in build.dart or by the linter and deploy
+/// tools.
 class CommandLineOptions {
-  /** Files marked as changed. */
+  /// Files marked as changed.
   final List<String> changedFiles;
 
-  /** Files marked as removed. */
+  /// Files marked as removed.
   final List<String> removedFiles;
 
-  /** Whether to clean intermediate artifacts, if any. */
+  /// Whether to clean intermediate artifacts, if any.
   final bool clean;
 
-  /** Whether to do a full build (as if all files have changed). */
+  /// Whether to do a full build (as if all files have changed).
   final bool full;
 
-  /** Whether to print results using a machine parseable format. */
+  /// Whether to print results using a machine parseable format.
   final bool machineFormat;
 
-  /** Whether the force deploy option was passed in the command line. */
+  /// Whether the force deploy option was passed in the command line.
   final bool forceDeploy;
 
-  /** Location where to generate output files. */
+  /// Location where to generate output files.
   final String outDir;
 
-  /** True to use the CSP-compliant JS file. */
+  /// True to use the CSP-compliant JS file.
   final bool contentSecurityPolicy;
 
-  /**
-   * True to include the JS script tag directly, without the
-   * "packages/browser/dart.js" trampoline.
-   */
+  /// True to include the JS script tag directly, without the
+  /// "packages/browser/dart.js" trampoline.
   final bool directlyIncludeJS;
 
-  /**
-   * Run transformers in release mode. For instance, uses the minified versions
-   * of the web_components polyfill.
-   */
+  /// Run transformers in release mode. For instance, uses the minified versions
+  /// of the web_components polyfill.
   final bool releaseMode;
 
   CommandLineOptions(this.changedFiles, this.removedFiles, this.clean,
@@ -247,32 +237,30 @@
       this.releaseMode);
 }
 
-/**
- * Parse command-line arguments and return a [CommandLineOptions] object. The
- * following flags are parsed by this method.
- *
- *   * `--changed file-path`: notify of a file change.
- *   * `--removed file-path`: notify that a file was removed.
- *   * `--clean`: remove temporary artifacts (if any)
- *   * `--full`: build everything, similar to marking every file as changed
- *   * `--machine`: produce output that can be parsed by tools, such as the Dart
- *     Editor.
- *   * `--deploy`: force deploy.
- *   * `--no-js`: deploy replaces *.dart scripts with *.dart.js. You can turn
- *     this feature off with --no-js, which leaves "packages/browser/dart.js".
- *   * `--csp`: replaces *.dart with *.dart.precompiled.js to comply with
- *     Content Security Policy restrictions.
- *   * `--help`: print documentation for each option and exit.
- *
- * Currently not all the flags are used by [lint] or [deploy] above, but they
- * are available so they can be used from your `build.dart`. For instance, see
- * the top-level library documentation for an example that uses the force-deploy
- * option to conditionally call [deploy].
- *
- * If this documentation becomes out of date, the best way to discover which
- * flags are supported is to invoke this function from your build.dart, and run
- * it with the `--help` command-line flag.
- */
+/// Parse command-line arguments and return a [CommandLineOptions] object. The
+/// following flags are parsed by this method.
+///
+///   * `--changed file-path`: notify of a file change.
+///   * `--removed file-path`: notify that a file was removed.
+///   * `--clean`: remove temporary artifacts (if any)
+///   * `--full`: build everything, similar to marking every file as changed
+///   * `--machine`: produce output that can be parsed by tools, such as the
+///     Dart Editor.
+///   * `--deploy`: force deploy.
+///   * `--no-js`: deploy replaces *.dart scripts with *.dart.js. You can turn
+///     this feature off with --no-js, which leaves "packages/browser/dart.js".
+///   * `--csp`: replaces *.dart with *.dart.precompiled.js to comply with
+///     Content Security Policy restrictions.
+///   * `--help`: print documentation for each option and exit.
+///
+/// Currently not all the flags are used by [lint] or [deploy] above, but they
+/// are available so they can be used from your `build.dart`. For instance, see
+/// the top-level library documentation for an example that uses the
+/// force-deploy option to conditionally call [deploy].
+///
+/// If this documentation becomes out of date, the best way to discover which
+/// flags are supported is to invoke this function from your build.dart, and run
+/// it with the `--help` command-line flag.
 CommandLineOptions parseOptions([List<String> args]) {
   if (args == null) {
     print('warning: the list of arguments from main(List<String> args) now '
diff --git a/pkg/polymer/lib/deploy.dart b/pkg/polymer/lib/deploy.dart
index 2a4cfb75..5fe199d 100644
--- a/pkg/polymer/lib/deploy.dart
+++ b/pkg/polymer/lib/deploy.dart
@@ -2,32 +2,29 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * **Note**: If you already have a `build.dart` in your application, we
- * recommend to use the `package:polymer/builder.dart` library instead.
+/// **Note**: If you already have a `build.dart` in your application, we
+/// recommend to use the `package:polymer/builder.dart` library instead.
 
- * Temporary deploy command used to create a version of the app that can be
- * compiled with dart2js and deployed. Following pub layout conventions, this
- * script will treat any HTML file under a package 'web/' and 'test/'
- * directories as entry points.
- *
- * From an application package you can run deploy by creating a small program
- * as follows:
- *
- *    import "package:polymer/deploy.dart" as deploy;
- *    main() => deploy.main();
- *
- * This library should go away once `pub deploy` can be configured to run
- * barback transformers.
- */
+/// Temporary deploy command used to create a version of the app that can be
+/// compiled with dart2js and deployed. Following pub layout conventions, this
+/// script will treat any HTML file under a package 'web/' and 'test/'
+/// directories as entry points.
+///
+/// From an application package you can run deploy by creating a small program
+/// as follows:
+///
+///    import "package:polymer/deploy.dart" as deploy;
+///    main() => deploy.main();
+///
+/// This library should go away once `pub deploy` can be configured to run
+/// barback transformers.
 library polymer.deploy;
 
-import 'dart:async';
 import 'dart:io';
 
 import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
-import 'src/build/common.dart' show TransformOptions;
+import 'src/build/common.dart' show TransformOptions, phasesForPolymer;
 import 'src/build/runner.dart';
 import 'transformer.dart';
 
@@ -44,7 +41,11 @@
         directlyIncludeJS: args['js'],
         contentSecurityPolicy: args['csp'],
         releaseMode: !args['debug']);
-    options = new BarbackOptions(createDeployPhases(transformOps), outDir);
+    var phases = createDeployPhases(transformOps);
+    options = new BarbackOptions(phases, outDir,
+        // TODO(sigmund): include here also smoke transformer when it's on by
+        // default.
+        packagePhases: {'polymer': phasesForPolymer});
   } else {
     options = _createTestOptions(
         test, outDir, args['js'], args['csp'], !args['debug']);
@@ -76,6 +77,10 @@
   }
   var packageName = readCurrentPackageFromPubspec(pubspecDir);
 
+  // Find the dart-root so we can include both polymer and smoke as additional
+  // packages whose transformers we need to run.
+  var pkgDir = path.join(_findDirWithDir(path.absolute(testDir), 'pkg'), 'pkg');
+
   var phases = createDeployPhases(new TransformOptions(
       entryPoints: [path.relative(testFile, from: pubspecDir)],
       directlyIncludeJS: directlyIncludeJS,
@@ -83,7 +88,17 @@
       releaseMode: releaseMode));
   return new BarbackOptions(phases, outDir,
       currentPackage: packageName,
-      packageDirs: {packageName : pubspecDir},
+      packageDirs: {
+        'polymer': path.join(pkgDir, 'polymer'),
+        'smoke': path.join(pkgDir, 'smoke'),
+        // packageName may be a duplicate of 'polymer', but that's ok, the
+        // following will be the value used in the map (they should also be the
+        // same value).
+        packageName: pubspecDir,
+      },
+      // TODO(sigmund): include here also smoke transformer when it's on by
+      // default.
+      packagePhases: {'polymer': phasesForPolymer},
       transformTests: true);
 }
 
@@ -97,6 +112,16 @@
   return dir;
 }
 
+String _findDirWithDir(String dir, String subdir) {
+  while (!new Directory(path.join(dir, subdir)).existsSync()) {
+    var parentDir = path.dirname(dir);
+    // If we reached root and failed to find it, bail.
+    if (parentDir == dir) return null;
+    dir = parentDir;
+  }
+  return dir;
+}
+
 void _reportErrorAndExit(e, trace) {
   print('Uncaught error: $e');
   if (trace != null) print(trace);
diff --git a/pkg/polymer/lib/deserialize.dart b/pkg/polymer/lib/deserialize.dart
index 60e63f7..32499ff 100644
--- a/pkg/polymer/lib/deserialize.dart
+++ b/pkg/polymer/lib/deserialize.dart
@@ -5,14 +5,11 @@
 library polymer.deserialize;
 
 import 'dart:convert' show JSON;
-import 'dart:mirrors' show TypeMirror;
 
-final _typeHandlers = () {
-  // TODO(jmesserly): switch to map and symbol literal form when supported.
-  var m = new Map();
-  m[#dart.core.String] = (x, _) => x;
-  m[#dart.core.Null] = (x, _) => x;
-  m[#dart.core.DateTime] = (x, def) {
+final _typeHandlers = {
+  String: (x, _) => x,
+  Null: (x, _) => x,
+  DateTime: (x, def) {
     // TODO(jmesserly): shouldn't need to try-catch here
     // See: https://code.google.com/p/dart/issues/detail?id=1878
     try {
@@ -20,20 +17,15 @@
     } catch (e) {
       return def;
     }
-  };
-  m[#dart.core.bool] = (x, _) => x != 'false';
-  m[#dart.core.int] =
-      (x, def) => int.parse(x, onError: (_) => def);
-  m[#dart.core.double] =
-      (x, def) => double.parse(x, (_) => def);
-  return m;
-}();
+  },
+  bool: (x, _) => x != 'false',
+  int: (x, def) => int.parse(x, onError: (_) => def),
+  double: (x, def) => double.parse(x, (_) => def),
+};
 
-/**
- * Convert representation of [value] based on type of [currentValue].
- */
-Object deserializeValue(String value, Object currentValue, TypeMirror type) {
-  var handler = _typeHandlers[type.qualifiedName];
+/// Convert representation of [value] based on [type] and [currentValue].
+Object deserializeValue(String value, Object currentValue, Type type) {
+  var handler = _typeHandlers[type];
   if (handler != null) return handler(value, currentValue);
 
   try {
diff --git a/pkg/polymer/lib/init.dart b/pkg/polymer/lib/init.dart
index 8eba9de..615c021 100644
--- a/pkg/polymer/lib/init.dart
+++ b/pkg/polymer/lib/init.dart
@@ -2,20 +2,18 @@
 // for 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 that automatically initializes polymer elements without having to
- * write a main for your application.
- *
- * If a polymer application is written entirely with `<polymer-element>` tags
- * and there is no initialization code that needs to happen before these
- * elements are created, then, instead of creating your own `main`, you can
- * simply include a script tag loading this library:
- *
- *    <script type="application/dart">import "package:polymer/init.dart";
- *    </script>
- *
- * This script tag should be placed after all HTML imports on your page.
- */
+/// Library that automatically initializes polymer elements without having to
+/// write a main for your application.
+///
+/// If a polymer application is written entirely with `<polymer-element>` tags
+/// and there is no initialization code that needs to happen before these
+/// elements are created, then, instead of creating your own `main`, you can
+/// simply include a script tag loading this library:
+///
+///    <script type="application/dart">import "package:polymer/init.dart";
+///    </script>
+///
+/// This script tag should be placed after all HTML imports on your page.
 library polymer.init;
 
 import 'package:polymer/polymer.dart';
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index 7aaedc0..6f6847e 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -2,41 +2,39 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Custom HTML tags, data binding, and templates for building
- * structured, encapsulated, client-side web apps.
- *
- * Polymer.dart, the next evolution of Web UI,
- * is an in-progress Dart port of the
- * [Polymer project](http://www.polymer-project.org/).
- * Polymer.dart compiles to JavaScript and runs across the modern web.
- *
- * To use polymer.dart in your application,
- * first add a
- * [dependency](http://pub.dartlang.org/doc/dependencies.html)
- * to the app's pubspec.yaml file.
- * Instead of using the open-ended `any` version specifier,
- * we recommend using a range of version numbers, as in this example:
- *
- *     dependencies:
- *       polymer: '>=0.7.1 <0.8'
- *
- * Then import the library into your application:
- *
- *     import 'package:polymer/polymer.dart';
- *
- * ## Other resources
- *
- * * [Polymer.dart homepage](http://www.dartlang.org/polymer-dart/):
- * Example code, project status, and
- * information about how to get started using Polymer.dart in your apps.
- *
- * * [polymer.dart package](http://pub.dartlang.org/packages/polymer):
- * More details, such as the current major release number.
- *
- * * [Upgrading to Polymer.dart](http://www.dartlang.org/polymer-dart/upgrading-to-polymer-from-web-ui.html):
- * Tips for converting your apps from Web UI to Polymer.dart.
- */
+/// Custom HTML tags, data binding, and templates for building
+/// structured, encapsulated, client-side web apps.
+///
+/// Polymer.dart, the next evolution of Web UI,
+/// is an in-progress Dart port of the
+/// [Polymer project](http://www.polymer-project.org/).
+/// Polymer.dart compiles to JavaScript and runs across the modern web.
+///
+/// To use polymer.dart in your application,
+/// first add a
+/// [dependency](http://pub.dartlang.org/doc/dependencies.html)
+/// to the app's pubspec.yaml file.
+/// Instead of using the open-ended `any` version specifier,
+/// we recommend using a range of version numbers, as in this example:
+///
+///     dependencies:
+///       polymer: '>=0.7.1 <0.8'
+///
+/// Then import the library into your application:
+///
+///     import 'package:polymer/polymer.dart';
+///
+/// ## Other resources
+///
+/// * [Polymer.dart homepage](http://www.dartlang.org/polymer-dart/):
+/// Example code, project status, and
+/// information about how to get started using Polymer.dart in your apps.
+///
+/// * [polymer.dart package](http://pub.dartlang.org/packages/polymer):
+/// More details, such as the current major release number.
+///
+/// * [Upgrading to Polymer.dart](http://www.dartlang.org/polymer-dart/upgrading-to-polymer-from-web-ui.html):
+/// Tips for converting your apps from Web UI to Polymer.dart.
 library polymer;
 
 import 'dart:async';
@@ -45,8 +43,10 @@
 import 'dart:js' as js;
 
 @MirrorsUsed(metaTargets:
-    const [Reflectable, ObservableProperty, CustomTag, _InitMethodAnnotation],
-    override: const ['polymer', 'polymer.deserialize'])
+    const [Reflectable, ObservableProperty, PublishedProperty, CustomTag,
+        _InitMethodAnnotation],
+    targets: const [PublishedProperty],
+    override: const ['smoke.mirrors', 'polymer'])
 import 'dart:mirrors';
 
 import 'package:logging/logging.dart' show Logger, Level;
@@ -55,6 +55,8 @@
 import 'package:path/path.dart' as path;
 import 'package:polymer_expressions/polymer_expressions.dart'
     show PolymerExpressions;
+import 'package:smoke/smoke.dart' as smoke;
+import 'package:smoke/mirrors.dart' as smoke;
 import 'package:template_binding/template_binding.dart';
 import 'package:web_components/polyfill.dart' show customElementsReady;
 
diff --git a/pkg/polymer/lib/src/boot.dart b/pkg/polymer/lib/src/boot.dart
index e0109e8..0bad65f 100644
--- a/pkg/polymer/lib/src/boot.dart
+++ b/pkg/polymer/lib/src/boot.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/** Ported from `polymer/src/boot.js`. **/
+/// Ported from `polymer/src/boot.js`. *
 part of polymer;
 
-/** Prevent a flash of unstyled content. */
+/// Prevent a flash of unstyled content.
 _preventFlashOfUnstyledContent() {
 
   var style = new StyleElement();
diff --git a/pkg/polymer/lib/src/build/build_filter.dart b/pkg/polymer/lib/src/build/build_filter.dart
index 9bc8bd4..fc2138d 100644
--- a/pkg/polymer/lib/src/build/build_filter.dart
+++ b/pkg/polymer/lib/src/build/build_filter.dart
@@ -2,10 +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.
 
-/**
- * Final phase of the polymer transformation: removes any files that are not
- * needed for deployment.
- */
+/// Final phase of the polymer transformation: removes any files that are not
+/// needed for deployment.
 library polymer.src.build.build_filter;
 
 import 'dart:async';
@@ -13,10 +11,8 @@
 import 'package:barback/barback.dart';
 import 'common.dart';
 
-/**
- * Removes any files not needed for deployment, such as internal build artifacts
- * and non-entry HTML files.
- */
+/// Removes any files not needed for deployment, such as internal build
+/// artifacts and non-entry HTML files.
 class BuildFilter extends Transformer with PolymerTransformer {
   final TransformOptions options;
   BuildFilter(this.options);
@@ -39,7 +35,7 @@
     return readPrimaryAsHtml(transform).then((document) {
       // Keep .html files that don't use polymer, since the app developer might
       // have non-polymer entrypoints.
-      if (document.queryAll('polymer-element').isEmpty) {
+      if (document.querySelectorAll('polymer-element').isEmpty) {
         transform.addOutput(transform.primaryInput);
       }
     });
diff --git a/pkg/polymer/lib/src/build/code_extractor.dart b/pkg/polymer/lib/src/build/code_extractor.dart
index a349f08..c66e8972 100644
--- a/pkg/polymer/lib/src/build/code_extractor.dart
+++ b/pkg/polymer/lib/src/build/code_extractor.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.
 
-/** Transfomer that extracts inlined script code into separate assets. */
+/// Transfomer that extracts inlined script code into separate assets.
 library polymer.src.build.code_extractor;
 
 import 'dart:async';
@@ -16,16 +16,14 @@
 
 import 'common.dart';
 
-/**
- * Transformer that extracts Dart code inlined in HTML script tags and outputs a
- * separate file for each.
- */
+/// Transformer that extracts Dart code inlined in HTML script tags and outputs
+/// a separate file for each.
 class InlineCodeExtractor extends Transformer with PolymerTransformer {
   final TransformOptions options;
 
   InlineCodeExtractor(this.options);
 
-  /** Only run this transformer on .html files. */
+  /// Only run this transformer on .html files.
   final String allowedExtensions = ".html";
 
   Future apply(Transform transform) {
@@ -34,7 +32,7 @@
     return readPrimaryAsHtml(transform).then((document) {
       int count = 0;
       bool htmlChanged = false;
-      for (var tag in document.queryAll('script')) {
+      for (var tag in document.querySelectorAll('script')) {
         // Only process tags that have inline Dart code
         if (tag.attributes['type'] != 'application/dart' ||
           tag.attributes.containsKey('src')) {
@@ -52,7 +50,7 @@
         // TODO(sigmund): ensure this filename is unique (dartbug.com/12618).
         tag.attributes['src'] = '$filename.$count.dart';
         var textContent = tag.nodes.first;
-        var code = textContent.value;
+        var code = textContent.text;
         var newId = id.addExtension('.$count.dart');
         if (!_hasLibraryDirective(code)) {
           var libname = path.withoutExtension(newId.path)
@@ -69,7 +67,7 @@
   }
 }
 
-/** Parse [code] and determine whether it has a library directive. */
+/// Parse [code] and determine whether it has a library directive.
 bool _hasLibraryDirective(String code) {
   var errorListener = new _ErrorCollector();
   var reader = new CharSequenceReader(code);
diff --git a/pkg/polymer/lib/src/build/common.dart b/pkg/polymer/lib/src/build/common.dart
index 516c02c..bcde554 100644
--- a/pkg/polymer/lib/src/build/common.dart
+++ b/pkg/polymer/lib/src/build/common.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.
 
-/** Common methods used by transfomers. */
+/// Common methods used by transfomers.
 library polymer.src.build.common;
 
 import 'dart:async';
@@ -12,12 +12,11 @@
 import 'package:html5lib/dom.dart' show Document;
 import 'package:html5lib/parser.dart' show HtmlParser;
 import 'package:path/path.dart' as path;
+import 'package:observe/transformer.dart' show ObservableTransformer;
 import 'package:source_maps/span.dart' show Span;
 
-/**
- * Parses an HTML file [contents] and returns a DOM-like tree. Adds emitted
- * error/warning to [logger].
- */
+/// Parses an HTML file [contents] and returns a DOM-like tree. Adds emitted
+/// error/warning to [logger].
 Document _parseHtml(String contents, String sourcePath, TransformLogger logger,
     {bool checkDocType: true}) {
   // TODO(jmesserly): make HTTP encoding configurable
@@ -35,38 +34,30 @@
   return document;
 }
 
-/** Additional options used by polymer transformers */
+/// Additional options used by polymer transformers
 class TransformOptions {
-  /**
-   * List of entrypoints paths. The paths are relative to the package root and
-   * are represented using posix style, which matches the representation used in
-   * asset ids in barback. If null, anything under 'web/' or 'test/' is
-   * considered an entry point.
-   */
+  /// List of entrypoints paths. The paths are relative to the package root and
+  /// are represented using posix style, which matches the representation used
+  /// in asset ids in barback. If null, anything under 'web/' or 'test/' is
+  /// considered an entry point.
   final List<String> entryPoints;
 
-  /**
-   * True to enable Content Security Policy.
-   * This means the HTML page will include *.dart.precompiled.js
-   *
-   * This flag has no effect unless [directlyIncludeJS] is enabled.
-   */
+  /// True to enable Content Security Policy.
+  /// This means the HTML page will include *.dart.precompiled.js
+  ///
+  /// This flag has no effect unless [directlyIncludeJS] is enabled.
   final bool contentSecurityPolicy;
 
-  /**
-   * True to include the compiled JavaScript directly from the HTML page.
-   * If enabled this will remove "packages/browser/dart.js" and replace
-   * `type="application/dart"` scripts with equivalent *.dart.js files.
-   *
-   * If [contentSecurityPolicy] enabled, this will reference files
-   * named *.dart.precompiled.js.
-   */
+  /// True to include the compiled JavaScript directly from the HTML page.
+  /// If enabled this will remove "packages/browser/dart.js" and replace
+  /// `type="application/dart"` scripts with equivalent *.dart.js files.
+  ///
+  /// If [contentSecurityPolicy] enabled, this will reference files
+  /// named *.dart.precompiled.js.
   final bool directlyIncludeJS;
 
-  /**
-   * Run transformers to create a releasable app. For example, include the
-   * minified versions of the polyfills rather than the debug versions.
-   */
+  /// Run transformers to create a releasable app. For example, include the
+  /// minified versions of the polyfills rather than the debug versions.
   final bool releaseMode;
 
   TransformOptions({entryPoints, this.contentSecurityPolicy: false,
@@ -74,7 +65,7 @@
       : entryPoints = entryPoints == null ? null
           : entryPoints.map(_systemToAssetPath).toList();
 
-  /** Whether an asset with [id] is an entry point HTML file. */
+  /// Whether an asset with [id] is an entry point HTML file.
   bool isHtmlEntryPoint(AssetId id) {
     if (id.extension != '.html') return false;
 
@@ -87,7 +78,7 @@
   }
 }
 
-/** Mixin for polymer transformers. */
+/// Mixin for polymer transformers.
 abstract class PolymerTransformer {
   TransformOptions get options;
 
@@ -103,28 +94,46 @@
   Future<Document> readAsHtml(AssetId id, Transform transform) {
     var primaryId = transform.primaryInput.id;
     bool samePackage = id.package == primaryId.package;
-    var url = samePackage ? id.path
-        : assetUrlFor(id, primaryId, transform.logger, allowAssetUrl: true);
+    var url = spanUrlFor(id, transform);
     return transform.readInputAsString(id).then((content) {
       return _parseHtml(content, url, transform.logger,
         checkDocType: samePackage && options.isHtmlEntryPoint(id));
     });
   }
 
+  /// Gets the appropriate URL to use in a [Span] to produce messages
+  /// (e.g. warnings) for users. This will attempt to format the URL in the most
+  /// useful way:
+  ///
+  /// - If the asset is within the primary package, then use the [id.path],
+  ///   the user will know it is a file from their own code.
+  /// - If the asset is from another package, then use [assetUrlFor], this will
+  ///   likely be a "package:" url to the file in the other package, which is
+  ///   enough for users to identify where the error is.
+  String spanUrlFor(AssetId id, Transform transform) {
+    var primaryId = transform.primaryInput.id;
+    bool samePackage = id.package == primaryId.package;
+    return samePackage ? id.path
+        : assetUrlFor(id, primaryId, transform.logger, allowAssetUrl: true);
+  }
+
   Future<bool> assetExists(AssetId id, Transform transform) =>
       transform.getInput(id).then((_) => true).catchError((_) => false);
 
   String toString() => 'polymer ($runtimeType)';
 }
 
-/**
- * Create an [AssetId] for a [url] seen in the [source] asset. By default this
- * is used to resolve relative urls that occur in HTML assets, including
- * cross-package urls of the form "packages/foo/bar.html". Dart-style "package:"
- * urls are not resolved unless [source] is Dart file (has a .dart extension).
- */
+/// Transformer phases which should be applied to the Polymer package.
+List<List<Transformer>> get phasesForPolymer =>
+    [[new ObservableTransformer(['lib/src/instance.dart'])]];
+
+/// Create an [AssetId] for a [url] seen in the [source] asset. By default this
+/// is used to resolve relative urls that occur in HTML assets, including
+/// cross-package urls of the form "packages/foo/bar.html". Dart "package:"
+/// urls are not resolved unless [source] is Dart file (has a .dart extension).
 // TODO(sigmund): delete once this is part of barback (dartbug.com/12610)
-AssetId resolve(AssetId source, String url, TransformLogger logger, Span span) {
+AssetId resolve(AssetId source, String url, TransformLogger logger, Span span,
+    {bool allowAbsolute: false}) {
   if (url == null || url == '') return null;
   var uri = Uri.parse(url);
   var urlBuilder = path.url;
@@ -135,9 +144,11 @@
         return new AssetId(uri.path.substring(0, index),
             'lib${uri.path.substring(index)}');
       }
-    } 
+    }
 
-    logger.error('absolute paths not allowed: "$url"', span: span);
+    if (!allowAbsolute) {
+      logger.error('absolute paths not allowed: "$url"', span: span);
+    }
     return null;
   }
 
@@ -203,10 +214,8 @@
       path.url.join(folder, path.url.joinAll(segments.sublist(index + 2))));
 }
 
-/**
- * Generate the import url for a file described by [id], referenced by a file
- * with [sourceId].
- */
+/// Generate the import url for a file described by [id], referenced by a file
+/// with [sourceId].
 // TODO(sigmund): this should also be in barback (dartbug.com/12610)
 String assetUrlFor(AssetId id, AssetId sourceId, TransformLogger logger,
     {bool allowAssetUrl: false}) {
@@ -236,7 +245,7 @@
 }
 
 
-/** Convert system paths to asset paths (asset paths are posix style). */
+/// Convert system paths to asset paths (asset paths are posix style).
 String _systemToAssetPath(String assetPath) {
   if (path.Style.platform != path.Style.windows) return assetPath;
   return path.posix.joinAll(path.split(assetPath));
diff --git a/pkg/polymer/lib/src/build/import_inliner.dart b/pkg/polymer/lib/src/build/import_inliner.dart
index 126dc1e..40d5ca5 100644
--- a/pkg/polymer/lib/src/build/import_inliner.dart
+++ b/pkg/polymer/lib/src/build/import_inliner.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.
 
-/** Transfomer that inlines polymer-element definitions from html imports. */
+/// Transfomer that inlines polymer-element definitions from html imports.
 library polymer.src.build.import_inliner;
 
 import 'dart:async';
@@ -13,7 +13,7 @@
 import 'package:html5lib/dom.dart' show
     Document, DocumentFragment, Element, Node;
 import 'package:html5lib/dom_parsing.dart' show TreeVisitor;
-import 'package:source_maps/span.dart' show Span;
+import 'package:source_maps/span.dart';
 
 import 'code_extractor.dart'; // import just for documentation.
 import 'common.dart';
@@ -24,9 +24,11 @@
   final TransformLogger logger;
   final AssetId docId;
   final seen = new Set<AssetId>();
-  final imported = new DocumentFragment();
   final scriptIds = <AssetId>[];
 
+  static const TYPE_DART = 'application/dart';
+  static const TYPE_JS = 'text/javascript';
+
   _HtmlInliner(this.options, Transform transform)
       : transform = transform,
         logger = transform.logger,
@@ -40,12 +42,11 @@
     return readPrimaryAsHtml(transform).then((document) =>
         _visitImports(document, docId).then((importsFound) {
 
+      var output = transform.primaryInput;
       if (importsFound) {
-        document.body.insertBefore(imported, document.body.firstChild);
-        transform.addOutput(new Asset.fromString(docId, document.outerHtml));
-      } else {
-        transform.addOutput(transform.primaryInput);
+        output = new Asset.fromString(docId, document.outerHtml);
       }
+      transform.addOutput(output);
 
       // We produce a secondary asset with extra information for later phases.
       transform.addOutput(new Asset.fromString(
@@ -54,32 +55,73 @@
     }));
   }
 
-  /**
-   * Visits imports in [document] and add the imported documents to [documents].
-   * Documents are added in the order they appear, transitive imports are added
-   * first.
-   */
+  /// Visits imports in [document] and add the imported documents to documents.
+  /// Documents are added in the order they appear, transitive imports are added
+  /// first.
+  ///
+  /// Returns `true` if and only if the document was changed and should be
+  /// written out.
   Future<bool> _visitImports(Document document, AssetId sourceId) {
-    bool hasImports = false;
+    bool changed = false;
+
+    _moveHeadToBody(document);
 
     // Note: we need to preserve the import order in the generated output.
     return Future.forEach(document.querySelectorAll('link'), (Element tag) {
-      if (tag.attributes['rel'] != 'import') return null;
+      var rel = tag.attributes['rel'];
+      if (rel != 'import' && rel != 'stylesheet') return null;
+
       var href = tag.attributes['href'];
-      var id = resolve(sourceId, href, transform.logger, tag.sourceSpan);
-      hasImports = true;
+      var id = resolve(sourceId, href, transform.logger, tag.sourceSpan,
+          allowAbsolute: rel == 'stylesheet');
 
-      tag.remove();
-      if (id == null || !seen.add(id) ||
-         (id.package == 'polymer' && id.path == 'lib/init.html')) return null;
+      if (rel == 'import') {
+        changed = true;
+        if (id == null || !seen.add(id)) {
+          tag.remove();
+          return null;
+        }
+        return _inlineImport(id, tag);
 
-      return _inlineImport(id);
-    }).then((_) => hasImports);
+      } else if (rel == 'stylesheet') {
+        if (id == null) return null;
+        changed = true;
+
+        return _inlineStylesheet(id, tag);
+      }
+    }).then((_) => changed);
+  }
+
+  /// To preserve the order of scripts with respect to inlined
+  /// link rel=import, we move both of those into the body before we do any
+  /// inlining.
+  ///
+  /// Note: we do this for stylesheets as well to preserve ordering with
+  /// respect to eachother, because stylesheets can be pulled in transitively
+  /// from imports.
+  // TODO(jmesserly): vulcanizer doesn't need this because they inline JS
+  // scripts, causing them to be naturally moved as part of the inlining.
+  // Should we do the same? Alternatively could we inline head into head and
+  // body into body and avoid this whole thing?
+  void _moveHeadToBody(Document doc) {
+    var insertionPoint = doc.body.firstChild;
+    for (var node in doc.head.nodes.toList(growable: false)) {
+      if (node is! Element) continue;
+      var tag = node.tagName;
+      var type = node.attributes['type'];
+      var rel = node.attributes['rel'];
+      if (tag == 'style' || tag == 'script' &&
+            (type == null || type == TYPE_JS || type == TYPE_DART) ||
+          tag == 'link' && (rel == 'stylesheet' || rel == 'import')) {
+        // Move the node into the body, where its contents will be placed.
+        doc.body.insertBefore(node, insertionPoint);
+      }
+    }
   }
 
   // Loads an asset identified by [id], visits its imports and collects its
   // html imports. Then inlines it into the main document.
-  Future _inlineImport(AssetId id) =>
+  Future _inlineImport(AssetId id, Element link) =>
       readAsHtml(id, transform).then((doc) => _visitImports(doc, id).then((_) {
 
     new _UrlNormalizer(transform, id).visit(doc);
@@ -87,21 +129,27 @@
 
     // TODO(jmesserly): figure out how this is working in vulcanizer.
     // Do they produce a <body> tag with a <head> and <body> inside?
-    imported.nodes
-        ..addAll(doc.head.nodes)
-        ..addAll(doc.body.nodes);
+    var imported = new DocumentFragment();
+    imported.nodes..addAll(doc.head.nodes)..addAll(doc.body.nodes);
+    link.replaceWith(imported);
   }));
 
-  /**
-   * Split Dart script tags from all the other elements. Now that Dartium
-   * only allows a single script tag per page, we can't inline script
-   * tags. Instead, we collect the urls of each script tag so we import
-   * them directly from the Dart bootstrap code.
-   */
+  Future _inlineStylesheet(AssetId id, Element link) {
+    return transform.readInputAsString(id).then((css) {
+      var url = spanUrlFor(id, transform);
+      css = new _UrlNormalizer(transform, id).visitCss(css, url);
+      link.replaceWith(new Element.tag('style')..text = css);
+    });
+  }
+
+  /// Split Dart script tags from all the other elements. Now that Dartium
+  /// only allows a single script tag per page, we can't inline script
+  /// tags. Instead, we collect the urls of each script tag so we import
+  /// them directly from the Dart bootstrap code.
   void _extractScripts(Document document) {
     bool first = true;
     for (var script in document.querySelectorAll('script')) {
-      if (script.attributes['type'] == 'application/dart') {
+      if (script.attributes['type'] == TYPE_DART) {
         script.remove();
 
         // only one Dart script per document is supported in Dartium.
@@ -128,21 +176,20 @@
   }
 }
 
-/**
- * Recursively inlines the contents of HTML imports. Produces as output a single
- * HTML file that inlines the polymer-element definitions, and a text file that
- * contains, in order, the URIs to each library that sourced in a script tag.
- *
- * This transformer assumes that all script tags point to external files. To
- * support script tags with inlined code, use this transformer after running
- * [InlineCodeExtractor] on an earlier phase.
- */
+/// Recursively inlines the contents of HTML imports. Produces as output a
+/// single HTML file that inlines the polymer-element definitions, and a text
+/// file that contains, in order, the URIs to each library that sourced in a
+/// script tag.
+///
+/// This transformer assumes that all script tags point to external files. To
+/// support script tags with inlined code, use this transformer after running
+/// [InlineCodeExtractor] on an earlier phase.
 class ImportInliner extends Transformer {
   final TransformOptions options;
 
   ImportInliner(this.options);
 
-  /** Only run on entry point .html files. */
+  /// Only run on entry point .html files.
   Future<bool> isPrimary(Asset input) =>
       new Future.value(options.isHtmlEntryPoint(input.id));
 
@@ -151,11 +198,11 @@
 }
 
 
-/** Internally adjusts urls in the html that we are about to inline. */
+/// Internally adjusts urls in the html that we are about to inline.
 class _UrlNormalizer extends TreeVisitor {
   final Transform transform;
 
-  /** Asset where the original content (and original url) was found. */
+  /// Asset where the original content (and original url) was found.
   final AssetId sourceId;
 
   _UrlNormalizer(this.transform, this.sourceId);
@@ -172,6 +219,25 @@
     super.visitElement(node);
   }
 
+  static final _URL = new RegExp(r'url\(([^)]*)\)', multiLine: true);
+  static final _QUOTE = new RegExp('["\']', multiLine: true);
+
+  /// Visit the CSS text and replace any relative URLs so we can inline it.
+  // Ported from:
+  // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378acc691f/lib/vulcan.js#L149
+  // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness.
+  // Maybe it's reliable enough for finding URLs in CSS? I'm not sure.
+  String visitCss(String cssText, String url) {
+    var src = new SourceFile.text(url, cssText);
+    return cssText.replaceAllMapped(_URL, (match) {
+      // Extract the URL, without any surrounding quotes.
+      var span = src.span(match.start, match.end);
+      var href = match[1].replaceAll(_QUOTE, '');
+      href = _newUrl(href, span);
+      return 'url($href)';
+    });
+  }
+
   _newUrl(String href, Span span) {
     var uri = Uri.parse(href);
     if (uri.isAbsolute) return href;
@@ -205,13 +271,11 @@
   }
 }
 
-/**
- * HTML attributes that expect a URL value.
- * <http://dev.w3.org/html5/spec/section-index.html#attributes-1>
- *
- * Every one of these attributes is a URL in every context where it is used in
- * the DOM. The comments show every DOM element where an attribute can be used.
- */
+/// HTML attributes that expect a URL value.
+/// <http://dev.w3.org/html5/spec/section-index.html#attributes-1>
+///
+/// Every one of these attributes is a URL in every context where it is used in
+/// the DOM. The comments show every DOM element where an attribute can be used.
 const _urlAttributes = const [
   'action',     // in form
   'background', // in body
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index b553ff0..06004eb 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -2,16 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Logic to validate that developers are correctly using Polymer constructs.
- * This is mainly used to produce warnings for feedback in the editor.
- */
+/// Logic to validate that developers are correctly using Polymer constructs.
+/// This is mainly used to produce warnings for feedback in the editor.
 library polymer.src.build.linter;
 
-import 'dart:io';
 import 'dart:async';
-import 'dart:mirrors';
-import 'dart:convert' show JSON;
 
 import 'package:barback/barback.dart';
 import 'package:html5lib/dom.dart';
@@ -21,15 +16,13 @@
 import 'common.dart';
 import 'utils.dart';
 
-/**
- * A linter that checks for common Polymer errors and produces warnings to
- * show on the editor or the command line. Leaves sources unchanged, but creates
- * a new asset containing all the warnings.
- */
+/// A linter that checks for common Polymer errors and produces warnings to
+/// show on the editor or the command line. Leaves sources unchanged, but
+/// creates a new asset containing all the warnings.
 class Linter extends Transformer with PolymerTransformer {
   final TransformOptions options;
 
-  /** Only run on .html files. */
+  /// Only run on .html files.
   final String allowedExtensions = '.html';
 
   Linter(this.options);
@@ -49,12 +42,10 @@
     });
   }
 
-  /**
-   * Collect into [elements] any data about each polymer-element defined in
-   * [document] or any of it's imports, unless they have already been [seen].
-   * Elements are added in the order they appear, transitive imports are added
-   * first.
-   */
+  /// Collect into [elements] any data about each polymer-element defined in
+  /// [document] or any of it's imports, unless they have already been [seen].
+  /// Elements are added in the order they appear, transitive imports are added
+  /// first.
   Future<Map<String, _ElementSummary>> _collectElements(
       Document document, AssetId sourceId, Transform transform,
       Set<AssetId> seen, [Map<String, _ElementSummary> elements]) {
@@ -79,7 +70,7 @@
       Document document, AssetId sourceId, Transform transform) {
     var importIds = [];
     var logger = transform.logger;
-    for (var tag in document.queryAll('link')) {
+    for (var tag in document.querySelectorAll('link')) {
       if (tag.attributes['rel'] != 'import') continue;
       var href = tag.attributes['href'];
       var span = tag.sourceSpan;
@@ -99,7 +90,7 @@
 
   void _addElements(Document document, TransformLogger logger,
       Map<String, _ElementSummary> elements) {
-    for (var tag in document.queryAll('polymer-element')) {
+    for (var tag in document.querySelectorAll('polymer-element')) {
       var name = tag.attributes['name'];
       if (name == null) continue;
       var extendsTag = tag.attributes['extends'];
@@ -123,13 +114,11 @@
 }
 
 
-/**
- * Information needed about other polymer-element tags in order to validate
- * how they are used and extended.
- *
- * Note: these are only created for polymer-element, because pure custom
- * elements don't have a declarative form.
- */
+/// Information needed about other polymer-element tags in order to validate
+/// how they are used and extended.
+///
+/// Note: these are only created for polymer-element, because pure custom
+/// elements don't have a declarative form.
 class _ElementSummary {
   final String tagName;
   final String extendsTag;
@@ -164,7 +153,7 @@
   }
 
   void visitElement(Element node) {
-    switch (node.tagName) {
+    switch (node.localName) {
       case 'link': _validateLinkElement(node); break;
       case 'element': _validateElementElement(node); break;
       case 'polymer-element': _validatePolymerElement(node); break;
@@ -184,7 +173,7 @@
     }
   }
 
-  /** Produce warnings for invalid link-rel tags. */
+  /// Produce warnings for invalid link-rel tags.
   void _validateLinkElement(Element node) {
     var rel = node.attributes['rel'];
     if (rel != 'import' && rel != 'stylesheet') return;
@@ -202,16 +191,14 @@
     _logger.warning('link rel="$rel" missing href.', span: node.sourceSpan);
   }
 
-  /** Produce warnings if using `<element>` instead of `<polymer-element>`. */
+  /// Produce warnings if using `<element>` instead of `<polymer-element>`.
   void _validateElementElement(Element node) {
     _logger.warning('<element> elements are not supported, use'
         ' <polymer-element> instead', span: node.sourceSpan);
   }
 
-  /**
-   * Produce warnings if using `<polymer-element>` in the wrong place or if the
-   * definition is not complete.
-   */
+  /// Produce warnings if using `<polymer-element>` in the wrong place or if the
+  /// definition is not complete.
   void _validatePolymerElement(Element node) {
     if (_inPolymerElement) {
       _logger.error('Nested polymer element definitions are not allowed.',
@@ -257,17 +244,15 @@
     _inPolymerElement = oldValue;
   }
 
-  /**
-   * Produces warnings for malformed script tags. In html5 leaving off type= is
-   * fine, but it defaults to text/javascript. Because this might be a common
-   * error, we warn about it when  src file ends in .dart, but the type is
-   * incorrect, or when users write code in an inline script tag of a custom
-   * element.
-   *
-   * The hope is that these cases shouldn't break existing valid code, but that
-   * they'll help Polymer authors avoid having their Dart code accidentally
-   * interpreted as JavaScript by the browser.
-   */
+  /// Produces warnings for malformed script tags. In html5 leaving off type= is
+  /// fine, but it defaults to text/javascript. Because this might be a common
+  /// error, we warn about it when  src file ends in .dart, but the type is
+  /// incorrect, or when users write code in an inline script tag of a custom
+  /// element.
+  ///
+  /// The hope is that these cases shouldn't break existing valid code, but that
+  /// they'll help Polymer authors avoid having their Dart code accidentally
+  /// interpreted as JavaScript by the browser.
   void _validateScriptElement(Element node) {
     var scriptType = node.attributes['type'];
     var isDart = scriptType == 'application/dart';
@@ -317,10 +302,8 @@
     }
   }
 
-  /**
-   * Produces warnings for misuses of on-foo event handlers, and for instanting
-   * custom tags incorrectly.
-   */
+  /// Produces warnings for misuses of on-foo event handlers, and for instanting
+  /// custom tags incorrectly.
   void _validateNormalElement(Element node) {
     // Event handlers only allowed inside polymer-elements
     node.attributes.forEach((name, value) {
@@ -330,7 +313,7 @@
     });
 
     // Validate uses of custom-tags
-    var nodeTag = node.tagName;
+    var nodeTag = node.localName;
     var hasIsAttribute;
     var customTagName;
     if (_isCustomTag(nodeTag)) {
@@ -383,9 +366,7 @@
     }
   }
 
-  /**
-   * Validate an attribute on a custom-element. Returns true if valid.
-   */
+  /// Validate an attribute on a custom-element. Returns true if valid.
   bool _validateCustomAttributeName(String name, FileSpan span) {
     if (name.contains('-')) {
       var newName = toCamelCase(name);
@@ -397,7 +378,7 @@
     return true;
   }
 
-  /** Validate event handlers are used correctly. */
+  /// Validate event handlers are used correctly.
   void _validateEventHandler(Element node, String name, String value) {
     if (!name.startsWith('on-')) {
       _logger.warning('Event handler "$name" will be interpreted as an inline'
@@ -437,10 +418,8 @@
   'missing-glyph': '',
 };
 
-/**
- * Returns true if this is a valid custom element name. See:
- * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-name>
- */
+/// Returns true if this is a valid custom element name. See:
+/// <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-name>
 bool _isCustomTag(String name) {
   if (name == null || !name.contains('-')) return false;
   return !_invalidTagNames.containsKey(name);
diff --git a/pkg/polymer/lib/src/build/polyfill_injector.dart b/pkg/polymer/lib/src/build/polyfill_injector.dart
index 02b9fd1..d1597e1 100644
--- a/pkg/polymer/lib/src/build/polyfill_injector.dart
+++ b/pkg/polymer/lib/src/build/polyfill_injector.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.
 
-/** Includes any additional polyfills that may needed by the deployed app. */
+/// Includes any additional polyfills that may needed by the deployed app.
 library polymer.src.build.polyfill_injector;
 
 import 'dart:async';
@@ -13,20 +13,18 @@
 import 'package:html5lib/parser.dart' show parseFragment;
 import 'common.dart';
 
-/**
- * Ensures that any scripts and polyfills needed to run a polymer application
- * are included. For example, this transformer will ensure that there is a
- * script tag that loads the polyfills and interop.js (used for css shimming).
- *
- * This step also replaces "packages/browser/dart.js" and the Dart script tag
- * with a script tag that loads the dart2js compiled code directly.
- */
+/// Ensures that any scripts and polyfills needed to run a polymer application
+/// are included. For example, this transformer will ensure that there is a
+/// script tag that loads the polyfills and interop.js (used for css shimming).
+///
+/// This step also replaces "packages/browser/dart.js" and the Dart script tag
+/// with a script tag that loads the dart2js compiled code directly.
 class PolyfillInjector extends Transformer with PolymerTransformer {
   final TransformOptions options;
 
   PolyfillInjector(this.options);
 
-  /** Only run on entry point .html files. */
+  /// Only run on entry point .html files.
   Future<bool> isPrimary(Asset input) =>
       new Future.value(options.isHtmlEntryPoint(input.id));
 
diff --git a/pkg/polymer/lib/src/build/runner.dart b/pkg/polymer/lib/src/build/runner.dart
index 41c65aa..bacb40d 100644
--- a/pkg/polymer/lib/src/build/runner.dart
+++ b/pkg/polymer/lib/src/build/runner.dart
@@ -2,10 +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.
 
-/**
- * Definitions used to run the polymer linter and deploy tools without using
- * pub serve or pub deploy.
- */
+/// Definitions used to run the polymer linter and deploy tools without using
+/// pub serve or pub deploy.
 library polymer.src.build.runner;
 
 import 'dart:async';
@@ -18,66 +16,65 @@
 import 'package:yaml/yaml.dart';
 
 
-/** Collects different parameters needed to configure and run barback. */
+/// Collects different parameters needed to configure and run barback.
 class BarbackOptions {
-  /** Phases of transformers to run. */
+  /// Phases of transformers to run for the current package.
+  /// Use packagePhases to specify phases for other packages.
   final List<List<Transformer>> phases;
 
-  /** Package to treat as the current package in barback. */
+  /// Package to treat as the current package in barback.
   final String currentPackage;
 
-  /**
-   * Mapping between package names and the path in the file system where
-   * to find the sources of such package.
-   */
+  /// Directory root for the current package.
+  final String packageHome;
+
+  /// Mapping between package names and the path in the file system where
+  /// to find the sources of such package.
   final Map<String, String> packageDirs;
 
-  /** Whether to run transformers on the test folder. */
+  /// Whether to run transformers on the test folder.
   final bool transformTests;
 
-  /** Whether to apply transformers on polymer dependencies. */
-  final bool transformPolymerDependencies;
-
-  /** Directory where to generate code, if any. */
+  /// Directory where to generate code, if any.
   final String outDir;
 
-  /**
-   * Whether to print error messages using a json-format that tools, such as the
-   * Dart Editor, can process.
-   */
+  /// Whether to print error messages using a json-format that tools, such as
+  /// the Dart Editor, can process.
   final bool machineFormat;
 
-  /**
-   * Whether to follow symlinks when listing directories. By default this is
-   * false because directories have symlinks for the packages directory created
-   * by pub, but it can be turned on for custom uses of this library.
-   */
+  /// Whether to follow symlinks when listing directories. By default this is
+  /// false because directories have symlinks for the packages directory created
+  /// by pub, but it can be turned on for custom uses of this library.
   final bool followLinks;
 
-  BarbackOptions(this.phases, this.outDir, {currentPackage, packageDirs,
-      this.transformTests: false, this.transformPolymerDependencies: false,
-      this.machineFormat: false, this.followLinks: false})
+  /// Phases of transformers to apply to packages other than the current
+  /// package, keyed by the package name.
+  final Map<String, List<List<Transformer>>> packagePhases;
+
+  BarbackOptions(this.phases, this.outDir, {currentPackage, String packageHome,
+      packageDirs, this.transformTests: false, this.machineFormat: false,
+      this.followLinks: false,
+      this.packagePhases: const {}})
       : currentPackage = (currentPackage != null
           ? currentPackage : readCurrentPackageFromPubspec()),
+        packageHome = packageHome,
         packageDirs = (packageDirs != null
-          ? packageDirs : _readPackageDirsFromPub(currentPackage));
+          ? packageDirs : readPackageDirsFromPub(packageHome, currentPackage));
 
 }
 
-/**
- * Creates a barback system as specified by [options] and runs it.  Returns a
- * future that contains the list of assets generated after barback runs to
- * completion.
- */
+/// Creates a barback system as specified by [options] and runs it.  Returns a
+/// future that contains the list of assets generated after barback runs to
+/// completion.
 Future<AssetSet> runBarback(BarbackOptions options) {
-  var barback = new Barback(new _PolymerPackageProvider(options.packageDirs));
+  var barback = new Barback(new _PackageProvider(options.packageDirs));
   _initBarback(barback, options);
   _attachListeners(barback, options);
   if (options.outDir == null) return barback.getAllAssets();
   return _emitAllFiles(barback, options);
 }
 
-/** Extract the current package from the pubspec.yaml file. */
+/// Extract the current package from the pubspec.yaml file.
 String readCurrentPackageFromPubspec([String dir]) {
   var pubspec = new File(
       dir == null ? 'pubspec.yaml' : path.join(dir, 'pubspec.yaml'));
@@ -89,13 +86,19 @@
   return loadYaml(pubspec.readAsStringSync())['name'];
 }
 
-/**
- * Extract a mapping between package names and the path in the file system where
- * to find the sources of such package. This map will contain an entry for the
- * current package and everything it depends on (extracted via `pub
- * list-package-dirs`).
- */
-Map<String, String> _readPackageDirsFromPub(String currentPackage) {
+/// Extract a mapping between package names and the path in the file system
+/// which has the source of the package. This map will contain an entry for the
+/// current package and everything it depends on (extracted via `pub
+/// list-package-dirs`).
+Map<String, String> readPackageDirsFromPub(
+    [String packageHome, String currentPackage]) {
+  var cachedDir = Directory.current;
+  if (packageHome != null) {
+    Directory.current = new Directory(packageHome);
+  } else {
+    packageHome = cachedDir.path;
+  }
+
   var dartExec = Platform.executable;
   // If dartExec == dart, then dart and pub are in standard PATH.
   var sdkDir = dartExec == 'dart' ? '' : path.dirname(dartExec);
@@ -108,22 +111,18 @@
     exit(result.exitCode);
   }
   var map = JSON.decode(result.stdout)["packages"];
-  map.forEach((k, v) { map[k] = path.dirname(v); });
-  map[currentPackage] = '.';
+  map.forEach((k, v) { map[k] = path.absolute(packageHome, path.dirname(v)); });
+
+  if (currentPackage == null) {
+    currentPackage = readCurrentPackageFromPubspec(packageHome);
+  }
+  map[currentPackage] = packageHome;
+
+  Directory.current = cachedDir;
   return map;
 }
 
-/** Internal packages used by polymer. */
-// TODO(sigmund): consider computing this list by recursively parsing
-// pubspec.yaml files in the `Options.packageDirs`.
-final Set<String> _polymerPackageDependencies = [
-    'analyzer', 'args', 'barback', 'browser', 'html5lib',
-    'js', 'logging', 'mutation_observer', 'observe', 'path'
-    'polymer_expressions', 'serialization', 'source_maps',
-    'stack_trace', 'template_binding', 'unittest', 'web_components',
-    'yaml'].toSet();
-
-/** Return the relative path of each file under [subDir] in [package]. */
+/// Return the relative path of each file under [subDir] in [package].
 Iterable<String> _listPackageDir(String package, String subDir,
     BarbackOptions options) {
   var packageDir = options.packageDirs[package];
@@ -135,25 +134,25 @@
       .map((f) => path.relative(f.path, from: packageDir));
 }
 
-/** A simple provider that reads files directly from the pub cache. */
-class _PolymerPackageProvider implements PackageProvider {
+/// A simple provider that reads files directly from the pub cache.
+class _PackageProvider implements PackageProvider {
   Map<String, String> packageDirs;
   Iterable<String> get packages => packageDirs.keys;
 
-  _PolymerPackageProvider(this.packageDirs);
+  _PackageProvider(this.packageDirs);
 
   Future<Asset> getAsset(AssetId id) => new Future.value(
       new Asset.fromPath(id, path.join(packageDirs[id.package],
       _toSystemPath(id.path))));
 }
 
-/** Convert asset paths to system paths (Assets always use the posix style). */
+/// Convert asset paths to system paths (Assets always use the posix style).
 String _toSystemPath(String assetPath) {
   if (path.Style.platform != path.Style.windows) return assetPath;
   return path.joinAll(path.posix.split(assetPath));
 }
 
-/** Tell barback which transformers to use and which assets to process. */
+/// Tell barback which transformers to use and which assets to process.
 void _initBarback(Barback barback, BarbackOptions options) {
   var assets = [];
   void addAssets(String package, String subDir) {
@@ -163,26 +162,26 @@
   }
 
   for (var package in options.packageDirs.keys) {
-    // There is nothing to do in the polymer package dependencies.
-    // However: in Polymer package *itself*, we need to replace Observable
-    // with ChangeNotifier.
-    if (!options.transformPolymerDependencies &&
-        _polymerPackageDependencies.contains(package)) continue;
-    barback.updateTransformers(package, options.phases);
-
     // Notify barback to process anything under 'lib' and 'asset'.
     addAssets(package, 'lib');
     addAssets(package, 'asset');
+
+    if (options.packagePhases.containsKey(package)) {
+      barback.updateTransformers(package, options.packagePhases[package]);
+    }
   }
+  barback.updateTransformers(options.currentPackage, options.phases);
 
   // In case of the current package, include also 'web'.
   addAssets(options.currentPackage, 'web');
   if (options.transformTests) addAssets(options.currentPackage, 'test');
 
+  // Add the sources after the transformers so all transformers are present
+  // when barback starts processing the assets.
   barback.updateSources(assets);
 }
 
-/** Attach error listeners on [barback] so we can report errors. */
+/// Attach error listeners on [barback] so we can report errors.
 void _attachListeners(Barback barback, BarbackOptions options) {
   // Listen for errors and results
   barback.errors.listen((e) {
@@ -211,10 +210,8 @@
   });
 }
 
-/**
- * Emits all outputs of [barback] and copies files that we didn't process (like
- * polymer's libraries).
- */
+/// Emits all outputs of [barback] and copies files that we didn't process (like
+/// dependent package's libraries).
 Future _emitAllFiles(Barback barback, BarbackOptions options) {
   return barback.getAllAssets().then((assets) {
     // Delete existing output folder before we generate anything
@@ -257,11 +254,9 @@
   });
 }
 
-/**
- * Adds a package symlink from each directory under `out/web/foo/` to
- * `out/packages`.
- */
-Future _addPackagesSymlinks(AssetSet assets, BarbackOptions options) {
+/// Adds a package symlink from each directory under `out/web/foo/` to
+/// `out/packages`.
+void _addPackagesSymlinks(AssetSet assets, BarbackOptions options) {
   var outPackages = path.join(options.outDir, 'packages');
   var currentPackage = options.currentPackage;
   for (var asset in assets) {
@@ -284,19 +279,16 @@
   }
 }
 
-/**
- * Emits a 'packages' directory directly under `out/packages` with the contents
- * of every file that was not transformed by barback.
- */
+/// Emits a 'packages' directory directly under `out/packages` with the contents
+/// of every file that was not transformed by barback.
 Future _emitPackagesDir(BarbackOptions options) {
-  if (options.transformPolymerDependencies) return new Future.value(null);
   var outPackages = path.join(options.outDir, 'packages');
   _ensureDir(outPackages);
 
   // Copy all the files we didn't process
   var dirs = options.packageDirs;
 
-  return Future.forEach(_polymerPackageDependencies, (package) {
+  return Future.forEach(dirs.keys, (package) {
     return Future.forEach(_listPackageDir(package, 'lib', options), (relpath) {
       var inpath = path.join(dirs[package], relpath);
       var outpath = path.join(outPackages, package, relpath.substring(4));
@@ -305,28 +297,26 @@
   });
 }
 
-/** Ensure [dirpath] exists. */
+/// Ensure [dirpath] exists.
 void _ensureDir(String dirpath) {
   new Directory(dirpath).createSync(recursive: true);
 }
 
-/**
- * Returns the first directory name on a url-style path, or null if there are no
- * slashes.
- */
+/// Returns the first directory name on a url-style path, or null if there are
+/// no slashes.
 String _firstDir(String url) {
   var firstSlash = url.indexOf('/');
   if (firstSlash == -1) return null;
   return url.substring(0, firstSlash);
 }
 
-/** Copy a file from [inpath] to [outpath]. */
+/// Copy a file from [inpath] to [outpath].
 Future _copyFile(String inpath, String outpath) {
   _ensureDir(path.dirname(outpath));
   return new File(inpath).openRead().pipe(new File(outpath).openWrite());
 }
 
-/** Write contents of an [asset] into a file at [filepath]. */
+/// Write contents of an [asset] into a file at [filepath].
 Future _writeAsset(String filepath, Asset asset) {
   _ensureDir(path.dirname(filepath));
   return asset.read().pipe(new File(filepath).openWrite());
@@ -338,10 +328,8 @@
       : (level == LogLevel.WARNING ? 'warning' : 'info');
 }
 
-/**
- * Formatter that generates messages using a format that can be parsed
- * by tools, such as the Dart Editor, for reporting error messages.
- */
+/// Formatter that generates messages using a format that can be parsed
+/// by tools, such as the Dart Editor, for reporting error messages.
 String _jsonFormatter(LogEntry entry) {
   var kind = _kindFromEntry(entry);
   var span = entry.span;
@@ -357,10 +345,8 @@
           }}]);
 }
 
-/**
- * Formatter that generates messages that are easy to read on the console (used
- * by default).
- */
+/// Formatter that generates messages that are easy to read on the console (used
+/// by default).
 String _consoleFormatter(LogEntry entry) {
   var kind = _kindFromEntry(entry);
   var useColors = stdioType(stdout) == StdioType.TERMINAL;
diff --git a/pkg/polymer/lib/src/build/script_compactor.dart b/pkg/polymer/lib/src/build/script_compactor.dart
index 335fcb0..9dd07e2 100644
--- a/pkg/polymer/lib/src/build/script_compactor.dart
+++ b/pkg/polymer/lib/src/build/script_compactor.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.
 
-/** Transfomer that combines multiple dart script tags into a single one. */
+/// Transfomer that combines multiple dart script tags into a single one.
 library polymer.src.build.script_compactor;
 
 import 'dart:async';
@@ -13,31 +13,28 @@
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:barback/barback.dart';
-import 'package:html5lib/parser.dart' show parseFragment;
 import 'package:path/path.dart' as path;
 import 'package:source_maps/span.dart' show SourceFile;
 
 import 'code_extractor.dart'; // import just for documentation.
 import 'common.dart';
 
-/**
- * Combines Dart script tags into a single script tag, and creates a new Dart
- * file that calls the main function of each of the original script tags.
- *
- * This transformer assumes that all script tags point to external files. To
- * support script tags with inlined code, use this transformer after running
- * [InlineCodeExtractor] on an earlier phase.
- *
- * Internally, this transformer will convert each script tag into an import
- * statement to a library, and then uses `initPolymer` (see polymer.dart)  to
- * process `@initMethod` and `@CustomTag` annotations in those libraries.
- */
+/// Combines Dart script tags into a single script tag, and creates a new Dart
+/// file that calls the main function of each of the original script tags.
+///
+/// This transformer assumes that all script tags point to external files. To
+/// support script tags with inlined code, use this transformer after running
+/// [InlineCodeExtractor] on an earlier phase.
+///
+/// Internally, this transformer will convert each script tag into an import
+/// statement to a library, and then uses `initPolymer` (see polymer.dart)  to
+/// process `@initMethod` and `@CustomTag` annotations in those libraries.
 class ScriptCompactor extends Transformer with PolymerTransformer {
   final TransformOptions options;
 
   ScriptCompactor(this.options);
 
-  /** Only run on entry point .html files. */
+  /// Only run on entry point .html files.
   Future<bool> isPrimary(Asset input) =>
       new Future.value(options.isHtmlEntryPoint(input.id));
 
@@ -53,7 +50,7 @@
         var mainScriptTag;
         bool changed = false;
 
-        for (var tag in document.queryAll('script')) {
+        for (var tag in document.querySelectorAll('script')) {
           var src = tag.attributes['src'];
           if (src == 'packages/polymer/boot.js') {
             tag.remove();
@@ -124,11 +121,9 @@
     });
   }
 
-  /**
-   * Computes the initializers of [dartLibrary]. That is, a closure that calls
-   * Polymer.register for each @CustomTag, and any public top-level methods
-   * labeled with @initMethod.
-   */
+  /// Computes the initializers of [dartLibrary]. That is, a closure that calls
+  /// Polymer.register for each @CustomTag, and any public top-level methods
+  /// labeled with @initMethod.
   Future<List<_Initializer>> _initializersOf(
       AssetId dartLibrary, Transform transform, TransformLogger logger) {
     var initializers = [];
@@ -172,10 +167,8 @@
       source.path.startsWith('lib/')
       ? 'package:${source.package}/${source.path.substring(4)}' : source.path;
 
-  /**
-   * Filter [exportedInitializers] according to [directive]'s show/hide
-   * combinators and add the result to [initializers].
-   */
+  /// Filter [exportedInitializers] according to [directive]'s show/hide
+  /// combinators and add the result to [initializers].
   // TODO(sigmund): call the analyzer's resolver instead?
   static _processExportDirective(ExportDirective directive,
       List<_Initializer> exportedInitializers,
@@ -192,10 +185,8 @@
     initializers.addAll(exportedInitializers);
   }
 
-  /**
-   * Add an initializer to register [node] as a polymer element if it contains
-   * an appropriate [CustomTag] annotation.
-   */
+  /// Add an initializer to register [node] as a polymer element if it contains
+  /// an appropriate [CustomTag] annotation.
   static _processClassDeclaration(ClassDeclaration node,
       List<_Initializer> initializers, SourceFile file,
       TransformLogger logger) {
@@ -219,7 +210,7 @@
     }
   }
 
-  /**  a method initializer for [function]. */
+  /// Add a method initializer for [function].
   static _processFunctionDeclaration(FunctionDeclaration function,
       List<_Initializer> initializers, SourceFile file,
       TransformLogger logger) {
@@ -233,7 +224,7 @@
   }
 }
 
-/** Parse [code] using analyzer. */
+/// Parse [code] using analyzer.
 CompilationUnit _parseCompilationUnit(String code) {
   var errorListener = new _ErrorCollector();
   var reader = new CharSequenceReader(code);
diff --git a/pkg/polymer/lib/src/build/utils.dart b/pkg/polymer/lib/src/build/utils.dart
index 59fdc73..b031373 100644
--- a/pkg/polymer/lib/src/build/utils.dart
+++ b/pkg/polymer/lib/src/build/utils.dart
@@ -4,11 +4,9 @@
 
 library polymer.src.utils;
 
-/**
- * Converts a string name with hyphens into an identifier, by removing hyphens
- * and capitalizing the following letter. Optionally [startUppercase] to
- * captialize the first letter.
- */
+/// Converts a string name with hyphens into an identifier, by removing hyphens
+/// and capitalizing the following letter. Optionally [startUppercase] to
+/// captialize the first letter.
 String toCamelCase(String hyphenedName, {bool startUppercase: false}) {
   var segments = hyphenedName.split('-');
   int start = startUppercase ? 0 : 1;
@@ -22,7 +20,7 @@
   return segments.join('');
 }
 
-/** Reverse of [toCamelCase]. */
+/// Reverse of [toCamelCase].
 String toHyphenedName(String word) {
   var sb = new StringBuffer();
   for (int i = 0; i < word.length; i++) {
diff --git a/pkg/polymer/lib/src/declaration.dart b/pkg/polymer/lib/src/declaration.dart
index 9201767..362a690 100644
--- a/pkg/polymer/lib/src/declaration.dart
+++ b/pkg/polymer/lib/src/declaration.dart
@@ -4,13 +4,11 @@
 
 part of polymer;
 
-/**
- * **Warning**: this class is experiental and subject to change.
- *
- * The implementation for the `polymer-element` element.
- *
- * Normally you do not need to use this class directly, see [PolymerElement].
- */
+/// **Warning**: this class is experiental and subject to change.
+///
+/// The implementation for the `polymer-element` element.
+///
+/// Normally you do not need to use this class directly, see [PolymerElement].
 class PolymerDeclaration extends HtmlElement {
   static const _TAG = 'polymer-element';
 
@@ -46,22 +44,20 @@
   String _name;
   String get name => _name;
 
-  /**
-   * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror]
-   * representing a getter. If it is a getter, there will also be a setter.
-   *
-   * Note: technically these are always single properties, so we could use
-   * a Symbol instead of a PropertyPath. However there are lookups between
-   * this map and [_observe] so it is easier to just track paths.
-   */
-  Map<PropertyPath, DeclarationMirror> _publish;
+  /// Map of publish properties. Can be a field or a property getter, but if
+  /// this map contains a getter, is because it also has a corresponding setter.
+  ///
+  /// Note: technically these are always single properties, so we could use a
+  /// Symbol instead of a PropertyPath. However there are lookups between this
+  /// map and [_observe] so it is easier to just track paths.
+  Map<PropertyPath, smoke.Declaration> _publish;
 
-  /** The names of published properties for this polymer-element. */
+  /// The names of published properties for this polymer-element.
   Iterable<String> get publishedProperties =>
       _publish != null ? _publish.keys.map((p) => '$p') : const [];
 
-  /** Same as [_publish] but with lower case names. */
-  Map<String, DeclarationMirror> _publishLC;
+  /// Same as [_publish] but with lower case names.
+  Map<String, smoke.Declaration> _publishLC;
 
   Map<PropertyPath, List<Symbol>> _observe;
 
@@ -78,10 +74,10 @@
     return template != null ? templateBind(template).content : null;
   }
 
-  /** Maps event names and their associated method in the element class. */
+  /// Maps event names and their associated method in the element class.
   final Map<String, String> _eventDelegates = {};
 
-  /** Expected events per element node. */
+  /// Expected events per element node.
   // TODO(sigmund): investigate whether we need more than 1 set of local events
   // per element (why does the js implementation stores 1 per template node?)
   Expando<Set<String>> _templateDelegates;
@@ -174,13 +170,11 @@
     // publishConstructor();
   }
 
-  /**
-   * Gets the Dart type registered for this name, and sets up declarative
-   * features. Fills in the [type] and [supertype] fields.
-   *
-   * *Note*: unlike the JavaScript version, we do not have to metaprogram the
-   * prototype, which simplifies this method.
-   */
+  /// Gets the Dart type registered for this name, and sets up declarative
+  /// features. Fills in the [type] and [supertype] fields.
+  ///
+  /// *Note*: unlike the JavaScript version, we do not have to metaprogram the
+  /// prototype, which simplifies this method.
   void buildType(String name, String extendee) {
     // get our custom type
     _type = _getRegisteredType(name);
@@ -189,17 +183,15 @@
     _supertype = _getRegisteredType(extendee);
     if (_supertype != null) _super = _getDeclaration(extendee);
 
-    var cls = reflectClass(_type);
-
     // transcribe `attributes` declarations onto own prototype's `publish`
-    publishAttributes(cls, _super);
+    publishAttributes(_super);
 
-    publishProperties(_type);
+    publishProperties();
 
-    inferObservers(cls);
+    inferObservers();
 
     // desugar compound observer syntax, e.g. @ObserveProperty('a b c')
-    explodeObservers(cls);
+    explodeObservers();
 
     // Skip the rest in Dart:
     // chain various meta-data objects to inherited versions
@@ -209,7 +201,7 @@
     // x-platform fixup
   }
 
-  /** Implement various declarative features. */
+  /// Implement various declarative features.
   void desugar(name, extendee) {
     // compile list of attributes to copy to instances
     accumulateInstanceAttributes();
@@ -230,15 +222,10 @@
     // under ShadowDOMPolyfill, transforms to approximate missing CSS features
     _shimShadowDomStyling(templateContent, name, extendee);
 
-    var cls = reflectClass(type);
     // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
     // lazy static initialization, can we get by without it?
-    var registered = cls.declarations[#registerCallback];
-    if (registered != null &&
-        registered is MethodMirror &&
-        registered.isStatic &&
-        registered.isRegularMethod) {
-      cls.invoke(#registerCallback, [this]);
+    if (smoke.hasStaticMethod(type, #registerCallback)) {
+      smoke.invoke(type, #registerCallback, [this]);
     }
   }
 
@@ -268,7 +255,7 @@
     document.register(name, type, extendsTag: baseTag);
   }
 
-  void publishAttributes(ClassMirror cls, PolymerDeclaration superDecl) {
+  void publishAttributes(PolymerDeclaration superDecl) {
     // get properties to publish
     if (superDecl != null && superDecl._publish != null) {
       // Dart note: even though we walk the type hierarchy in
@@ -277,7 +264,7 @@
       _publish = new Map.from(superDecl._publish);
     }
 
-    _publish = _getPublishedProperties(cls, _publish);
+    _publish = _getPublishedProperties(_type, _publish);
 
     // merge names from 'attributes' attribute
     var attrs = attributes['attributes'];
@@ -297,14 +284,14 @@
           continue;
         }
 
-        var mirror = _getProperty(cls, property);
-        if (mirror == null) {
+        var decl = smoke.getDeclaration(_type, property);
+        if (decl == null || decl.isMethod || decl.isFinal) {
           window.console.warn('property for attribute $attr of polymer-element '
               'name=$name not found.');
           continue;
         }
         if (_publish == null) _publish = {};
-        _publish[path] = mirror;
+        _publish[path] = decl;
       }
     }
 
@@ -335,7 +322,7 @@
     return !blackList.containsKey(name) && !name.startsWith('on-');
   }
 
-  /** Extracts events from the element tag attributes. */
+  /// Extracts events from the element tag attributes.
   void parseHostEvents() {
     addAttributeDelegates(_eventDelegates);
   }
@@ -358,10 +345,8 @@
     return (url.split('/')..removeLast()..add('')).join('/');
   }
 
-  /**
-   * Install external stylesheets loaded in <element> elements into the
-   * element's template.
-   */
+  /// Install external stylesheets loaded in <element> elements into the
+  /// element's template.
   void installSheets() {
     cacheSheets();
     cacheStyles();
@@ -379,14 +364,12 @@
     for (var s in styles) s.remove();
   }
 
-  /**
-   * Takes external stylesheets loaded in an `<element>` element and moves
-   * their content into a style element inside the `<element>`'s template.
-   * The sheet is then removed from the `<element>`. This is done only so
-   * that if the element is loaded in the main document, the sheet does
-   * not become active.
-   * Note, ignores sheets with the attribute 'polymer-scope'.
-   */
+  /// Takes external stylesheets loaded in an `<element>` element and moves
+  /// their content into a style element inside the `<element>`'s template.
+  /// The sheet is then removed from the `<element>`. This is done only so
+  /// that if the element is loaded in the main document, the sheet does
+  /// not become active.
+  /// Note, ignores sheets with the attribute 'polymer-scope'.
   void installLocalSheets() {
     var sheets = this.sheets.where(
         (s) => !s.attributes.containsKey(_SCOPE_ATTR));
@@ -414,13 +397,11 @@
     return nodes;
   }
 
-  /**
-   * Promotes external stylesheets and style elements with the attribute
-   * polymer-scope='global' into global scope.
-   * This is particularly useful for defining @keyframe rules which
-   * currently do not function in scoped or shadow style elements.
-   * (See wkb.ug/72462)
-   */
+  /// Promotes external stylesheets and style elements with the attribute
+  /// polymer-scope='global' into global scope.
+  /// This is particularly useful for defining @keyframe rules which
+  /// currently do not function in scoped or shadow style elements.
+  /// (See wkb.ug/72462)
   // TODO(sorvell): remove when wkb.ug/72462 is addressed.
   void installGlobalStyles() {
     var style = styleForScope(_STYLE_GLOBAL_SCOPE);
@@ -456,54 +437,42 @@
         ..attributes[_STYLE_SCOPE_ATTRIBUTE] = '$name-$scopeDescriptor';
   }
 
-  /**
-   * Fetch a list of all *Changed methods so we can observe the associated
-   * properties.
-   */
-  void inferObservers(ClassMirror cls) {
-    if (cls == _htmlElementType) return;
-    inferObservers(cls.superclass);
-    for (var method in cls.declarations.values) {
-      if (method is! MethodMirror || method.isStatic
-          || !method.isRegularMethod) continue;
-
-      String name = MirrorSystem.getName(method.simpleName);
+  /// Fetch a list of all *Changed methods so we can observe the associated
+  /// properties.
+  void inferObservers() {
+    var options = const smoke.QueryOptions(includeFields: false,
+        includeProperties: false, includeMethods: true, includeInherited: true,
+        includeUpTo: HtmlElement);
+    for (var decl in smoke.query(_type, options)) {
+      String name = smoke.symbolToName(decl.name);
       if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') {
         // TODO(jmesserly): now that we have a better system, should we
         // deprecate *Changed methods?
         if (_observe == null) _observe = new HashMap();
         name = name.substring(0, name.length - 7);
-        _observe[new PropertyPath(name)] = [method.simpleName];
+        _observe[new PropertyPath(name)] = [decl.name];
       }
     }
   }
 
-  /**
-   * Fetch a list of all methods annotated with [ObserveProperty] so we can
-   * observe the associated properties.
-   */
-  void explodeObservers(ClassMirror cls) {
-    if (cls == _htmlElementType) return;
-
-    explodeObservers(cls.superclass);
-    for (var method in cls.declarations.values) {
-      if (method is! MethodMirror || method.isStatic
-          || !method.isRegularMethod) continue;
-
-      for (var meta in _safeGetMetadata(method)) {
-        if (meta.reflectee is! ObserveProperty) continue;
-
+  /// Fetch a list of all methods annotated with [ObserveProperty] so we can
+  /// observe the associated properties.
+  void explodeObservers() {
+    var options = const smoke.QueryOptions(includeFields: false,
+        includeProperties: false, includeMethods: true, includeInherited: true,
+        includeUpTo: HtmlElement, withAnnotations: const [ObserveProperty]);
+    for (var decl in smoke.query(_type, options)) {
+      for (var meta in decl.annotations) {
+        if (meta is! ObserveProperty) continue;
         if (_observe == null) _observe = new HashMap();
-
-        for (String name in meta.reflectee.names) {
-          _observe.putIfAbsent(new PropertyPath(name), () => [])
-              .add(method.simpleName);
+        for (String name in meta.names) {
+          _observe.putIfAbsent(new PropertyPath(name), () => []).add(decl.name);
         }
       }
     }
   }
 
-  void publishProperties(Type type) {
+  void publishProperties() {
     // Dart note: _publish was already populated by publishAttributes
     if (_publish != null) _publishLC = _lowerCaseMap(_publish);
   }
@@ -548,88 +517,27 @@
 bool _isRegistered(String name) => _declarations.containsKey(name);
 PolymerDeclaration _getDeclaration(String name) => _declarations[name];
 
-final _objectType = reflectClass(Object);
-final _htmlElementType = reflectClass(HtmlElement);
-
-Map _getPublishedProperties(ClassMirror cls, Map props) {
-  if (cls == _htmlElementType) return props;
-  props = _getPublishedProperties(cls.superclass, props);
-  for (var member in cls.declarations.values) {
-    if (member.isStatic || member.isPrivate) continue;
-
-    if (member is VariableMirror && !member.isFinal
-        || member is MethodMirror && member.isGetter) {
-
-      for (var meta in member.metadata) {
-        if (meta.reflectee is PublishedProperty) {
-          // Note: we delay the setter check until we find @published because
-          // it's a tad expensive.
-          if (member is! MethodMirror || _hasSetter(cls, member)) {
-            if (props == null) props = {};
-            props[new PropertyPath([member.simpleName])] = member;
-          }
-          break;
-        }
-      }
-    }
+Map<PropertyPath, smoke.Declaration> _getPublishedProperties(
+    Type type, Map<PropertyPath, smoke.Declaration> props) {
+  var options = const smoke.QueryOptions(includeInherited: true,
+      includeUpTo: HtmlElement, withAnnotations: const [PublishedProperty]);
+  for (var decl in smoke.query(type, options)) {
+    if (decl.isFinal) continue;
+    if (props == null) props = {};
+    props[new PropertyPath([decl.name])] = decl;
   }
-
   return props;
 }
 
-DeclarationMirror _getProperty(ClassMirror cls, Symbol property) {
-  do {
-    var mirror = cls.declarations[property];
-    if (mirror is MethodMirror && mirror.isGetter && _hasSetter(cls, mirror)
-        || mirror is VariableMirror) {
-      return mirror;
-    }
-    cls = cls.superclass;
-
-    // It's generally a good idea to stop at Object, since we know it doesn't
-    // have what we want.
-    // TODO(jmesserly): This is also a workaround for what appears to be a V8
-    // bug introduced between Chrome 31 and 32. After 32
-    // JsClassMirror.declarations on Object calls
-    // JsClassMirror.typeVariables, which tries to get the _jsConstructor's
-    // .prototype["<>"]. This ends up getting the "" property instead, maybe
-    // because "<>" doesn't exist, and gets ";" which then blows up because
-    // the code later on expects a List of ints.
-  } while (cls != _objectType);
-  return null;
-}
-
-List _safeGetMetadata(MethodMirror method) {
-  // TODO(jmesserly): dart2js blows up getting metadata from methods in some
-  // cases. Why does this happen? It seems like the culprit might be named
-  // arguments. Unfortunately even calling method.parameters also
-  // triggers the bug in computeFunctionRti. For now we guard against it
-  // with this check.
-  try {
-    return method.metadata;
-  } catch (e) {
-    return [];
-  }
-}
-
-bool _hasSetter(ClassMirror cls, MethodMirror getter) {
-  var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}=');
-  var mirror = cls.declarations[setterName];
-  return mirror is MethodMirror && mirror.isSetter;
-}
-
-
-/** Attribute prefix used for declarative event handlers. */
+/// Attribute prefix used for declarative event handlers.
 const _EVENT_PREFIX = 'on-';
 
-/** Whether an attribute declares an event. */
+/// Whether an attribute declares an event.
 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
 
 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
 
-/**
- * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
- */
+/// Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
 void _shimShadowDomStyling(DocumentFragment template, String name,
     String extendee) {
   if (template == null || !_hasShadowDomPolyfill) return;
@@ -654,33 +562,26 @@
 String _cssTextFromSheet(LinkElement sheet) {
   if (sheet == null) return '';
 
+  // In deploy mode we should never do a sync XHR; link rel=stylesheet will
+  // be inlined into a <style> tag by ImportInliner.
+  if (_deployMode) return '';
+
   // TODO(jmesserly): sometimes the href property is wrong after deployment.
   var href = sheet.href;
   if (href == '') href = sheet.attributes["href"];
 
-  // TODO(jmesserly): our build is not doing the right thing for
-  // link rel=stylesheet, see http://dartbug.com/16648
-  if (js.context != null && js.context.hasProperty('HTMLImports')) {
-    var jsSheet = new js.JsObject.fromBrowserObject(sheet);
-    var resource = jsSheet['__resource'];
-    if (resource != null) return resource;
-    // TODO(jmesserly): figure out why HTMLImports is failing to load these.
-    // Falling back to sync XHR is no good.
-    // _sheetLog.fine('failed to get stylesheet text href="$href"');
-    // return '';
-  }
   // TODO(jmesserly): it seems like polymer-js is always polyfilling
-  // HTMLImports, because their code depends on "__resource" to work.
-  // We work around this by using a sync XHR to get the stylesheet text.
-  // Right now this code is only used in Dartium, but if it's going to stick
-  // around we will need to find a different approach.
+  // HTMLImports, because their code depends on "__resource" to work, so I
+  // don't see how it can work with native HTML Imports. We use a sync-XHR
+  // under the assumption that the file is likely to have been already
+  // downloaded and cached by HTML Imports.
   try {
     return (new HttpRequest()
         ..open('GET', href, async: false)
         ..send())
         .responseText;
   } on DomException catch (e, t) {
-    _sheetLog.fine('failed to get stylesheet text href="$href" error: '
+    _sheetLog.fine('failed to XHR stylesheet text href="$href" error: '
         '$e, trace: $t');
     return '';
   }
diff --git a/pkg/polymer/lib/src/instance.dart b/pkg/polymer/lib/src/instance.dart
index abc2a0c..1bd0a25 100644
--- a/pkg/polymer/lib/src/instance.dart
+++ b/pkg/polymer/lib/src/instance.dart
@@ -4,35 +4,31 @@
 
 part of polymer;
 
-/**
- * Use this annotation to publish a field as an attribute. For example:
- *
- *     class MyPlaybackElement extends PolymerElement {
- *       // This will be available as an HTML attribute, for example:
- *       //     <my-playback volume="11">
- *       @published double volume;
- *     }
- */
+/// Use this annotation to publish a field as an attribute. For example:
+///
+///     class MyPlaybackElement extends PolymerElement {
+///       // This will be available as an HTML attribute, for example:
+///       //     <my-playback volume="11">
+///       @published double volume;
+///     }
 const published = const PublishedProperty();
 
-/** An annotation used to publish a field as an attribute. See [published]. */
+/// An annotation used to publish a field as an attribute. See [published].
 class PublishedProperty extends ObservableProperty {
   const PublishedProperty();
 }
 
-/**
- * Use this type to observe a property and have the method be called when it
- * changes. For example:
- *
- *     @ObserveProperty('foo.bar baz qux')
- *     validate() {
- *       // use this.foo.bar, this.baz, and this.qux in validation
- *       ...
- *     }
- *
- * Note that you can observe a property path, and more than a single property
- * can be specified in a space-delimited list or as a constant List.
- */
+/// Use this type to observe a property and have the method be called when it
+/// changes. For example:
+///
+///     @ObserveProperty('foo.bar baz qux')
+///     validate() {
+///       // use this.foo.bar, this.baz, and this.qux in validation
+///       ...
+///     }
+///
+/// Note that you can observe a property path, and more than a single property
+/// can be specified in a space-delimited list or as a constant List.
 class ObserveProperty {
   final _names;
 
@@ -51,13 +47,11 @@
   const ObserveProperty(this._names);
 }
 
-/**
- * The mixin class for Polymer elements. It provides convenience features on top
- * of the custom elements web standard.
- *
- * If this class is used as a mixin,
- * you must call `polymerCreated()` from the body of your constructor.
- */
+/// The mixin class for Polymer elements. It provides convenience features on
+/// top of the custom elements web standard.
+///
+/// If this class is used as a mixin,
+/// you must call `polymerCreated()` from the body of your constructor.
 abstract class Polymer implements Element, Observable, NodeBindExtension {
   // Fully ported from revision:
   // https://github.com/Polymer/polymer/blob/37eea00e13b9f86ab21c85a955585e8e4237e3d2
@@ -72,18 +66,16 @@
   //   src/instance/utils.js
 
   // TODO(jmesserly): should this really be public?
-  /** Regular expression that matches data-bindings. */
+  /// Regular expression that matches data-bindings.
   static final bindPattern = new RegExp(r'\{\{([^{}]*)}}');
 
-  /**
-   * Like [document.register] but for Polymer elements.
-   *
-   * Use the [name] to specify custom elment's tag name, for example:
-   * "fancy-button" if the tag is used as `<fancy-button>`.
-   *
-   * The [type] is the type to construct. If not supplied, it defaults to
-   * [PolymerElement].
-   */
+  /// Like [document.register] but for Polymer elements.
+  ///
+  /// Use the [name] to specify custom elment's tag name, for example:
+  /// "fancy-button" if the tag is used as `<fancy-button>`.
+  ///
+  /// The [type] is the type to construct. If not supplied, it defaults to
+  /// [PolymerElement].
   // NOTE: this is called "element" in src/declaration/polymer-element.js, and
   // exported as "Polymer".
   static void register(String name, [Type type]) {
@@ -103,15 +95,13 @@
 
   static final Completer _ready = new Completer();
 
-  /**
-   * Future indicating that the Polymer library has been loaded and is ready
-   * for use.
-   */
+  /// Future indicating that the Polymer library has been loaded and is ready
+  /// for use.
   static Future get onReady => _ready.future;
 
   PolymerDeclaration _declaration;
 
-  /** The most derived `<polymer-element>` declaration for this element. */
+  /// The most derived `<polymer-element>` declaration for this element.
   PolymerDeclaration get declaration => _declaration;
 
   Map<String, StreamSubscription> _observers;
@@ -129,12 +119,10 @@
 
   BindingDelegate syntax = _polymerSyntax;
 
-  /**
-   * Shadow roots created by [parseElement]. See [getShadowRoot].
-   */
+  /// Shadow roots created by [parseElement]. See [getShadowRoot].
   final _shadowRoots = new HashMap<String, ShadowRoot>();
 
-  /** Map of items in the shadow root(s) by their [Element.id]. */
+  /// Map of items in the shadow root(s) by their [Element.id].
   // TODO(jmesserly): various issues:
   // * wrap in UnmodifiableMapView?
   // * should we have an object that implements noSuchMethod?
@@ -146,23 +134,19 @@
   @reflectable final Map<String, Element> $ =
       new ObservableMap<String, Element>();
 
-  /**
-   * Gets the shadow root associated with the corresponding custom element.
-   *
-   * This is identical to [shadowRoot], unless there are multiple levels of
-   * inheritance and they each have their own shadow root. For example,
-   * this can happen if the base class and subclass both have `<template>` tags
-   * in their `<polymer-element>` tags.
-   */
+  /// Gets the shadow root associated with the corresponding custom element.
+  ///
+  /// This is identical to [shadowRoot], unless there are multiple levels of
+  /// inheritance and they each have their own shadow root. For example,
+  /// this can happen if the base class and subclass both have `<template>` tags
+  /// in their `<polymer-element>` tags.
   // TODO(jmesserly): Polymer does not have this feature. Reconcile.
   ShadowRoot getShadowRoot(String customTagName) => _shadowRoots[customTagName];
 
-  /**
-   * If this class is used as a mixin, this method must be called from inside
-   * of the `created()` constructor.
-   *
-   * If this class is a superclass, calling `super.created()` is sufficient.
-   */
+  /// If this class is used as a mixin, this method must be called from inside
+  /// of the `created()` constructor.
+  ///
+  /// If this class is a superclass, calling `super.created()` is sufficient.
   void polymerCreated() {
     if (this.ownerDocument.window != null || alwaysPrepare ||
         _preparingElements > 0) {
@@ -170,7 +154,7 @@
     }
   }
 
-  /** Retrieves the custom element name by inspecting the host node. */
+  /// Retrieves the custom element name by inspecting the host node.
   String get _customTagName {
     var isAttr = attributes['is'];
     return (isAttr == null || isAttr == '') ? localName : isAttr;
@@ -198,7 +182,7 @@
     ready();
   }
 
-  /** Called when [prepareElement] is finished. */
+  /// Called when [prepareElement] is finished.
   void ready() {}
 
   void enteredView() {
@@ -212,7 +196,7 @@
     if (!preventDispose) asyncUnbindAll();
   }
 
-  /** Recursive ancestral <element> initialization, oldest first. */
+  /// Recursive ancestral <element> initialization, oldest first.
   void parseDeclarations(PolymerDeclaration declaration) {
     if (declaration != null) {
       parseDeclarations(declaration.superDeclaration);
@@ -220,9 +204,7 @@
     }
   }
 
-  /**
-   * Parse input `<polymer-element>` as needed, override for custom behavior.
-   */
+  /// Parse input `<polymer-element>` as needed, override for custom behavior.
   void parseDeclaration(Element elementElement) {
     var template = fetchTemplate(elementElement);
 
@@ -243,15 +225,11 @@
     _shadowRoots[name] = root;
   }
 
-  /**
-   * Return a shadow-root template (if desired), override for custom behavior.
-   */
+  /// Return a shadow-root template (if desired), override for custom behavior.
   Element fetchTemplate(Element elementElement) =>
       elementElement.querySelector('template');
 
-  /**
-   * Utility function that stamps a `<template>` into light-dom.
-   */
+  /// Utility function that stamps a `<template>` into light-dom.
   Node lightFromTemplate(Element template) {
     if (template == null) return null;
     // stamp template
@@ -267,19 +245,16 @@
     return dom;
   }
 
-  /**
-   * Utility function that creates a shadow root from a `<template>`.
-   *
-   * The base implementation will return a [ShadowRoot], but you can replace it
-   * with your own code and skip ShadowRoot creation. In that case, you should
-   * return `null`.
-   *
-   * In your overridden method, you can use [instanceTemplate] to stamp the
-   * template and initialize data binding, and [shadowRootReady] to intialize
-   * other Polymer features like event handlers. It is fine to call
-   * shadowRootReady with a node something other than a ShadowRoot; for example,
-   * with this Node.
-   */
+  /// Utility function that creates a shadow root from a `<template>`.
+  ///
+  /// The base implementation will return a [ShadowRoot], but you can replace it
+  /// with your own code and skip ShadowRoot creation. In that case, you should
+  /// return `null`.
+  ///
+  /// In your overridden method, you can use [instanceTemplate] to stamp the
+  /// template and initialize data binding, and [shadowRootReady] to intialize
+  /// other Polymer features like event handlers. It is fine to call
+  /// shadowRootReady with a node other than a ShadowRoot such as with `this`.
   ShadowRoot shadowFromTemplate(Element template) {
     if (template == null) return null;
     // cache elder shadow root (if any)
@@ -315,10 +290,10 @@
     // PointerGestures.register(root);
   }
 
-  /** Locate nodes with id and store references to them in [$] hash. */
+  /// Locate nodes with id and store references to them in [$] hash.
   void marshalNodeReferences(Node root) {
     if (root == null) return;
-    for (var n in (root as dynamic).queryAll('[id]')) {
+    for (var n in (root as dynamic).querySelectorAll('[id]')) {
       $[n.id] = n;
     }
   }
@@ -330,12 +305,10 @@
   }
 
   // TODO(jmesserly): this could be a top level method.
-  /**
-   * Returns a future when `node` changes, or when its children or subtree
-   * changes.
-   *
-   * Use [MutationObserver] if you want to listen to a stream of changes.
-   */
+  /// Returns a future when `node` changes, or when its children or subtree
+  /// changes.
+  ///
+  /// Use [MutationObserver] if you want to listen to a stream of changes.
   Future<List<MutationRecord>> onMutation(Node node) {
     var completer = new Completer();
     new MutationObserver((mutations, observer) {
@@ -356,52 +329,47 @@
     attributes.forEach(attributeToProperty);
   }
 
-  /**
-   * If attribute [name] is mapped to a property, deserialize
-   * [value] into that property.
-   */
+  /// If attribute [name] is mapped to a property, deserialize
+  /// [value] into that property.
   void attributeToProperty(String name, String value) {
     // try to match this attribute to a property (attributes are
     // all lower-case, so this is case-insensitive search)
-    var property = propertyForAttribute(name);
-    if (property == null) return;
+    var decl = propertyForAttribute(name);
+    if (decl == null) return;
 
     // filter out 'mustached' values, these are to be
     // replaced with bound-data and are not yet values
     // themselves.
     if (value == null || value.contains(Polymer.bindPattern)) return;
 
-    // get original value
-    final self = reflect(this);
-    final currentValue = self.getField(property.simpleName).reflectee;
+    final currentValue = smoke.read(this, decl.name);
 
     // deserialize Boolean or Number values from attribute
-    final newValue = deserializeValue(value, currentValue,
-        _inferPropertyType(currentValue, property));
+    var type = decl.type;
+    if ((type == Object || type == dynamic) && currentValue != null) {
+      // Attempt to infer field type from the current value.
+      type = currentValue.runtimeType;
+    }
+    final newValue = deserializeValue(value, currentValue, type);
 
     // only act if the value has changed
     if (!identical(newValue, currentValue)) {
       // install new value (has side-effects)
-      self.setField(property.simpleName, newValue);
+      smoke.write(this, decl.name, newValue);
     }
   }
 
-  /** Return the published property matching name, or null. */
+  /// Return the published property matching name, or null.
   // TODO(jmesserly): should we just return Symbol here?
-  DeclarationMirror propertyForAttribute(String name) {
+  smoke.Declaration propertyForAttribute(String name) {
     final publishLC = _declaration._publishLC;
     if (publishLC == null) return null;
     //console.log('propertyForAttribute:', name, 'matches', match);
     return publishLC[name];
   }
 
-  /**
-   * Convert representation of [value] based on [type] and [currentValue].
-   */
-  // TODO(jmesserly): this should probably take a ClassMirror instead of
-  // TypeMirror, but it is currently impossible to get from a TypeMirror to a
-  // ClassMirror.
-  Object deserializeValue(String value, Object currentValue, TypeMirror type) =>
+  /// Convert representation of [value] based on [type] and [currentValue].
+  Object deserializeValue(String value, Object currentValue, Type type) =>
       deserialize.deserializeValue(value, currentValue, type);
 
   String serializeValue(Object value) {
@@ -435,19 +403,17 @@
     }
   }
 
-  /**
-   * Creates the document fragment to use for each instance of the custom
-   * element, given the `<template>` node. By default this is equivalent to:
-   *
-   *     templateBind(template).createInstance(this, polymerSyntax);
-   *
-   * Where polymerSyntax is a singleton `PolymerExpressions` instance from the
-   * [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
-   * package.
-   *
-   * You can override this method to change the instantiation behavior of the
-   * template, for example to use a different data-binding syntax.
-   */
+  /// Creates the document fragment to use for each instance of the custom
+  /// element, given the `<template>` node. By default this is equivalent to:
+  ///
+  ///     templateBind(template).createInstance(this, polymerSyntax);
+  ///
+  /// Where polymerSyntax is a singleton `PolymerExpressions` instance from the
+  /// [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
+  /// package.
+  ///
+  /// You can override this method to change the instantiation behavior of the
+  /// template, for example to use a different data-binding syntax.
   DocumentFragment instanceTemplate(Element template) =>
       templateBind(template).createInstance(this, syntax);
 
@@ -458,15 +424,15 @@
     // property changes that occur as a result of binding will be observed.
     if (!_elementPrepared) prepareElement();
 
-    var property = propertyForAttribute(name);
-    if (property == null) {
+    var decl = propertyForAttribute(name);
+    if (decl == null) {
       // Cannot call super.bind because template_binding is its own package
       return nodeBindFallback(this).bind(name, bindable, oneTime: oneTime);
     } else {
       // clean out the closets
       unbind(name);
       // use n-way Polymer binding
-      var observer = bindProperty(property.simpleName, bindable);
+      var observer = bindProperty(decl.name, bindable);
 
       // reflect bound property to attribute when binding
       // to ensure binding is not left on attribute if property
@@ -476,7 +442,7 @@
 
       // TODO(jmesserly): polymer has the path_ in their observer object, should
       // we use that too instead of allocating it here?
-      reflectPropertyToAttribute(new PropertyPath([property.simpleName]));
+      reflectPropertyToAttribute(new PropertyPath([decl.name]));
       return bindings[name] = observer;
     }
   }
@@ -542,7 +508,7 @@
     }
   }
 
-  /** Set up property observers. */
+  /// Set up property observers.
   void observeProperties() {
     final observe = _declaration._observe;
     final publish = _declaration._publish;
@@ -574,7 +540,7 @@
   }
 
 
-  /** Responds to property changes on this element. */
+  /// Responds to property changes on this element.
   void notifyPropertyChanges(List newValues, Map oldValues, List paths) {
     final observe = _declaration._observe;
     final publish = _declaration._publish;
@@ -598,7 +564,8 @@
         // observes the value if it is an array
         observeArrayValue(path, newValue, oldValue);
         // Dart note: JS passes "arguments", so we pass along our args.
-        invokeMethod(method, [oldValue, newValue, newValues, oldValues, paths]);
+        smoke.invoke(this, method,
+            [oldValue, newValue, newValues, oldValues, paths], adjust: true);
       }
     });
   }
@@ -628,7 +595,7 @@
       }
       var sub = value.listChanges.listen((changes) {
         for (var callback in callbacks) {
-          invokeMethod(callback, [old]);
+          smoke.invoke(this, callback, [old], adjust: true);
         }
       });
       registerObserver('${name}__array', sub);
@@ -645,7 +612,7 @@
     unregisterObservers();
   }
 
-  /** Bookkeeping observers for memory management. */
+  /// Bookkeeping observers for memory management.
   void registerObserver(String name, StreamSubscription sub) {
     if (_observers == null) {
       _observers = new Map<String, StreamSubscription>();
@@ -667,17 +634,15 @@
     _observers = null;
   }
 
-  /**
-   * Bind a [property] in this object to a [path] in model. *Note* in Dart it
-   * is necessary to also define the field:
-   *
-   *     var myProperty;
-   *
-   *     ready() {
-   *       super.ready();
-   *       bindProperty(#myProperty, this, 'myModel.path.to.otherProp');
-   *     }
-   */
+  /// Bind a [property] in this object to a [path] in model. *Note* in Dart it
+  /// is necessary to also define the field:
+  ///
+  ///     var myProperty;
+  ///
+  ///     ready() {
+  ///       super.ready();
+  ///       bindProperty(#myProperty, this, 'myModel.path.to.otherProp');
+  ///     }
   Bindable bindProperty(Symbol name, Bindable bindable) {
     // Dart note: normally we only reach this code when we know it's a
     // property, but if someone uses bindProperty directly they might get a
@@ -703,7 +668,7 @@
     return new _PolymerBinding(this, name, bindable);
   }
 
-  /** Attach event listeners on the host (this) element. */
+  /// Attach event listeners on the host (this) element.
   void addHostListeners() {
     var events = _declaration._eventDelegates;
     if (events.isEmpty) return;
@@ -752,18 +717,23 @@
   String findEventDelegate(Event event) =>
       _declaration._eventDelegates[_eventNameFromType(event.type)];
 
-  /**
-   * Calls [methodOrCallback] with [args] if it is a closure, otherwise, treat
-   * it as a method name in [object], and invoke it.
-   */
+  /// Calls [methodOrCallback] with [args] if it is a closure, otherwise, treat
+  /// it as a method name in [object], and invoke it.
   void dispatchMethod(object, callbackOrMethod, List args) {
     bool log = _eventsLog.isLoggable(Level.FINE);
     if (log) _eventsLog.fine('>>> [$localName]: dispatch $callbackOrMethod');
 
     if (callbackOrMethod is Function) {
+      int maxArgs = smoke.maxArgs(callbackOrMethod);
+      if (maxArgs == -1) {
+        _eventsLog.warning(
+            'invalid callback: expected callback of 0, 1, 2, or 3 arguments');
+      }
+      args.length = maxArgs;
       Function.apply(callbackOrMethod, args);
     } else if (callbackOrMethod is String) {
-      _invokeMethod(object, new Symbol(callbackOrMethod), args);
+      smoke.invoke(object, smoke.nameToSymbol(callbackOrMethod), args,
+          adjust: true);
     } else {
       _eventsLog.warning('invalid callback');
     }
@@ -771,15 +741,13 @@
     if (log) _eventsLog.info('<<< [$localName]: dispatch $callbackOrMethod');
   }
 
-  /**
-   * Bind events via attributes of the form `on-eventName`. This method can be
-   * use to hooks into the model syntax and adds event listeners as needed. By
-   * default, binding paths are always method names on the root model, the
-   * custom element in which the node exists. Adding a '@' in the path directs
-   * the event binding to use the model path as the event listener.  In both
-   * cases, the actual listener is attached to a generic method which evaluates
-   * the bound path at event execution time.
-   */
+  /// Bind events via attributes of the form `on-eventName`. This method can be
+  /// use to hooks into the model syntax and adds event listeners as needed. By
+  /// default, binding paths are always method names on the root model, the
+  /// custom element in which the node exists. Adding a '@' in the path directs
+  /// the event binding to use the model path as the event listener.  In both
+  /// cases, the actual listener is attached to a generic method which evaluates
+  /// the bound path at event execution time.
   // from src/instance/event.js#prepareBinding
   static PrepareBindingFunction prepareBinding(String path, String name, node) {
 
@@ -797,41 +765,16 @@
     };
   }
 
-  /** Call [methodName] method on this object with [args]. */
+  /// Call [methodName] method on this object with [args].
   invokeMethod(Symbol methodName, List args) =>
-      _invokeMethod(this, methodName, args);
+      smoke.invoke(this, methodName, args, adjust: true);
 
-  /** Call [methodName] method on [receiver] with [args]. */
-  static _invokeMethod(receiver, Symbol methodName, List args) {
-    // TODO(jmesserly): use function type tests instead of mirrors for dispatch.
-    var receiverMirror = reflect(receiver);
-    var method = _findMethod(receiverMirror.type, methodName);
-    if (method != null) {
-      // This will either truncate the argument list or extend it with extra
-      // null arguments, so it will match the signature.
-      // TODO(sigmund): consider accepting optional arguments when we can tell
-      // them appart from named arguments (see http://dartbug.com/11334)
-      args.length = method.parameters.where((p) => !p.isOptional).length;
-    }
-    return receiverMirror.invoke(methodName, args).reflectee;
-  }
-
-  static MethodMirror _findMethod(ClassMirror type, Symbol name) {
-    do {
-      var member = type.declarations[name];
-      if (member is MethodMirror) return member;
-      type = type.superclass;
-    } while (type != null);
-  }
-
-  /**
-   * Invokes a function asynchronously.
-   * This will call `Platform.flush()` and then return a `new Timer`
-   * with the provided [method] and [timeout].
-   *
-   * If you would prefer to run the callback using
-   * [window.requestAnimationFrame], see the [async] method.
-   */
+  /// Invokes a function asynchronously.
+  /// This will call `Platform.flush()` and then return a `new Timer`
+  /// with the provided [method] and [timeout].
+  ///
+  /// If you would prefer to run the callback using
+  /// [window.requestAnimationFrame], see the [async] method.
   // Dart note: "async" is split into 2 methods so it can have a sensible type
   // signatures. Also removed the various features that don't make sense in a
   // Dart world, like binding to "this" and taking arguments list.
@@ -842,15 +785,13 @@
     return new Timer(timeout, method);
   }
 
-  /**
-   * Invokes a function asynchronously.
-   * This will call `Platform.flush()` and then call
-   * [window.requestAnimationFrame] with the provided [method] and return the
-   * result.
-   *
-   * If you would prefer to run the callback after a given duration, see
-   * the [asyncTimer] method.
-   */
+  /// Invokes a function asynchronously.
+  /// This will call `Platform.flush()` and then call
+  /// [window.requestAnimationFrame] with the provided [method] and return the
+  /// result.
+  ///
+  /// If you would prefer to run the callback after a given duration, see
+  /// the [asyncTimer] method.
   int async(RequestAnimationFrameCallback method) {
     // when polyfilling Object.observe, ensure changes
     // propagate before executing the async method
@@ -858,10 +799,8 @@
     return window.requestAnimationFrame(method);
   }
 
-  /**
-   * Fire a [CustomEvent] targeting [toNode], or this if toNode is not
-   * supplied. Returns the [detail] object.
-   */
+  /// Fire a [CustomEvent] targeting [toNode], or this if toNode is not
+  /// supplied. Returns the [detail] object.
   Object fire(String type, {Object detail, Node toNode, bool canBubble}) {
     var node = toNode != null ? toNode : this;
     //log.events && console.log('[%s]: sending [%s]', node.localName, inType);
@@ -873,9 +812,7 @@
     return detail;
   }
 
-  /**
-   * Fire an event asynchronously. See [async] and [fire].
-   */
+  /// Fire an event asynchronously. See [async] and [fire].
   asyncFire(String type, {Object detail, Node toNode, bool canBubble}) {
     // TODO(jmesserly): I'm not sure this method adds much in Dart, it's easy to
     // add "() =>"
@@ -883,9 +820,7 @@
         type, detail: detail, toNode: toNode, canBubble: canBubble));
   }
 
-  /**
-   * Remove [className] from [old], add class to [anew], if they exist.
-   */
+  /// Remove [className] from [old], add class to [anew], if they exist.
   void classFollows(Element anew, Element old, String className) {
     if (old != null) {
       old.classes.remove(className);
@@ -895,23 +830,21 @@
     }
   }
 
-  /**
-   * Installs external stylesheets and <style> elements with the attribute
-   * polymer-scope='controller' into the scope of element. This is intended
-   * to be a called during custom element construction. Note, this incurs a
-   * per instance cost and should be used sparingly.
-   *
-   * The need for this type of styling should go away when the shadowDOM spec
-   * addresses these issues:
-   *
-   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391
-   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390
-   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389
-   *
-   * @param element The custom element instance into whose controller (parent)
-   * scope styles will be installed.
-   * @param elementElement The <element> containing controller styles.
-   */
+  /// Installs external stylesheets and <style> elements with the attribute
+  /// polymer-scope='controller' into the scope of element. This is intended
+  /// to be a called during custom element construction. Note, this incurs a
+  /// per instance cost and should be used sparingly.
+  ///
+  /// The need for this type of styling should go away when the shadowDOM spec
+  /// addresses these issues:
+  ///
+  /// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391
+  /// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390
+  /// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389
+  ///
+  /// @param element The custom element instance into whose controller (parent)
+  /// scope styles will be installed.
+  /// @param elementElement The <element> containing controller styles.
   // TODO(sorvell): remove when spec issues are addressed
   void installControllerStyles() {
     var scope = findStyleController();
@@ -969,13 +902,11 @@
     scope.append(clone);
   }
 
-  /**
-   * Prevents flash of unstyled content
-   * This is the list of selectors for veiled elements
-   */
+  /// Prevents flash of unstyled content
+  /// This is the list of selectors for veiled elements
   static List<Element> veiledElements = ['body'];
 
-  /** Apply unveil class. */
+  /// Apply unveil class.
   static void unveilElements() {
     window.requestAnimationFrame((_) {
       var nodes = document.querySelectorAll('.$_VEILED_CLASS');
@@ -1001,28 +932,26 @@
 // TODO(jmesserly): our approach leads to race conditions in the bindings.
 // See http://code.google.com/p/dart/issues/detail?id=13567
 class _PolymerBinding extends Bindable {
-  final InstanceMirror _target;
+  final Polymer _target;
   final Symbol _property;
   final Bindable _bindable;
   StreamSubscription _sub;
   Object _lastValue;
 
-  _PolymerBinding(Polymer node, this._property, this._bindable)
-      : _target = reflect(node) {
-
-    _sub = node.changes.listen(_propertyValueChanged);
+  _PolymerBinding(this._target, this._property, this._bindable) {
+    _sub = _target.changes.listen(_propertyValueChanged);
     _updateNode(open(_updateNode));
   }
 
   void _updateNode(newValue) {
     _lastValue = newValue;
-    _target.setField(_property, newValue);
+    smoke.write(_target, _property, newValue);
   }
 
   void _propertyValueChanged(List<ChangeRecord> records) {
     for (var record in records) {
       if (record is PropertyChangeRecord && record.name == _property) {
-        final newValue = _target.getField(_property).reflectee;
+        final newValue = smoke.read(_target, _property);
         if (!identical(_lastValue, newValue)) {
           this.value = newValue;
         }
@@ -1046,35 +975,6 @@
 
 bool _toBoolean(value) => null != value && false != value;
 
-TypeMirror _propertyType(DeclarationMirror property) =>
-    property is VariableMirror ? property.type
-        : (property as MethodMirror).returnType;
-
-TypeMirror _inferPropertyType(Object value, DeclarationMirror property) {
-  var type = _propertyType(property);
-  if (type.qualifiedName == #dart.core.Object ||
-      type.qualifiedName == #dynamic) {
-    // Attempt to infer field type from the default value.
-    if (value != null) {
-      Type t = _getCoreType(value);
-      if (t != null) return reflectClass(t);
-      return reflect(value).type;
-    }
-  }
-  return type;
-}
-
-Type _getCoreType(Object value) {
-  if (value == null) return Null;
-  if (value is int) return int;
-  // Avoid "is double" to prevent warning that it won't work in dart2js.
-  if (value is num) return double;
-  if (value is bool) return bool;
-  if (value is String) return String;
-  if (value is DateTime) return DateTime;
-  return null;
-}
-
 final Logger _observeLog = new Logger('polymer.observe');
 final Logger _eventsLog = new Logger('polymer.events');
 final Logger _unbindLog = new Logger('polymer.unbind');
@@ -1084,11 +984,9 @@
 
 final Expando _eventHandledTable = new Expando<Set<Node>>();
 
-/**
- * Base class for PolymerElements deriving from HtmlElement.
- *
- * See [Polymer].
- */
+/// Base class for PolymerElements deriving from HtmlElement.
+///
+/// See [Polymer].
 class PolymerElement extends HtmlElement with Polymer, Observable {
   PolymerElement.created() : super.created() {
     polymerCreated();
@@ -1155,4 +1053,4 @@
       _sub = null;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/polymer/lib/src/job.dart b/pkg/polymer/lib/src/job.dart
index 5ba818f..e92d0c8 100644
--- a/pkg/polymer/lib/src/job.dart
+++ b/pkg/polymer/lib/src/job.dart
@@ -4,14 +4,12 @@
 
 part of polymer;
 
-/**
- * Invoke [callback] in [wait], unless the job is re-registered,
- * which resets the timer. For example:
- *
- *     _myJob = runJob(_myJob, callback, const Duration(milliseconds: 100));
- *
- * Returns a job handle which can be used to re-register a job.
- */
+/// Invoke [callback] in [wait], unless the job is re-registered,
+/// which resets the timer. For example:
+///
+///     _myJob = runJob(_myJob, callback, const Duration(milliseconds: 100));
+///
+/// Returns a job handle which can be used to re-register a job.
 // Dart note: renamed to runJob to avoid conflict with instance member "job".
 _Job _runJob(_Job job, void callback(), Duration wait) {
   if (job != null) {
diff --git a/pkg/polymer/lib/src/loader.dart b/pkg/polymer/lib/src/loader.dart
index 7a04ef1..e6f17f5 100644
--- a/pkg/polymer/lib/src/loader.dart
+++ b/pkg/polymer/lib/src/loader.dart
@@ -4,28 +4,24 @@
 
 part of polymer;
 
-/** Annotation used to automatically register polymer elements. */
+/// Annotation used to automatically register polymer elements.
 class CustomTag {
   final String tagName;
   const CustomTag(this.tagName);
 }
 
-/**
- * Metadata used to label static or top-level methods that are called
- * automatically when loading the library of a custom element.
- */
+/// Metadata used to label static or top-level methods that are called
+/// automatically when loading the library of a custom element.
 const initMethod = const _InitMethodAnnotation();
 
-/**
- * Initializes a polymer application as follows:
- *   * set up up polling for observable changes
- *   * initialize Model-Driven Views
- *   * Include some style to prevent flash of unstyled content (FOUC)
- *   * for each library included transitively from HTML and HTML imports,
- *   register custom elements declared there (labeled with [CustomTag]) and
- *   invoke the initialization method on it (top-level functions annotated with
- *   [initMethod]).
- */
+/// Initializes a polymer application as follows:
+///   * set up up polling for observable changes
+///   * initialize Model-Driven Views
+///   * Include some style to prevent flash of unstyled content (FOUC)
+///   * for each library included transitively from HTML and HTML imports,
+///   register custom elements declared there (labeled with [CustomTag]) and
+///   invoke the initialization method on it (top-level functions annotated with
+///   [initMethod]).
 Zone initPolymer() {
   // We use this pattern, and not the inline lazy initialization pattern, so we
   // can help dart2js detect that _discoverInitializers can be tree-shaken for
@@ -33,21 +29,23 @@
   // TODO(sigmund): fix polymer's transformers so they can replace initPolymer
   // by initPolymerOptimized.
   if (_initializers == null) _initializers = _discoverInitializers();
-  if (_useDirtyChecking) {
+
+  // In deployment mode, we rely on change notifiers instead of dirty checking.
+  if (!_deployMode) {
     return dirtyCheckZone()..run(initPolymerOptimized);
   }
 
   return initPolymerOptimized();
 }
 
-/**
- * Same as [initPolymer], but runs the version that is optimized for deployment
- * to the internet. The biggest difference is it omits the [Zone] that
- * automatically invokes [Observable.dirtyCheck], and the list of initializers
- * must be supplied instead of being dynamically searched for at runtime using
- * mirrors.
- */
+/// Same as [initPolymer], but runs the version that is optimized for deployment
+/// to the internet. The biggest difference is it omits the [Zone] that
+/// automatically invokes [Observable.dirtyCheck], and the list of initializers
+/// must be supplied instead of being dynamically searched for at runtime using
+/// mirrors.
 Zone initPolymerOptimized() {
+  // TODO(sigmund): refactor this so we can replace it by codegen.
+  smoke.useMirrors();
   // TODO(jmesserly): there is some code in src/declaration/polymer-element.js,
   // git version 37eea00e13b9f86ab21c85a955585e8e4237e3d2, right before
   // it registers polymer-element, which uses Platform.deliverDeclarations to
@@ -65,30 +63,26 @@
   return Zone.current;
 }
 
-/**
- * Configures [initPolymer] making it optimized for deployment to the internet.
- * With this setup the initializer list is supplied instead of being dynamically
- * searched for at runtime. Additionally, after this method is called,
- * [initPolymer] omits the [Zone] that automatically invokes
- * [Observable.dirtyCheck].
- */
+/// Configures [initPolymer] making it optimized for deployment to the internet.
+/// With this setup the initializer list is supplied instead of searched for
+/// at runtime. Additionally, after this method is called [initPolymer] omits
+/// the [Zone] that automatically invokes [Observable.dirtyCheck].
 void configureForDeployment(List<Function> initializers) {
   _initializers = initializers;
-  _useDirtyChecking = false;
+  _deployMode = true;
 }
 
-/**
- * List of initializers that by default will be executed when calling
- * initPolymer. If null, initPolymer will compute the list of initializers by
- * crawling HTML imports, searchfing for script tags, and including an
- * initializer for each type tagged with a [CustomTag] annotation and for each
- * top-level method annotated with [initMethod]. The value of this field is
- * assigned programatically by the code generated from the polymer deploy
- * scripts.
- */
+/// List of initializers that by default will be executed when calling
+/// initPolymer. If null, initPolymer will compute the list of initializers by
+/// crawling HTML imports, searchfing for script tags, and including an
+/// initializer for each type tagged with a [CustomTag] annotation and for each
+/// top-level method annotated with [initMethod]. The value of this field is
+/// assigned programatically by the code generated from the polymer deploy
+/// scripts.
 List<Function> _initializers;
 
-bool _useDirtyChecking = true;
+/// True if we're in deployment mode.
+bool _deployMode = false;
 
 List<Function> _discoverInitializers() {
   var initializers = [];
@@ -105,13 +99,11 @@
   return initializers;
 }
 
-/**
- * Walks the HTML import structure to discover all script tags that are
- * implicitly loaded. This code is only used in Dartium and should only be
- * called after all HTML imports are resolved. Polymer ensures this by asking
- * users to put their Dart script tags after all HTML imports (this is checked
- * by the linter, and Dartium will otherwise show an error message).
- */
+/// Walks the HTML import structure to discover all script tags that are
+/// implicitly loaded. This code is only used in Dartium and should only be
+/// called after all HTML imports are resolved. Polymer ensures this by asking
+/// users to put their Dart script tags after all HTML imports (this is checked
+/// by the linter, and Dartium will otherwise show an error message).
 List<String> _discoverScripts(Document doc, String baseUri,
     [Set<Document> seen, List<String> scripts]) {
   if (seen == null) seen = new Set<Document>();
@@ -124,7 +116,7 @@
   seen.add(doc);
 
   bool scriptSeen = false;
-  for (var node in doc.queryAll('script,link[rel="import"]')) {
+  for (var node in doc.querySelectorAll('script,link[rel="import"]')) {
     if (node is LinkElement) {
       _discoverScripts(node.import, node.href, seen, scripts);
     } else if (node is ScriptElement && node.type == 'application/dart') {
@@ -141,7 +133,7 @@
   return scripts;
 }
 
-/** All libraries in the current isolate. */
+/// All libraries in the current isolate.
 final _libs = currentMirrorSystem().libraries;
 
 // TODO(sigmund): explore other (cheaper) ways to resolve URIs relative to the
@@ -159,16 +151,14 @@
       (uriPath.contains('/packages/') || uriPath.startsWith('packages/'));
 }
 
-/**
- * Reads the library at [uriString] (which can be an absolute URI or a relative
- * URI from the root library), and:
- *
- *   * If present, invokes any top-level and static functions marked
- *     with the [initMethod] annotation (in the order they appear).
- *
- *   * Registers any [PolymerElement] that is marked with the [CustomTag]
- *     annotation.
- */
+/// Reads the library at [uriString] (which can be an absolute URI or a relative
+/// URI from the root library), and:
+///
+///   * If present, invokes any top-level and static functions marked
+///     with the [initMethod] annotation (in the order they appear).
+///
+///   * Registers any [PolymerElement] that is marked with the [CustomTag]
+///     annotation.
 void _loadLibrary(String uriString, List<Function> initializers) {
   var uri = _rootUri.resolve(uriString);
   var lib = _libs[uri];
diff --git a/pkg/polymer/lib/transformer.dart b/pkg/polymer/lib/transformer.dart
index 960d9df..6183a74 100644
--- a/pkg/polymer/lib/transformer.dart
+++ b/pkg/polymer/lib/transformer.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.
 
-/** Transfomer used for pub-serve and pub-deploy. */
+/// Transfomer used for pub-serve and pub-deploy.
 library polymer.transformer;
 
 import 'package:barback/barback.dart';
@@ -16,17 +16,15 @@
 import 'src/build/polyfill_injector.dart';
 import 'src/build/script_compactor.dart';
 
-/**
- * The Polymer transformer, which internally runs several phases that will:
- *   * Extract inlined script tags into their separate files
- *   * Apply the observable transformer on every Dart script.
- *   * Inline imported html files
- *   * Combine scripts from multiple files into a single script tag
- *   * Inject extra polyfills needed to run on all browsers.
- *
- * At the end of these phases, this tranformer produces a single entrypoint HTML
- * file with a single Dart script that can later be compiled with dart2js.
- */
+/// The Polymer transformer, which internally runs several phases that will:
+///   * Extract inlined script tags into their separate files
+///   * Apply the observable transformer on every Dart script.
+///   * Inline imported html files
+///   * Combine scripts from multiple files into a single script tag
+///   * Inject extra polyfills needed to run on all browsers.
+///
+/// At the end of these phases, this tranformer produces a single entrypoint
+/// HTML file with a single Dart script that can later be compiled with dart2js.
 class PolymerTransformerGroup implements TransformerGroup {
   final Iterable<Iterable> phases;
 
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 08e2b6a..a57e7a6 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -7,15 +7,16 @@
   browsers.
 homepage: https://www.dartlang.org/polymer-dart/
 dependencies:
-  analyzer: ">=0.10.1 <0.11.0"
-  args: ">=0.9.0 <0.10.0"
-  barback: ">=0.9.0 <0.12.0"
+  analyzer: ">=0.12.0 <0.13.0"
+  args: ">=0.9.0 <0.11.0"
+  barback: ">=0.9.0 <0.13.0"
   browser: ">=0.9.0 <0.10.0"
   html5lib: ">=0.9.2-dev <0.10.0"
   logging: ">=0.9.0 <0.10.0"
   observe: ">=0.10.0-dev <0.11.0"
   path: ">=0.9.0 <2.0.0"
   polymer_expressions: ">=0.10.0-dev <0.11.0"
+  smoke: ">=0.1.0-dev <0.2.0"
   source_maps: ">=0.9.0 <0.10.0"
   template_binding: ">=0.10.0-dev <0.11.0"
   web_components: ">=0.3.0 <0.4.0"
@@ -24,6 +25,6 @@
 - observe:
     files: lib/src/instance.dart
 dev_dependencies:
-  unittest: ">=0.9.0 <0.10.0"
+  unittest: ">=0.10.0 <0.11.0"
 environment:
   sdk: ">=1.1.0-dev.5.0 <2.0.0"
diff --git a/pkg/polymer/test/attr_deserialize_test.dart b/pkg/polymer/test/attr_deserialize_test.dart
index 4cee6c9..536b019 100644
--- a/pkg/polymer/test/attr_deserialize_test.dart
+++ b/pkg/polymer/test/attr_deserialize_test.dart
@@ -26,7 +26,7 @@
   setUp(() => Polymer.onReady);
 
   test('attributes were deserialized', () {
-    MyElement elem = query('my-element');
+    MyElement elem = querySelector('my-element');
     final msg = 'property should match attribute.';
     expect(elem.volume, 11.0, reason: '"volume" should match attribute');
     expect(elem.factor, 3, reason: '"factor" should match attribute');
diff --git a/pkg/polymer/test/attr_mustache_test.dart b/pkg/polymer/test/attr_mustache_test.dart
index 45da525..e327ed6 100644
--- a/pkg/polymer/test/attr_mustache_test.dart
+++ b/pkg/polymer/test/attr_mustache_test.dart
@@ -51,8 +51,8 @@
   setUp(() => Polymer.onReady);
 
   test('mustache attributes', () {
-    final xtest = document.query('#test');
-    final xtarget = xtest.shadowRoot.query('#target');
+    final xtest = document.querySelector('#test');
+    final xtarget = xtest.shadowRoot.querySelector('#target');
     return xtarget.foundSrc;
   });
 }
diff --git a/pkg/polymer/test/bind_test.dart b/pkg/polymer/test/bind_test.dart
index 1fd6515..7a58683 100644
--- a/pkg/polymer/test/bind_test.dart
+++ b/pkg/polymer/test/bind_test.dart
@@ -50,5 +50,5 @@
 
   setUp(() => Polymer.onReady);
 
-  test('ready called', () => (query('x-foo') as XFoo).onTestDone);
+  test('ready called', () => (querySelector('x-foo') as XFoo).onTestDone);
 }
diff --git a/pkg/polymer/test/build/common.dart b/pkg/polymer/test/build/common.dart
index a4d9ba2..be187ca 100644
--- a/pkg/polymer/test/build/common.dart
+++ b/pkg/polymer/test/build/common.dart
@@ -20,15 +20,11 @@
     str.splitMapJoin('\n',
         onNonMatch: (s) => s.replaceAll(new RegExp(r'\s+$'), ''));
 
-/**
- * A helper package provider that has files stored in memory, also wraps
- * [Barback] to simply our tests.
- */
+/// A helper package provider that has files stored in memory, also wraps
+/// [Barback] to simply our tests.
 class TestHelper implements PackageProvider {
-  /**
-   * Maps from an asset string identifier of the form 'package|path' to the
-   * file contents.
-   */
+  /// Maps from an asset string identifier of the form 'package|path' to the
+  /// file contents.
   final Map<String, String> files;
   final Iterable<String> packages;
   final List<String> messages;
@@ -66,6 +62,8 @@
     });
 
     logSubscription = barback.log.listen((entry) {
+      // Ignore info messages.
+      if (entry.level == LogLevel.INFO) return;
       if (entry.level == LogLevel.ERROR) errorSeen = true;
       // We only check messages when an expectation is provided.
       if (messages == null) return;
@@ -86,10 +84,8 @@
     logSubscription.cancel();
   }
 
-  /**
-   * Tells barback which files have changed, and thus anything that depends on
-   * it on should be computed. By default mark all the input files.
-   */
+  /// Tells barback which files have changed, and thus anything that depends on
+  /// it on should be computed. By default mark all the input files.
   void run([Iterable<String> paths]) {
     if (paths == null) paths = files.keys;
     barback.updateSources(paths.map(idFromString));
@@ -109,11 +105,14 @@
   }
 
   Future checkAll(Map<String, String> files) {
-    var futures = [];
-    files.forEach((k, v) {
-      futures.add(check(k, v));
-    });
-    return Future.wait(futures).then((_) {
+    return barback.results.first.then((_) {
+      if (files == null) return null;
+      var futures = [];
+      files.forEach((k, v) {
+        futures.add(check(k, v));
+      });
+      return Future.wait(futures);
+    }).then((_) {
       // We only check messages when an expectation is provided.
       if (messages == null) return;
       expect(messages.length, messagesSeen,
diff --git a/pkg/polymer/test/build/import_inliner_test.dart b/pkg/polymer/test/build/import_inliner_test.dart
index 8de8571..f665003 100644
--- a/pkg/polymer/test/build/import_inliner_test.dart
+++ b/pkg/polymer/test/build/import_inliner_test.dart
@@ -11,9 +11,15 @@
 
 import 'common.dart';
 
+final phases = [[new ImportInliner(new TransformOptions())]];
+
 void main() {
   useCompactVMConfiguration();
-  var phases = [[new ImportInliner(new TransformOptions())]];
+  group('rel=import', importTests);
+  group('rel=stylesheet', stylesheetTests);
+}
+
+void importTests() {
   testPhases('no changes', phases, {
       'a|web/test.html': '<!DOCTYPE html><html></html>',
     }, {
@@ -82,6 +88,37 @@
       'a|web/test2.html.scriptUrls': '[]',
     });
 
+  testPhases('preserves order of scripts', phases,
+    {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<script type="text/javascript">/*first*/</script>'
+          '<script src="second.js"></script>'
+          '<link rel="import" href="test2.html">'
+          '<script type="application/dart">/*forth*/</script>'
+          '</head></html>',
+      'a|web/test2.html':
+          '<!DOCTYPE html><html><head><script>/*third*/</script>'
+          '</head><body><polymer-element>2</polymer-element></html>',
+      'a|web/second.js': '/*second*/'
+    }, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '</head><body>'
+          '<script type="text/javascript">/*first*/</script>'
+          '<script src="second.js"></script>'
+          '<script>/*third*/</script>'
+          '<polymer-element>2</polymer-element>'
+          '<script type="application/dart">/*forth*/</script>'
+          '</body></html>',
+      'a|web/test.html.scriptUrls': '[]',
+      'a|web/test2.html':
+          '<!DOCTYPE html><html><head><script>/*third*/</script>'
+          '</head><body><polymer-element>2</polymer-element></html>',
+      'a|web/test2.html.scriptUrls': '[]',
+      'a|web/second.js': '/*second*/'
+    });
+
   testPhases('no transformation outside web/', phases,
     {
       'a|lib/test.html':
@@ -502,3 +539,130 @@
           '<polymer-element>3</polymer-element></body></html>',
     });
 }
+
+void stylesheetTests() {
+
+  testPhases('empty stylesheet', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="">' // empty href
+          '</head></html>',
+      'a|web/test2.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet">'         // no href
+          '</head></html>',
+    }, {
+      'a|web/test.html':
+        '<!DOCTYPE html><html><head>'
+        '<link rel="stylesheet" href="">' // empty href
+        '</head></html>',
+      'a|web/test.html.scriptUrls': '[]',
+      'a|web/test2.html':
+        '<!DOCTYPE html><html><head>'
+        '<link rel="stylesheet">'         // no href
+        '</head></html>',
+      'a|web/test2.html.scriptUrls': '[]',
+    });
+
+  testPhases('absolute uri', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="/foo.css">'
+          '</head></html>',
+      'a|web/test2.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="http://example.com/bar.css">'
+          '</head></html>',
+    }, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="/foo.css">'
+          '</head></html>',
+      'a|web/test.html.scriptUrls': '[]',
+      'a|web/test2.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="http://example.com/bar.css">'
+          '</head></html>',
+      'a|web/test2.html.scriptUrls': '[]',
+    });
+
+  testPhases('shallow, inlines css', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="stylesheet" href="test2.css">'
+          '</head></html>',
+      'a|web/test2.css':
+          'h1 { font-size: 70px; }',
+    }, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head></head><body>'
+          '<style>h1 { font-size: 70px; }</style>'
+          '</body></html>',
+      'a|web/test.html.scriptUrls': '[]',
+      'a|web/test2.css':
+          'h1 { font-size: 70px; }',
+    });
+
+  testPhases('deep, inlines css', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="import" href="test2.html">'
+          '</head></html>',
+      'a|web/test2.html':
+          '<polymer-element>2'
+          '<link rel="stylesheet" href="assets/b/test3.css">'
+          '</polymer-element>',
+      'b|asset/test3.css':
+          'body {\n  background: #eaeaea url("assets/b/test4.png");\n}\n'
+          '.foo {\n  background: url("../../packages/c/test5.png");\n}',
+      'b|asset/test4.png': 'PNG',
+      'c|lib/test5.png': 'PNG',
+    }, {
+      'a|web/test.html':
+        '<!DOCTYPE html><html><head></head><body>'
+        '<polymer-element>2'
+        '<style>'
+        'body {\n  background: #eaeaea url(assets/b/test4.png);\n}\n'
+        '.foo {\n  background: url(packages/c/test5.png);\n}'
+        '</style>'
+        '</polymer-element>'
+        '</body></html>',
+      'a|web/test2.html':
+          '<html><head></head><body>'
+          '<polymer-element>2'
+          '<style>'
+          'body {\n  background: #eaeaea url(assets/b/test4.png);\n}\n'
+          '.foo {\n  background: url(packages/c/test5.png);\n}'
+          '</style>'
+          '</polymer-element>'
+          '</body></html>',
+      'b|asset/test3.css':
+          'body {\n  background: #eaeaea url("assets/b/test4.png");\n}\n'
+          '.foo {\n  background: url("../../packages/c/test5.png");\n}',
+      'b|asset/test4.png': 'PNG',
+      'c|lib/test5.png': 'PNG',
+    });
+
+
+  testPhases('shallow, inlines css and preserves order', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<style>.first { color: black }</style>'
+          '<link rel="stylesheet" href="test2.css">'
+          '<style>.second { color: black }</style>'
+          '</head></html>',
+      'a|web/test2.css':
+          'h1 { font-size: 70px; }',
+    }, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head></head><body>'
+          '<style>.first { color: black }</style>'
+          '<style>h1 { font-size: 70px; }</style>'
+          '<style>.second { color: black }</style>'
+          '</body></html>',
+      'a|web/test.html.scriptUrls': '[]',
+      'a|web/test2.css':
+          'h1 { font-size: 70px; }',
+    });
+
+}
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index 1641b64..4894b55 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:polymer/src/build/common.dart';
 import 'package:polymer/src/build/linter.dart';
-import 'package:source_maps/span.dart';
 import 'package:unittest/compact_vm_config.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/polymer/test/build/static_clean_test.dart b/pkg/polymer/test/build/static_clean_test.dart
index 410fc51..2fa62a9 100644
--- a/pkg/polymer/test/build/static_clean_test.dart
+++ b/pkg/polymer/test/build/static_clean_test.dart
@@ -6,6 +6,8 @@
 
 import 'package:polymer/builder.dart';
 
+_unused() => build;
+
 void main() {
   // Check that builder.dart is statically clean. Nothing to do.
 }
diff --git a/pkg/polymer/test/build/utils_test.dart b/pkg/polymer/test/build/utils_test.dart
index cd99656..8aa3bdd 100644
--- a/pkg/polymer/test/build/utils_test.dart
+++ b/pkg/polymer/test/build/utils_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.
 
-/** Tests for some of the utility helper functions used by the compiler. */
+/// Tests for some of the utility helper functions used by the compiler.
 library polymer.test.utils_test;
 
 import 'package:unittest/compact_vm_config.dart';
diff --git a/pkg/polymer/test/custom_event_test.dart b/pkg/polymer/test/custom_event_test.dart
index 08c45af..b584029 100644
--- a/pkg/polymer/test/custom_event_test.dart
+++ b/pkg/polymer/test/custom_event_test.dart
@@ -35,7 +35,7 @@
 class TestCustomEvent extends PolymerElement {
   TestCustomEvent.created() : super.created();
 
-  get fooBar => getShadowRoot('test-custom-event').query('foo-bar');
+  get fooBar => getShadowRoot('test-custom-event').querySelector('foo-bar');
 
   final events = [];
   fooHandler(e) => events.add(['foo', e]);
@@ -49,7 +49,7 @@
   setUp(() => Polymer.onReady);
 
   test('custom event', () {
-    final testComp = query('test-custom-event');
+    final testComp = querySelector('test-custom-event');
     final fooBar = testComp.fooBar;
 
     final binding = nodeBind(fooBar).bindings['on-barbaz'];
diff --git a/pkg/polymer/test/entered_view_test.dart b/pkg/polymer/test/entered_view_test.dart
index c9f7b34..632ea70 100644
--- a/pkg/polymer/test/entered_view_test.dart
+++ b/pkg/polymer/test/entered_view_test.dart
@@ -40,13 +40,13 @@
   setUp(() => Polymer.onReady);
 
   test('element created properly', () {
-    XOuter outer = query('x-outer');
+    XOuter outer = querySelector('x-outer');
     outer.expand = true;
     return outer.onMutation(outer.shadowRoot).then((_) {
       // Element upgrade is also using mutation observers. Wait another tick so
       // it goes before we do.
       return new Future(() {
-        XInner inner = outer.shadowRoot.query('x-inner');
+        XInner inner = outer.shadowRoot.querySelector('x-inner');
         expect(inner.enteredCount, 1, reason: 'enteredView should be called');
       });
     });
diff --git a/pkg/polymer/test/event_handlers_test.dart b/pkg/polymer/test/event_handlers_test.dart
index 33d8631..852d44d 100644
--- a/pkg/polymer/test/event_handlers_test.dart
+++ b/pkg/polymer/test/event_handlers_test.dart
@@ -114,7 +114,7 @@
 
   setUp(() => Polymer.onReady);
   test('events handled', () {
-    XTest test = query('x-test');
+    XTest test = querySelector('x-test');
     expect(test._onTestDone, isNotNull, reason: 'ready was called');
     return test._onTestDone;
   });
diff --git a/pkg/polymer/test/event_path_declarative_test.dart b/pkg/polymer/test/event_path_declarative_test.dart
index 1c9495f..9983d13 100644
--- a/pkg/polymer/test/event_path_declarative_test.dart
+++ b/pkg/polymer/test/event_path_declarative_test.dart
@@ -9,13 +9,11 @@
 library polymer.test.event_path_declarative_test;
 
 import 'dart:async';
-import 'dart:collection';
 import 'dart:html';
 
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 import 'package:polymer/polymer.dart';
-import 'package:template_binding/template_binding.dart';
 
 var _observedEvents = [];
 var _testFired;
diff --git a/pkg/polymer/test/event_path_test.dart b/pkg/polymer/test/event_path_test.dart
index f1e23eb..86978eb 100644
--- a/pkg/polymer/test/event_path_test.dart
+++ b/pkg/polymer/test/event_path_test.dart
@@ -36,25 +36,25 @@
   setUp(() => Polymer.onReady);
 
   test('bubbling in the right order', () {
-    var item1 = query('#item1');
-    var menuButton = query('#menuButton');
+    var item1 = querySelector('#item1');
+    var menuButton = querySelector('#menuButton');
     // Note: polymer uses automatic node finding (menuButton.$.menu)
     // also note that their node finding code also reachs into the ids
     // from the parent shadow (menu.$.selectorContent instead of
     // menu.$.menuShadow.$.selectorContent)
-    var menu = menuButton.shadowRoot.query('#menu');
-    var overlay = menuButton.shadowRoot.query('#overlay');
+    var menu = menuButton.shadowRoot.querySelector('#menu');
+    var overlay = menuButton.shadowRoot.querySelector('#overlay');
     var expectedPath = <Node>[
         item1,
-        menuButton.shadowRoot.query('#menuButtonContent'),
-        menu.shadowRoot.olderShadowRoot.query('#selectorContent'),
-        menu.shadowRoot.olderShadowRoot.query('#selectorDiv'),
+        menuButton.shadowRoot.querySelector('#menuButtonContent'),
+        menu.shadowRoot.olderShadowRoot.querySelector('#selectorContent'),
+        menu.shadowRoot.olderShadowRoot.querySelector('#selectorDiv'),
         menu.shadowRoot.olderShadowRoot,
-        menu.shadowRoot.query('#menuShadow'),
-        menu.shadowRoot.query('#menuDiv'),
+        menu.shadowRoot.querySelector('#menuShadow'),
+        menu.shadowRoot.querySelector('#menuDiv'),
         menu.shadowRoot,
         menu,
-        menuButton.shadowRoot.query('#menuButtonDiv'),
+        menuButton.shadowRoot.querySelector('#menuButtonDiv'),
         // TODO(sigmund): this test is currently broken because currently
         // registerElement is sensitive to the order in which each custom
         // element is registered. When fixed, we should be able to add the
@@ -69,7 +69,7 @@
     for (int i = 0; i < expectedPath.length; i++) {
       var node = expectedPath[i];
       expect(node, isNotNull, reason: "Should not be null at $i");
-      node.on['x'].listen(expectAsync1((e) {
+      node.on['x'].listen(expectAsync((e) {
         expect(e.currentTarget, node);
         expect(x++, i);
       }));
diff --git a/pkg/polymer/test/events_test.dart b/pkg/polymer/test/events_test.dart
index f14cf4a..a1c601a 100644
--- a/pkg/polymer/test/events_test.dart
+++ b/pkg/polymer/test/events_test.dart
@@ -53,34 +53,34 @@
   test('host event', () {
     // Note: this test is currently the only event in
     // polymer/test/js/events.js at commit #7936ff8
-    var testA = query('#a');
+    var testA = querySelector('#a');
     expect(testA.clicks, isEmpty);
     testA.click();
     expect(testA.clicks, ['host click on: test-a (id a)']);
   });
 
   test('local event', () {
-    var testB = query('#b');
+    var testB = querySelector('#b');
     expect(testB.clicks, isEmpty);
     testB.click();
     expect(testB.clicks, []);
-    var b1 = testB.shadowRoot.query('#b-1');
+    var b1 = testB.shadowRoot.querySelector('#b-1');
     b1.click();
     expect(testB.clicks, []);
-    var b2 = testB.shadowRoot.query('#b-2');
+    var b2 = testB.shadowRoot.querySelector('#b-2');
     b2.click();
     expect(testB.clicks, ['local click under test-b (id b) on b-2']);
   });
 
   test('event on superclass', () {
-    var testC = query('#c');
+    var testC = querySelector('#c');
     expect(testC.clicks, isEmpty);
     testC.click();
     expect(testC.clicks, []);
-    var c1 = testC.shadowRoot.query('#c-1');
+    var c1 = testC.shadowRoot.querySelector('#c-1');
     c1.click();
     expect(testC.clicks, []);
-    var c2 = testC.shadowRoot.query('#c-2');
+    var c2 = testC.shadowRoot.querySelector('#c-2');
     c2.click();
     expect(testC.clicks, ['local click under test-c (id c) on c-2']);
   });
diff --git a/pkg/polymer/test/instance_attrs_test.dart b/pkg/polymer/test/instance_attrs_test.dart
index a759ae9..f5b6eac 100644
--- a/pkg/polymer/test/instance_attrs_test.dart
+++ b/pkg/polymer/test/instance_attrs_test.dart
@@ -24,7 +24,7 @@
   setUp(() => Polymer.onReady);
 
   test('attributes were deserialized', () {
-    var elem = query('my-element');
+    var elem = querySelector('my-element');
 
     expect(elem.attributes, {'foo': '123', 'bar': 'hi', 'baz': 'world'},
         reason: 'attributes should be copied to instance');
diff --git a/pkg/polymer/test/prop_attr_bind_reflection_test.dart b/pkg/polymer/test/prop_attr_bind_reflection_test.dart
index 554bbfb..bfe16bf 100644
--- a/pkg/polymer/test/prop_attr_bind_reflection_test.dart
+++ b/pkg/polymer/test/prop_attr_bind_reflection_test.dart
@@ -33,7 +33,8 @@
   setUp(() => Polymer.onReady);
 
   test('attribute reflected to property name', () {
-    var child = query('my-element').shadowRoot.query('my-child-element');
+    var child = querySelector('my-element')
+        .shadowRoot.querySelector('my-child-element');
     expect(child.lowercase, 11);
     expect(child.camelCase, 11);
 
diff --git a/pkg/polymer/test/prop_attr_reflection_test.dart b/pkg/polymer/test/prop_attr_reflection_test.dart
index 37562da..79b9c8e 100644
--- a/pkg/polymer/test/prop_attr_reflection_test.dart
+++ b/pkg/polymer/test/prop_attr_reflection_test.dart
@@ -52,9 +52,9 @@
   Polymer.register('x-compose', XCompose);
 
   test('property attribute reflection', () {
-    var xcompose = query('x-compose');
-    var xfoo = query('x-foo');
-    var xbar = query('x-bar');
+    var xcompose = querySelector('x-compose');
+    var xfoo = querySelector('x-foo');
+    var xbar = querySelector('x-bar');
     xfoo.foo = 5;
     return onAttributeChange(xfoo).then((_) {
       expect(xcompose.$['bar'].attributes.containsKey('zim'), false,
diff --git a/pkg/polymer/test/property_change_test.dart b/pkg/polymer/test/property_change_test.dart
index ea41e11..a8f0845 100644
--- a/pkg/polymer/test/property_change_test.dart
+++ b/pkg/polymer/test/property_change_test.dart
@@ -5,7 +5,6 @@
 library polymer.test.property_change_test;
 
 import 'dart:async';
-import 'dart:html';
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
diff --git a/pkg/polymer/test/publish_attributes_test.dart b/pkg/polymer/test/publish_attributes_test.dart
index 78bd593..6ff61a8 100644
--- a/pkg/polymer/test/publish_attributes_test.dart
+++ b/pkg/polymer/test/publish_attributes_test.dart
@@ -59,7 +59,7 @@
   setUp(() => Polymer.onReady);
 
   test('published properties', () {
-    published(tag) => (query('polymer-element[name=$tag]')
+    published(tag) => (querySelector('polymer-element[name=$tag]')
         as PolymerDeclaration).publishedProperties;
 
     expect(published('x-foo'), ['Foo', 'baz']);
diff --git a/pkg/polymer/test/publish_inherited_properties_test.dart b/pkg/polymer/test/publish_inherited_properties_test.dart
index 24595c4..dddbf29 100644
--- a/pkg/polymer/test/publish_inherited_properties_test.dart
+++ b/pkg/polymer/test/publish_inherited_properties_test.dart
@@ -53,7 +53,7 @@
   setUp(() => Polymer.onReady);
 
   test('published properties', () {
-    published(tag) => (query('polymer-element[name=$tag]')
+    published(tag) => (querySelector('polymer-element[name=$tag]')
         as PolymerDeclaration).publishedProperties;
 
     expect(published('x-zot'), ['Foo', 'Bar', 'zot', 'm']);
diff --git a/pkg/polymer/test/take_attributes_test.dart b/pkg/polymer/test/take_attributes_test.dart
index f5778c5..8267deb 100644
--- a/pkg/polymer/test/take_attributes_test.dart
+++ b/pkg/polymer/test/take_attributes_test.dart
@@ -56,7 +56,7 @@
   setUp(() => Polymer.onReady);
 
   test('take attributes', () {
-    queryXTag(x) => document.query(x);
+    queryXTag(x) => document.querySelector(x);
 
     expect(queryXTag("#foo0").boolean, true);
     expect(queryXTag("#foo1").boolean, false);
diff --git a/pkg/polymer/test/template_distribute_dynamic_test.dart b/pkg/polymer/test/template_distribute_dynamic_test.dart
index e80c624..8d6cc6a 100644
--- a/pkg/polymer/test/template_distribute_dynamic_test.dart
+++ b/pkg/polymer/test/template_distribute_dynamic_test.dart
@@ -58,5 +58,5 @@
 
   setUp(() => Polymer.onReady);
 
-  test('inserted called', () => (query('x-test') as XTest).onTestDone);
+  test('inserted called', () => (querySelector('x-test') as XTest).onTestDone);
 }
diff --git a/pkg/polymer/test/unbind_test.dart b/pkg/polymer/test/unbind_test.dart
index 4dc961d..1de5630 100644
--- a/pkg/polymer/test/unbind_test.dart
+++ b/pkg/polymer/test/unbind_test.dart
@@ -69,7 +69,7 @@
 _unbound(node) => reflect(node).getField(unboundSymbol).reflectee;
 
 unbindTests() {
-  var xTest = document.query('x-test');
+  var xTest = document.querySelector('x-test');
   xTest.foo = 'bar';
   scheduleMicrotask(Observable.dirtyCheck);
 
diff --git a/pkg/polymer_expressions/lib/eval.dart b/pkg/polymer_expressions/lib/eval.dart
index 22851e6..7b925a7 100644
--- a/pkg/polymer_expressions/lib/eval.dart
+++ b/pkg/polymer_expressions/lib/eval.dart
@@ -7,17 +7,18 @@
 import 'dart:async';
 import 'dart:collection';
 
-@MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
-    override: 'polymer_expressions.eval')
-import 'dart:mirrors';
+@MirrorsUsed(
+    metaTargets: const [Reflectable, ObservableProperty],
+    override: 'smoke.mirrors')
+import 'dart:mirrors' show MirrorsUsed;
 
 import 'package:observe/observe.dart';
+import 'package:smoke/smoke.dart' as smoke;
 
 import 'async.dart';
 import 'expression.dart';
 import 'filter.dart';
 import 'visitor.dart';
-import 'src/mirrors.dart';
 
 final _BINARY_OPERATORS = {
   '+':  (a, b) => a + b,
@@ -142,7 +143,7 @@
   if (isIndex) {
     o[property] = value;
   } else {
-    reflect(o).setField(new Symbol(property), value);
+    smoke.write(o, smoke.nameToSymbol(property), value);
   }
 }
 
@@ -159,33 +160,19 @@
   final Object model;
   // TODO(justinfagnani): disallow adding/removing names
   final ObservableMap<String, Object> _variables;
-  InstanceMirror __modelMirror;
 
   Scope({this.model, Map<String, Object> variables, this.parent})
       : _variables = new ObservableMap.from(variables == null ? {} : variables);
 
-  InstanceMirror get _modelMirror {
-    if (__modelMirror != null) return __modelMirror;
-    __modelMirror = reflect(model);
-    return __modelMirror;
-  }
-
   Object operator[](String name) {
     if (name == 'this') {
       return model;
     } else if (_variables.containsKey(name)) {
       return _convert(_variables[name]);
-    } else if (model != null) {
-      var symbol = new Symbol(name);
-      var classMirror = _modelMirror.type;
-      var memberMirror = getMemberMirror(classMirror, symbol);
-      // TODO(jmesserly): simplify once dartbug.com/13002 is fixed.
-      // This can just be "if memberMirror != null" and delete the Method class.
-      if (memberMirror is VariableMirror ||
-          (memberMirror is MethodMirror && memberMirror.isGetter)) {
-        return _convert(_modelMirror.getField(symbol).reflectee);
-      } else if (memberMirror is MethodMirror) {
-        return new Method(_modelMirror, symbol);
+    } else {
+      var symbol = smoke.nameToSymbol(name);
+      if (model != null && smoke.hasGetter(model.runtimeType, symbol)) {
+        return _convert(smoke.read(model, symbol));
       }
     }
     if (parent != null) {
@@ -203,12 +190,8 @@
       return null;
     } else if (_variables.containsKey(name)) {
       return _variables;
-    } else {
-      var symbol = new Symbol(name);
-      var classMirror = _modelMirror.type;
-      if (getMemberMirror(classMirror, symbol) != null) {
-        return model;
-      }
+    } else if (smoke.hasGetter(model.runtimeType, smoke.nameToSymbol(name))) {
+      return model;
     }
     if (parent != null) {
       return parent.ownerOf(name);
@@ -216,14 +199,9 @@
   }
 
   bool contains(String name) {
-    if (_variables.containsKey(name)) {
+    if (_variables.containsKey(name) ||
+        smoke.hasGetter(model.runtimeType, smoke.nameToSymbol(name))) {
       return true;
-    } else {
-      var symbol = new Symbol(name);
-      var classMirror = _modelMirror.type;
-      if (getMemberMirror(classMirror, symbol) != null) {
-        return true;
-      }
     }
     if (parent != null) {
       return parent.contains(name);
@@ -480,7 +458,7 @@
 
     var owner = scope.ownerOf(value);
     if (owner is Observable) {
-      var symbol = new Symbol(value);
+      var symbol = smoke.nameToSymbol(value);
       _subscription = (owner as Observable).changes.listen((changes) {
         if (changes.any(
             (c) => c is PropertyChangeRecord && c.name == symbol)) {
@@ -590,9 +568,8 @@
       _value = null;
       return;
     }
-    var mirror = reflect(receiverValue);
-    var symbol = new Symbol(_expr.name);
-    _value = mirror.getField(symbol).reflectee;
+    var symbol = smoke.nameToSymbol(_expr.name);
+    _value = smoke.read(receiverValue, symbol);
 
     if (receiverValue is Observable) {
       _subscription = (receiverValue as Observable).changes.listen((changes) {
@@ -657,11 +634,10 @@
       // changed? listen to the scope to see if the top-level method has
       // changed?
       assert(receiverValue is Function);
-      _value = call(receiverValue, args);
+      _value = _convert(Function.apply(receiverValue, args));
     } else {
-      var mirror = reflect(receiverValue);
-      var symbol = new Symbol(_expr.method);
-      _value = mirror.invoke(symbol, args, null).reflectee;
+      var symbol = smoke.nameToSymbol(_expr.method);
+      _value = smoke.invoke(receiverValue, symbol, args);
 
       if (receiverValue is Observable) {
         _subscription = (receiverValue as Observable).changes.listen(
@@ -706,20 +682,6 @@
 
 _toBool(v) => (v == null) ? false : v;
 
-/** Call a [Function] or a [Method]. */
-// TODO(jmesserly): remove this once dartbug.com/13002 is fixed.
-// Just inline `_convert(Function.apply(...))` to the call site.
-Object call(Object receiver, List args) {
-  var result;
-  if (receiver is Method) {
-    Method method = receiver;
-    result = method.mirror.invoke(method.symbol, args, null).reflectee;
-  } else {
-    result = Function.apply(receiver, args, null);
-  }
-  return _convert(result);
-}
-
 /**
  * A comprehension declaration ("a in b"). [identifier] is the loop variable
  * that's added to the scope during iteration. [iterable] is the set of
@@ -733,20 +695,6 @@
       : iterable = (iterable != null) ? iterable : const [];
 }
 
-/** A method on a model object in a [Scope]. */
-class Method {
-  final InstanceMirror mirror;
-  final Symbol symbol;
-
-  Method(this.mirror, this.symbol);
-
-  /**
-   * Support for calling single argument methods like [Filter]s.
-   * This does not work for calls that need to pass more than one argument.
-   */
-  call(arg0) => mirror.invoke(symbol, [arg0], null).reflectee;
-}
-
 class EvalException implements Exception {
   final String message;
   EvalException(this.message);
diff --git a/pkg/polymer_expressions/lib/src/mirrors.dart b/pkg/polymer_expressions/lib/src/mirrors.dart
deleted file mode 100644
index f46ee6e..0000000
--- a/pkg/polymer_expressions/lib/src/mirrors.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library polymer_expressions.src.mirrors;
-
-import 'package:observe/observe.dart' show Reflectable, ObservableProperty;
-
-@MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
-    override: 'polymer_expressions.src.mirrors')
-import 'dart:mirrors';
-
-/**
- * Walks up the class hierarchy to find a method declaration with the given
- * [name].
- *
- * Note that it's not possible to tell if there's an implementation via
- * noSuchMethod().
- */
-Mirror getMemberMirror(ClassMirror classMirror, Symbol name) {
-  if (classMirror.declarations.containsKey(name)) {
-    return classMirror.declarations[name];
-  }
-  if (hasSuperclass(classMirror)) {
-    var mirror = getMemberMirror(classMirror.superclass, name);
-    if (mirror != null) {
-      return mirror;
-    }
-  }
-  for (ClassMirror supe in classMirror.superinterfaces) {
-    var mirror = getMemberMirror(supe, name);
-    if (mirror != null) {
-      return mirror;
-    }
-  }
-  return null;
-}
-
-/**
- * Work-around for http://dartbug.com/5794
- */
-bool hasSuperclass(ClassMirror classMirror) {
-  var superclass = classMirror.superclass;
-  return (superclass != null) &&
-      (superclass.qualifiedName != #dart.core.Object);
-}
diff --git a/pkg/scheduled_test/lib/descriptor.dart b/pkg/scheduled_test/lib/descriptor.dart
index 0004236..f49f323 100644
--- a/pkg/scheduled_test/lib/descriptor.dart
+++ b/pkg/scheduled_test/lib/descriptor.dart
@@ -10,6 +10,8 @@
 /// on the physical filesystem, or [Descriptor.validate] to schedule an
 /// assertion that that structure exists. For example:
 ///
+///     import 'dart:io';
+///
 ///     import 'package:scheduled_test/descriptor.dart' as d;
 ///     import 'package:scheduled_test/scheduled_test.dart';
 ///
@@ -31,7 +33,7 @@
 ///             d.file('child', 'child-contents')
 ///           ])
 ///         ]).validate();
-///       })
+///       });
 ///     }
 ///
 /// Usually you don't want your tests cluttering up your working directory with
@@ -100,7 +102,7 @@
 
 /// Creates a new binary [FileDescriptor] descriptor with [name] and [contents].
 FileDescriptor binaryFile(String name, List<int> contents) =>
-  new FileDescriptor.binary(name, contents);
+    new FileDescriptor.binary(name, contents);
 
 /// Creates a new text [FileDescriptor] with [name] that matches its String
 /// contents against [matcher]. If the file is created, it's considered to be
@@ -112,16 +114,15 @@
 /// contents against [matcher]. If the file is created, it's considered to be
 /// empty.
 FileDescriptor binaryMatcherFile(String name, matcher) =>
-  new FileDescriptor.binaryMatcher(name, wrapMatcher(matcher));
+    new FileDescriptor.binaryMatcher(name, wrapMatcher(matcher));
 
 /// Creates a new [DirectoryDescriptor] descriptor with [name] and [contents].
 DirectoryDescriptor dir(String name, [Iterable<Descriptor> contents]) =>
-   new DirectoryDescriptor(name, contents == null? <Descriptor>[] : contents);
+    new DirectoryDescriptor(name, contents == null ? <Descriptor>[] : contents);
 
 /// Creates a new descriptor wrapping a [Future]. This descriptor forwards all
 /// asynchronous operations to the result of [future].
-AsyncDescriptor async(Future<Descriptor> future) =>
-  new AsyncDescriptor(future);
+AsyncDescriptor async(Future<Descriptor> future) => new AsyncDescriptor(future);
 
 /// Creates a new [NothingDescriptor] descriptor that asserts that no entry
 /// named [name] exists.
@@ -131,7 +132,7 @@
 /// a name matching [pattern] exists, and matches the [Descriptor] returned
 /// by [fn].
 PatternDescriptor pattern(Pattern name, EntryCreator fn) =>
-  new PatternDescriptor(name, fn);
+    new PatternDescriptor(name, fn);
 
 /// A convenience method for creating a [PatternDescriptor] descriptor that
 /// constructs a [FileDescriptor] descriptor.
@@ -141,4 +142,4 @@
 /// A convenience method for creating a [PatternDescriptor] descriptor that
 /// constructs a [DirectoryDescriptor] descriptor.
 PatternDescriptor dirPattern(Pattern name, [Iterable<Descriptor> contents]) =>
-  pattern(name, (realName) => dir(realName, contents));
+    pattern(name, (realName) => dir(realName, contents));
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 295efcb..46bb5b6 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -10,6 +10,7 @@
 
 import 'package:stack_trace/stack_trace.dart';
 
+import 'scheduled_stream.dart';
 import 'scheduled_test.dart';
 import 'src/utils.dart';
 import 'src/value_future.dart';
@@ -44,7 +45,8 @@
   Stream<String> _stdoutLog;
 
   /// A line-by-line view of the standard output stream of the process.
-  StreamIterator<String> _stdout;
+  ScheduledStream<String> get stdout => _stdout;
+  ScheduledStream<String> _stdout;
 
   /// A canceller that controls both [_stdout] and [_stdoutLog].
   StreamCanceller _stdoutCanceller;
@@ -54,7 +56,8 @@
   Stream<String> _stderrLog;
 
   /// A line-by-line view of the standard error stream of the process.
-  StreamIterator<String> _stderr;
+  ScheduledStream<String> get stderr => _stderr;
+  ScheduledStream<String> _stderr;
 
   /// A canceller that controls both [_stderr] and [_stderrLog].
   StreamCanceller _stderrCanceller;
@@ -112,8 +115,8 @@
     _stderrCanceller = stderrWithCanceller.last;
     _stderrLog = stderrWithCanceller.first;
 
-    _stdout = new StreamIterator<String>(stdoutStream());
-    _stderr = new StreamIterator<String>(stderrStream());
+    _stdout = new ScheduledStream<String>(stdoutStream());
+    _stderr = new ScheduledStream<String>(stderrStream());
   }
 
   /// Updates [_description] to reflect [executable] and [arguments], which are
@@ -251,37 +254,6 @@
     }, "cleaning up process '$description'");
   }
 
-  /// Reads the next line of stdout from the process.
-  Future<String> nextLine() => schedule(() => streamIteratorFirst(_stdout),
-      "reading the next stdout line from process '$description'");
-
-  /// Reads the next line of stderr from the process.
-  Future<String> nextErrLine() => schedule(() => streamIteratorFirst(_stderr),
-      "reading the next stderr line from process '$description'");
-
-  /// Reads the remaining stdout from the process. This should only be called
-  /// after kill() or shouldExit().
-  Future<String> remainingStdout() {
-    if (!_endScheduled) {
-      throw new StateError("remainingStdout() should only be called after "
-          "kill() or shouldExit().");
-    }
-    return schedule(() => concatRest(_stdout),
-        "reading the remaining stdout from process '$description'");
-  }
-
-  /// Reads the remaining stderr from the process. This should only be called
-  /// after kill() or shouldExit().
-  Future<String> remainingStderr() {
-    if (!_endScheduled) {
-      throw new StateError("remainingStderr() should only be called after "
-          "kill() or shouldExit().");
-    }
-
-    return schedule(() => concatRest(_stderr),
-        "reading the remaining stderr from process '$description'");
-  }
-
   /// Returns a stream that will emit anything the process emits via the
   /// process's standard output from now on.
   ///
@@ -289,8 +261,7 @@
   /// standard output, including other calls to [stdoutStream].
   ///
   /// This can be overridden by subclasses to return a derived standard output
-  /// stream. This stream will then be used for [nextLine], [nextErrLine],
-  /// [remainingStdout], and [remainingStderr].
+  /// stream. This stream will then be used for [stdout] and [stderr].
   Stream<String> stdoutStream() {
     var pair = tee(_stdoutLog);
     _stdoutLog = pair.first;
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index 6713054..b6ba30d 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -228,7 +228,7 @@
   _test(description, body, unittest.solo_test);
 
 void _test(String description, void body(), Function testFn) {
-  _ensureInitialized();
+  unittest.ensureInitialized();
   _ensureSetUpForTopLevel();
   testFn(description, () {
     var completer = new Completer();
@@ -260,7 +260,7 @@
 /// Creates a new named group of tests. This has the same semantics as
 /// [unittest.group].
 void group(String description, void body()) {
-  _ensureInitialized();
+  unittest.ensureInitialized();
   _ensureSetUpForTopLevel();
   unittest.group(description, () {
     var wasInGroup = _inGroup;
@@ -316,11 +316,22 @@
 void _setUpScheduledTest([void setUpFn()]) {
   if (!_inGroup) {
     _setUpForTopLevel = true;
+    var oldWrapAsync = unittest.wrapAsync;
     unittest.setUp(() {
       if (currentSchedule != null) {
         throw new StateError('There seems to be another scheduled test '
             'still running.');
       }
+
+      unittest.wrapAsync = (f, [description]) {
+        // It's possible that this setup is run before a vanilla unittest test
+        // if [unittest.test] is run in the same context as
+        // [scheduled_test.test]. In that case, [currentSchedule] will never be
+        // set and we should forward to the [unittest.wrapAsync].
+        if (currentSchedule == null) return oldWrapAsync(f, description);
+        return currentSchedule.wrapAsync(f, description);
+      };
+
       if (_setUpFn != null) {
         var parentFn = _setUpFn;
         _setUpFn = () { parentFn(); setUpFn(); };
@@ -330,6 +341,7 @@
     });
 
     unittest.tearDown(() {
+      unittest.wrapAsync = oldWrapAsync;
       _currentSchedule = null;
       _setUpFn = null;
     });
@@ -345,20 +357,6 @@
   }
 }
 
-/// Ensures that the global configuration for `scheduled_test` has been
-/// initialized.
-void _ensureInitialized() {
-  unittest.ensureInitialized();
-  unittest.wrapAsync = (f, [description]) {
-    if (currentSchedule == null) {
-      throw new StateError("Unexpected call to wrapAsync with no current "
-          "schedule.");
-    }
-
-    return currentSchedule.wrapAsync(f, description);
-  };
-}
-
 /// Like [wrapAsync], this ensures that the current task queue waits for
 /// out-of-band asynchronous code, and that errors raised in that code are
 /// handled correctly. However, [wrapFuture] wraps a [Future] chain rather than
diff --git a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
index 515f6e4..25762d6 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
@@ -28,22 +28,22 @@
   /// contents against [matcher]. If the file is created, it's considered to be
   /// empty.
   factory FileDescriptor.matcher(String name, Matcher matcher) =>
-    new _MatcherFileDescriptor(name, matcher, isBinary: false);
+      new _MatcherFileDescriptor(name, matcher, isBinary: false);
 
   /// Creates a new binary [FileDescriptor] with [name] that matches its binary
   /// contents against [matcher]. If the file is created, it's considered to be
   /// empty.
   factory FileDescriptor.binaryMatcher(String name, Matcher matcher) =>
-    new _MatcherFileDescriptor(name, matcher, isBinary: true);
+      new _MatcherFileDescriptor(name, matcher, isBinary: true);
 
   /// Creates a new binary [FileDescriptor] descriptor with [name] and
   /// [contents].
   factory FileDescriptor.binary(String name, List<int> contents) =>
-    new _BinaryFileDescriptor(name, contents);
+      new _BinaryFileDescriptor(name, contents);
 
   /// Creates a new text [FileDescriptor] with [name] and [contents].
   factory FileDescriptor(String name, String contents) =>
-    new _StringFileDescriptor(name, contents);
+      new _StringFileDescriptor(name, contents);
 
   FileDescriptor._(String name, this.contents)
       : super(name);
diff --git a/pkg/scheduled_test/lib/src/stream_matcher.dart b/pkg/scheduled_test/lib/src/stream_matcher.dart
index f1e65da..f230e10 100644
--- a/pkg/scheduled_test/lib/src/stream_matcher.dart
+++ b/pkg/scheduled_test/lib/src/stream_matcher.dart
@@ -64,6 +64,14 @@
 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
 StreamMatcher consumeThrough(matcher) => new _ConsumeThroughMatcher(matcher);
 
+/// A matcher that consumes values emitted by a stream as long as they match
+/// [matcher].
+///
+/// This matcher will always match a stream. It exists to consume values.
+///
+/// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
+StreamMatcher consumeWhile(matcher) => new _ConsumeWhileMatcher(matcher);
+
 /// A matcher that matches either [streamMatcher1], [streamMatcher2], or both.
 ///
 /// If both matchers match the stream, the one that consumed more values will be
@@ -82,6 +90,14 @@
 /// [streamMatcher] can be a [StreamMatcher], a [Matcher], or an [Object].
 StreamMatcher allow(streamMatcher) => new _AllowMatcher(streamMatcher);
 
+/// A matcher that asserts that a stream never emits values matching
+/// [streamMatcher].
+///
+/// This will consume the remainder of a stream.
+///
+/// [streamMatcher] can be a [StreamMatcher], a [Matcher], or an [Object].
+StreamMatcher never(streamMatcher) => new _NeverMatcher(streamMatcher);
+
 /// A matcher that matches a stream that emits no more values.
 StreamMatcher get isDone => new _IsDoneMatcher();
 
@@ -132,8 +148,8 @@
       });
     }
 
-    return collectValues(_n).then((description) {
-      if (description != null) return description;
+    return collectValues(_n).then((failure) {
+      if (failure != null) return failure;
       var matchState = {};
       if (_matcher.matches(collectedValues, matchState)) return null;
       return _matcher.describeMismatch(collectedValues, new StringDescription(),
@@ -162,12 +178,12 @@
     matchNext() {
       if (matchers.isEmpty) return new Future.value();
       var matcher = matchers.removeFirst();
-      return matcher.tryMatch(stream).then((description) {
-        if (description == null) return matchNext();
-        var newDescription = new StringDescription(
+      return matcher.tryMatch(stream).then((failure) {
+        if (failure == null) return matchNext();
+        var newFailure = new StringDescription(
               'matcher #${_matchers.length - matchers.length} failed');
-        if (description.length != 0) newDescription.add(':\n$description');
-        return newDescription;
+        if (failure.length != 0) newFailure.add(':\n$failure');
+        return newFailure;
       });
     }
 
@@ -203,7 +219,35 @@
 
   String toString() {
     return new StringDescription('values followed by ')
-      .addDescriptionOf(_matcher).toString();
+        .addDescriptionOf(_matcher).toString();
+  }
+}
+
+/// See [consumeWhile].
+class _ConsumeWhileMatcher implements StreamMatcher {
+  final Matcher _matcher;
+
+  _ConsumeWhileMatcher(matcher)
+      : _matcher = wrapMatcher(matcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    consumeNext() {
+      return stream.hasNext.then((hasNext) {
+        if (!hasNext) return new Future.value();
+
+        return _peek(stream).then((value) {
+          if (!_matcher.matches(value, {})) return null;
+          return stream.next().then((_) => consumeNext());
+        });
+      });
+    }
+
+    return consumeNext();
+  }
+
+  String toString() {
+    return new StringDescription('any number of ')
+        .addDescriptionOf(_matcher).toString();
   }
 }
 
@@ -223,26 +267,26 @@
     return Future.wait([
       _matcher1.tryMatch(stream1).whenComplete(stream1.close),
       _matcher2.tryMatch(stream2).whenComplete(stream2.close)
-    ]).then((descriptions) {
-      var description1 = descriptions.first;
-      var description2 = descriptions.last;
+    ]).then((failures) {
+      var failure1 = failures.first;
+      var failure2 = failures.last;
 
       // If both matchers matched, use the one that consumed more of the stream.
-      if (description1 == null && description2 == null) {
+      if (failure1 == null && failure2 == null) {
         if (stream1.emittedValues.length >= stream2.emittedValues.length) {
           return _matcher1.tryMatch(stream);
         } else {
           return _matcher2.tryMatch(stream);
         }
-      } else if (description1 == null) {
+      } else if (failure1 == null) {
         return _matcher1.tryMatch(stream);
-      } else if (description2 == null) {
+      } else if (failure2 == null) {
         return _matcher2.tryMatch(stream);
       } else {
         return new StringDescription('both\n')
-            .add(prefixLines(description1.toString(), prefix: '  '))
+            .add(prefixLines(failure1.toString(), prefix: '  '))
             .add('\nand\n')
-            .add(prefixLines(description2.toString(), prefix: '  '))
+            .add(prefixLines(failure2.toString(), prefix: '  '))
             .toString();
       }
     });
@@ -266,8 +310,8 @@
 
   Future<Description> tryMatch(ScheduledStream stream) {
     var fork = stream.fork();
-    return _matcher.tryMatch(fork).whenComplete(fork.close).then((description) {
-      if (description != null) return null;
+    return _matcher.tryMatch(fork).whenComplete(fork.close).then((failure) {
+      if (failure != null) return null;
       return _matcher.tryMatch(stream);
     });
   }
@@ -279,6 +323,38 @@
   }
 }
 
+/// See [never].
+class _NeverMatcher implements StreamMatcher {
+  final StreamMatcher _matcher;
+
+  _NeverMatcher(streamMatcher)
+      : _matcher = new StreamMatcher.wrap(streamMatcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    consumeNext() {
+      return stream.hasNext.then((hasNext) {
+        if (!hasNext) return new Future.value();
+
+        var fork = stream.fork();
+        return _matcher.tryMatch(fork).whenComplete(fork.close)
+            .then((failure) {
+          if (failure != null) {
+            return stream.next().then((_) => consumeNext());
+          }
+
+          return new StringDescription("matched\n")
+              .add(prefixLines(_matcher.toString(), prefix: '  '));
+        });
+      });
+    }
+
+    return consumeNext();
+  }
+
+  String toString() =>
+    'never\n${prefixLines(_matcher.toString(), prefix: '  ')}';
+}
+
 /// See [isDone].
 class _IsDoneMatcher implements StreamMatcher {
   _IsDoneMatcher();
@@ -292,3 +368,10 @@
 
   String toString() => 'is done';
 }
+
+/// Returns a [Future] that completes to the next value emitted by [stream]
+/// without actually consuming that value.
+Future _peek(ScheduledStream stream) {
+  var fork = stream.fork();
+  return fork.next().whenComplete(fork.close);
+}
diff --git a/pkg/scheduled_test/lib/src/substitute_future.dart b/pkg/scheduled_test/lib/src/substitute_future.dart
index 5c91689..6351330 100644
--- a/pkg/scheduled_test/lib/src/substitute_future.dart
+++ b/pkg/scheduled_test/lib/src/substitute_future.dart
@@ -30,7 +30,7 @@
     _completer.future.then(onValue, onError: onError);
   Future<T> whenComplete(action()) => _completer.future.whenComplete(action);
   Future timeout(Duration timeLimit, {void onTimeout()}) =>
-    _completer.future.timeout(timeLimit, onTimeout: onTimeout);
+      _completer.future.timeout(timeLimit, onTimeout: onTimeout);
 
   /// Substitutes [newFuture] for the currently wrapped [Future], which is
   /// returned.
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index 5bd52430..d55f427 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -64,10 +64,10 @@
   final Chain stackChain;
 
   Task(fn(), String description, TaskQueue queue)
-    : this._(fn, description, queue, null, queue.contents.length);
+      : this._(fn, description, queue, null, queue.contents.length);
 
   Task._child(fn(), String description, Task parent)
-    : this._(fn, description, parent.queue, parent, parent.children.length);
+      : this._(fn, description, parent.queue, parent, parent.children.length);
 
   Task._(fn(), this.description, TaskQueue queue, this.parent, this._id)
       : queue = queue,
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index e767e02..b356294 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -17,7 +17,7 @@
 
   String toString() => '($first, $last)';
 
-  bool operator==(other) {
+  bool operator ==(other) {
     if (other is! Pair) return false;
     return other.first == first && other.last == last;
   }
@@ -126,7 +126,7 @@
 /// Returns a [Future] that completes after pumping the event queue [times]
 /// times. By default, this should pump the event queue enough times to allow
 /// any code to run, as long as it's not waiting on some external event.
-Future pumpEventQueue([int times=20]) {
+Future pumpEventQueue([int times = 20]) {
   if (times == 0) return new Future.value();
   // We use a delayed future to allow microtask events to finish. The
   // Future.value or Future() constructors use scheduleMicrotask themselves and
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index 69bbb2c..540a751 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -1,5 +1,5 @@
 name: scheduled_test
-version: 0.9.3-dev
+version: 0.10.0-dev
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
@@ -13,6 +13,6 @@
   http: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <2.0.0"
   stack_trace: ">=0.9.1 <0.10.0"
-  unittest: ">=0.9.0 <0.10.0"
+  unittest: ">=0.9.0 <0.11.0"
 environment:
   sdk: ">=0.8.10+6 <2.0.0"
diff --git a/pkg/scheduled_test/test/descriptor/async_test.dart b/pkg/scheduled_test/test/descriptor/async_test.dart
index 72e7ceb..8c1f80c 100644
--- a/pkg/scheduled_test/test/descriptor/async_test.dart
+++ b/pkg/scheduled_test/test/descriptor/async_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/descriptor.dart' as d;
 import 'package:scheduled_test/scheduled_test.dart';
 
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index c8bc601..13c5a1d 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -137,7 +137,7 @@
 /// an error occurred.
 bool _hasError(Map results) {
   return results['errors'] > 0 || results['uncaughtError'] != null ||
-    (results['passed'] == 0 && results['failed'] == 0);
+      (results['passed'] == 0 && results['failed'] == 0);
 }
 
 /// Returns a string description of the test run descibed by [results].
diff --git a/pkg/scheduled_test/test/scheduled_future_matchers_test.dart b/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
index 1a0c77c..c1cf2d6 100644
--- a/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
+++ b/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 
 import 'metatest.dart';
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index 8ff1533..f7493d0 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -9,6 +9,7 @@
 
 import 'package:path/path.dart' as path;
 import 'package:scheduled_test/scheduled_process.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
 import 'metatest.dart';
@@ -128,16 +129,19 @@
       });
 
       var process = startDartProcess('');
-      expect(process.nextLine(), completion(equals('hello')));
-      expect(process.nextLine(), completion(equals('world')));
+      process.stdout.expect('hello');
+      process.stdout.expect('world');
       process.shouldExit(0);
     });
 
     test('test 2', () {
       expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
       expect(errors.length, anyOf(1, 2));
-      expect(errors[0].error, isStateError);
-      expect(errors[0].error.message, equals("No elements"));
+      expect(errors[0].error, new isInstanceOf<TestFailure>());
+      expect(errors[0].error.message, equals(
+          "Expected: 'hello'\n"
+          " Emitted: \n"
+          "   Which: unexpected end of stream"));
 
       // Whether or not this error appears depends on how quickly the "no
       // elements" error is handled.
@@ -161,171 +165,29 @@
     });
   });
 
-  expectTestsPass("nextLine returns the next line of stdout from the process",
-      () {
+  expectTestsPass("stdout exposes the standard output from the process", () {
     test('test', () {
       var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
-      expect(process.nextLine(), completion(equals('hello')));
-      expect(process.nextLine(), completion(equals('')));
-      expect(process.nextLine(), completion(equals('world')));
-      expect(process.nextLine(), completion(equals('hi')));
+      process.stdout.expect('hello');
+      process.stdout.expect('');
+      process.stdout.expect('world');
+      process.stdout.expect('hi');
+      process.stdout.expect(isDone);
       process.shouldExit(0);
     });
   });
 
-  expectTestsPass("nextLine throws an error if there's no more stdout", () {
-    var errors;
-    test('test 1', () {
-      currentSchedule.onException.schedule(() {
-        errors = currentSchedule.errors;
-      });
-
-      var process = startDartProcess('print("hello");');
-      expect(process.nextLine(), completion(equals('hello')));
-      expect(process.nextLine(), completion(equals('world')));
-      process.shouldExit(0);
-    });
-
-    test('test 2', () {
-      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
-      expect(errors.length, anyOf(1, 2));
-      expect(errors[0].error, isStateError);
-      expect(errors[0].error.message, equals("No elements"));
-
-      // Whether or not this error appears depends on how quickly the "no
-      // elements" error is handled.
-      if (errors.length == 2) {
-        expect(errors[1].error.toString(), matches(r"^Process "
-            r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
-            r"exit code 0\."));
-      }
-    });
-  }, passing: ['test 2']);
-
-  expectTestsPass("nextErrLine returns the next line of stderr from the "
-      "process", () {
+  expectTestsPass("stderr exposes the stderr from the process", () {
     test('test', () {
       var process = startDartProcess(r'''
           stderr.write("hello\n\nworld\n");
           stderr.write("hi");
           ''');
-      expect(process.nextErrLine(), completion(equals('hello')));
-      expect(process.nextErrLine(), completion(equals('')));
-      expect(process.nextErrLine(), completion(equals('world')));
-      expect(process.nextErrLine(), completion(equals('hi')));
-      process.shouldExit(0);
-    });
-  });
-
-  expectTestsPass("nextErrLine throws an error if there's no more stderr", () {
-    var errors;
-    test('test 1', () {
-      currentSchedule.onException.schedule(() {
-        errors = currentSchedule.errors;
-      });
-
-      var process = startDartProcess(r'stderr.write("hello\n");');
-      expect(process.nextErrLine(), completion(equals('hello')));
-      expect(process.nextErrLine(), completion(equals('world')));
-      process.shouldExit(0);
-    });
-
-    test('test 2', () {
-      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
-      expect(errors.length, anyOf(1, 2));
-      expect(errors[0].error, isStateError);
-      expect(errors[0].error.message, equals("No elements"));
-
-      // Whether or not this error appears depends on how quickly the "no
-      // elements" error is handled.
-      if (errors.length == 2) {
-        expect(errors[1].error.toString(), matches(r"^Process "
-            r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
-            r"exit code 0\."));
-      }
-    });
-  }, passing: ['test 2']);
-
-  expectTestsPass("remainingStdout returns all the stdout if it's not consumed "
-      "any other way", () {
-    test('test', () {
-      var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
-      process.shouldExit(0);
-      expect(process.remainingStdout(),
-          completion(equals("hello\n\nworld\nhi")));
-    });
-  });
-
-  expectTestsPass("remainingStdout returns the empty string if there's no "
-      "stdout", () {
-    test('test', () {
-      var process = startDartProcess(r'');
-      process.shouldExit(0);
-      expect(process.remainingStdout(), completion(isEmpty));
-    });
-  });
-
-  expectTestsPass("remainingStdout returns the remaining stdout after the "
-      "lines consumed by nextLine", () {
-    test('test', () {
-      var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
-      expect(process.nextLine(), completion(equals("hello")));
-      expect(process.nextLine(), completion(equals("")));
-      process.shouldExit(0);
-      expect(process.remainingStdout(), completion(equals("world\nhi")));
-    });
-  });
-
-  expectTestsPass("remainingStdout can't be called before the process is "
-      "scheduled to end", () {
-    test('test', () {
-      var process = startDartProcess(r'');
-      expect(process.remainingStdout, throwsA(isStateError));
-      process.shouldExit(0);
-    });
-  });
-
-  expectTestsPass("remainingStderr returns all the stderr if it's not consumed "
-      "any other way", () {
-    test('test', () {
-      var process = startDartProcess(r'''
-          stderr.write("hello\n\nworld\n");
-          stderr.write("hi\n");
-          ''');
-      process.shouldExit(0);
-      expect(process.remainingStderr(),
-          completion(equals("hello\n\nworld\nhi")));
-    });
-  });
-
-  expectTestsPass("remainingStderr returns the empty string if there's no "
-      "stderr", () {
-    test('test', () {
-      var process = startDartProcess(r'');
-      process.shouldExit(0);
-      expect(process.remainingStderr(), completion(isEmpty));
-    });
-  });
-
-  expectTestsPass("remainingStderr returns the remaining stderr after the "
-      "lines consumed by nextLine", () {
-    test('test', () {
-      var process = startDartProcess(r'''
-          stderr.write("hello\n\nworld\n");
-          stderr.write("hi\n");
-          ''');
-      expect(process.nextErrLine(), completion(equals("hello")));
-      expect(process.nextErrLine(), completion(equals("")));
-      process.shouldExit(0);
-      expect(process.remainingStderr(), completion(equals("world\nhi")));
-    });
-  });
-
-  expectTestsPass("remainingStderr can't be called before the process is "
-      "scheduled to end", () {
-    test('test', () {
-      var process = startDartProcess(r'');
-      expect(process.remainingStderr, throwsA(isStateError));
+      process.stderr.expect('hello');
+      process.stderr.expect('');
+      process.stderr.expect('world');
+      process.stderr.expect('hi');
+      process.stderr.expect(isDone);
       process.shouldExit(0);
     });
   });
@@ -337,9 +199,9 @@
           stdinLines.listen((line) => print("> $line"));
           ''');
       process.writeLine("hello");
-      expect(process.nextLine(), completion(equals("> hello")));
+      process.stdout.expect("> hello");
       process.writeLine("world");
-      expect(process.nextLine(), completion(equals("> world")));
+      process.stdout.expect("> world");
       process.kill();
     });
   });
@@ -352,7 +214,7 @@
           ''');
       process.closeStdin();
       process.shouldExit(0);
-      expect(process.nextLine(), completion(equals('stdin closed')));
+      process.stdout.expect('stdin closed');
     });
   });
 }
diff --git a/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart b/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart
index b08fc37..93c6b43 100644
--- a/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart
+++ b/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart
@@ -208,6 +208,20 @@
         "   Which: unexpected end of stream"));
   });
 
+  expectTestPasses("consumeWhile() consumes values while the given matcher "
+      "matches", () {
+    var stream = createStream();
+    stream.expect(consumeWhile(lessThan(4)));
+    stream.expect(4);
+  });
+
+  expectTestPasses("consumeWhile() will stop if the first value doesn't match",
+      () {
+    var stream = createStream();
+    stream.expect(consumeWhile(2));
+    stream.expect(1);
+  });
+
   expectTestPasses("either() will match if the first branch matches", () {
     createStream().expect(either(1, 100));
   });
@@ -264,6 +278,29 @@
     stream.expect(1);
   });
 
+  expectTestPasses("never() consumes everything if the matcher never matches",
+      () {
+    var stream = createStream();
+    stream.expect(never(inOrder([2, 1])));
+  });
+
+  expectTestFails("never() fails if the matcher matches", () {
+    var stream = createStream();
+    stream.expect(never(inOrder([2, 3])));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: never\n"
+        "        |   * <2>\n"
+        "        |   * <3>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "   Which: matched\n"
+        "        |   * <2>\n"
+        "        |   * <3>"));
+  });
+
   expectTestPasses("isDone succeeds at the end of the stream", () {
     var stream = createStream();
     stream.expect(consumeThrough(5));
diff --git a/pkg/scheduled_test/test/scheduled_test/abort_test.dart b/pkg/scheduled_test/test/scheduled_test/abort_test.dart
index fc4622c..aeaf19a 100644
--- a/pkg/scheduled_test/test/scheduled_test/abort_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/abort_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../metatest.dart';
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
index 97f2d19..ab45c2c 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../metatest.dart';
@@ -66,4 +64,4 @@
       expect(currentSchedule.currentQueue.name, equals('tasks'));
     });
   });
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
index a3648f1..048745d 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
index 0c4f587..676e5e1 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
@@ -40,4 +40,4 @@
       expect(oldSchedule.state, equals(ScheduleState.DONE));
     });
   });
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
index 1356b80..7612db1 100644
--- a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart b/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
index b603456..4715010 100644
--- a/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../metatest.dart';
@@ -160,4 +158,4 @@
       });
     });
   });
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart b/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
index 890b8fa..5e45613 100644
--- a/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../metatest.dart';
@@ -76,4 +74,4 @@
       expect(onExceptionRun, isTrue);
     });
   }, passing: ['test 2']);
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart b/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
index dec4a7c..ad443e4 100644
--- a/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart b/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
index e9b6476..25bf0e7 100644
--- a/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/simple_test.dart b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
index 00ab216..6626526 100644
--- a/pkg/scheduled_test/test/scheduled_test/simple_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
@@ -121,4 +121,4 @@
       }));
     });
   });
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart b/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
index ae7ddb1..d5130a4 100644
--- a/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/timeout_test.dart b/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
index 0328d73..ac9faac 100644
--- a/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/unhandled_error_test.dart b/pkg/scheduled_test/test/scheduled_test/unhandled_error_test.dart
index aaf87f3..171edb2 100644
--- a/pkg/scheduled_test/test/scheduled_test/unhandled_error_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/unhandled_error_test.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 
 import 'package:scheduled_test/scheduled_test.dart';
-import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
 import '../metatest.dart';
 import '../utils.dart';
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
index 6e89962..f873109 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
index 307cba5..077aeb4 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
 
diff --git a/pkg/scheduled_test/test/unittest_compatibility_test.dart b/pkg/scheduled_test/test/unittest_compatibility_test.dart
new file mode 100644
index 0000000..1dc8988
--- /dev/null
+++ b/pkg/scheduled_test/test/unittest_compatibility_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// This isn't a common use-case, but we want to make sure scheduled_test doesn't
+// step on unittest's toes too much.
+import 'dart:async';
+
+import 'package:scheduled_test/scheduled_test.dart' as scheduled_test;
+import 'package:unittest/unittest.dart' as unittest;
+
+void main() {
+  scheduled_test.test('scheduled_test throws', () {
+    scheduled_test.expect(new Future.error('foo'),
+        scheduled_test.throwsA('foo'));
+  });
+
+  unittest.test('unittest throws', () {
+    // We test a future matcher because scheduled_test modifies some of
+    // unittest's asynchrony infrastructure.
+    unittest.expect(new Future.error('foo'), unittest.throwsA('foo'));
+  });
+}
diff --git a/pkg/smoke/AUTHORS b/pkg/smoke/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/smoke/AUTHORS
@@ -0,0 +1,9 @@
+# Names should be added to this file with this pattern:
+#
+# For individuals:
+#   Name <email address>
+#
+# For organizations:
+#   Organization <fnmatch pattern>
+#
+Google Inc. <*@google.com>
diff --git a/pkg/smoke/CHANGELOG.md b/pkg/smoke/CHANGELOG.md
new file mode 100644
index 0000000..3ceed16
--- /dev/null
+++ b/pkg/smoke/CHANGELOG.md
@@ -0,0 +1,6 @@
+# changelog
+
+This file contains highlights of what changes on each version of this package.
+
+#### Pub version 0.1.0-dev
+  * First version of this package. Initial API and mirror based implementation.
diff --git a/pkg/smoke/LICENSE b/pkg/smoke/LICENSE
new file mode 100644
index 0000000..95987ba
--- /dev/null
+++ b/pkg/smoke/LICENSE
@@ -0,0 +1,27 @@
+// Copyright (c) 2014 The Polymer Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/smoke/PATENTS b/pkg/smoke/PATENTS
new file mode 100644
index 0000000..e120963
--- /dev/null
+++ b/pkg/smoke/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Polymer project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Polymer, where such license applies only to those
+patent claims, both currently owned or controlled by Google and acquired
+in the future, licensable by Google that are necessarily infringed by
+this implementation of Polymer.  This grant does not include claims
+that would be infringed only as a consequence of further modification of
+this implementation.  If you or your agent or exclusive licensee
+institute or order or agree to the institution of patent litigation
+against any entity (including a cross-claim or counterclaim in a
+lawsuit) alleging that this implementation of Polymer or any code
+incorporated within this implementation of Polymer constitutes
+direct or contributory patent infringement, or inducement of patent
+infringement, then any patent rights granted to you under this License
+for this implementation of Polymer shall terminate as of the date
+such litigation is filed.
diff --git a/pkg/smoke/README.md b/pkg/smoke/README.md
new file mode 100644
index 0000000..1889574
--- /dev/null
+++ b/pkg/smoke/README.md
@@ -0,0 +1,37 @@
+Smoke (and mirrors)
+===================
+
+Smoke is a package that exposes a reduced reflective system API. This API
+includes accessing objects in a dynamic fashion (read properties, write
+properties, and call methods), inspecting types (for example, whether a
+method exists), and symbol/string convertion.
+
+The package provides a default implementation of this API that uses the system's
+mirrors, but additionally provides mechanisms for statically generating code
+that can replace the mirror-based implementation.
+
+The intention of this package is to allow frameworks to use mirrors in a way
+that will not impose on their users. The idea is that users will not worry about
+how to preserve symbols when compiling with dart2js (for instance, using the
+[MirrorsUsed][] annotation). Instead, this package provides the building
+blocks to autogenerate whatever is needed for dart2js to be happy and to
+generate reasonable code.
+
+Note this package alone doesn't know how to generate everything, but it provides
+a simple API that different frameworks can use to define what needs to be
+generated.
+
+
+Smoke reflective API
+====================
+
+Use `package:smoke/smoke.dart` in your framework to read and write objects and
+to inspect type information. Read the Dart-docs for more details.
+
+Code Generation
+===============
+
+TBD. We envision we'll have a base transformer class that can be tailored to
+create a transformer for your framework.
+
+[MirrorsUsed]: https://api.dartlang.org/apidocs/channels/stable/#dart-mirrors.MirrorsUsed
diff --git a/pkg/smoke/lib/mirrors.dart b/pkg/smoke/lib/mirrors.dart
new file mode 100644
index 0000000..4048aae
--- /dev/null
+++ b/pkg/smoke/lib/mirrors.dart
@@ -0,0 +1,333 @@
+// 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.
+
+/// Implementation of the smoke services using mirrors.
+library smoke.mirrors;
+
+import 'dart:mirrors';
+import 'package:smoke/smoke.dart';
+import 'package:logging/logging.dart';
+import 'src/common.dart';
+
+/// Set up the smoke package to use a mirror-based implementation. To tune what
+/// is preserved by `dart:mirrors`, use a @MirrorsUsed annotation and include
+/// 'smoke.mirrors' in your override arguments.
+useMirrors() {
+  configure(new ReflectiveObjectAccessorService(),
+      new ReflectiveTypeInspectorService(),
+      new ReflectiveSymbolConverterService());
+}
+
+var _logger = new Logger('smoke.mirrors');
+
+
+/// Implements [ObjectAccessorService] using mirrors.
+class ReflectiveObjectAccessorService implements ObjectAccessorService {
+  read(Object object, Symbol name) {
+    var decl = getDeclaration(object.runtimeType, name);
+    if (decl != null && decl.isMethod) {
+      // TODO(sigmund,jmesserly): remove this once dartbug.com/13002 is fixed.
+      return new _MethodClosure(object, name);
+    } else {
+      return reflect(object).getField(name).reflectee;
+    }
+  }
+
+  void write(Object object, Symbol name, value) {
+    reflect(object).setField(name, value);
+  }
+
+  invoke(receiver, Symbol methodName, List args,
+      {Map namedArgs, bool adjust: false}) {
+    var receiverMirror;
+    var method;
+    if (receiver is Type) {
+      receiverMirror = reflectType(receiver);
+      method = receiverMirror.declarations[methodName];
+    } else {
+      receiverMirror = reflect(receiver);
+      method = _findMethod(receiverMirror.type, methodName);
+    }
+    if (method != null && adjust) {
+      var required = 0;
+      var optional = 0;
+      for (var p in method.parameters) {
+        if (p.isOptional) {
+          if (!p.isNamed) optional++;
+        } else {
+          required++;
+        }
+      }
+      args = adjustList(args, required, required + optional);
+    }
+    return receiverMirror.invoke(methodName, args, namedArgs).reflectee;
+  }
+}
+
+/// Implements [TypeInspectorService] using mirrors.
+class ReflectiveTypeInspectorService implements TypeInspectorService {
+  bool isSubclassOf(Type type, Type supertype) {
+    if (type == supertype || supertype == Object) return true;
+    // TODO(sigmund): change to mirror.isSubclassOf when it gets implemented in
+    // dart2js. (dartbug.com/12439)
+    var mirror = reflectClass(type);
+    var top = reflectClass(supertype);
+    while (mirror != _objectType) {
+      mirror = _safeSuperclass(mirror);
+      if (mirror == top) return true;
+    }
+    return false;
+  }
+
+  bool hasGetter(Type type, Symbol name) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return false;
+    while (mirror != _objectType) {
+      final members = mirror.declarations;
+      if (members.containsKey(name)) return true;
+      mirror = _safeSuperclass(mirror);
+    }
+    return false;
+  }
+
+  bool hasSetter(Type type, Symbol name) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return false;
+    var setterName = _setterName(name);
+    while (mirror != _objectType) {
+      final members = mirror.declarations;
+      var declaration = members[name];
+      if (declaration is VariableMirror && !declaration.isFinal) return true;
+      if (members.containsKey(setterName)) return true;
+      mirror = _safeSuperclass(mirror);
+    }
+    return false;
+  }
+
+  bool hasInstanceMethod(Type type, Symbol name) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return false;
+    while (mirror != _objectType) {
+      final m = mirror.declarations[name];
+      if (m is MethodMirror && m.isRegularMethod && !m.isStatic) return true;
+      mirror = _safeSuperclass(mirror);
+    }
+    return false;
+  }
+
+  bool hasStaticMethod(Type type, Symbol name) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return false;
+    final m = mirror.declarations[name];
+    return m is MethodMirror && m.isRegularMethod && m.isStatic;
+  }
+
+  Declaration getDeclaration(Type type, Symbol name) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return null;
+
+    var declaration;
+    while (mirror != _objectType) {
+      final members = mirror.declarations;
+      if (members.containsKey(name)) {
+        declaration = members[name];
+        break;
+      }
+      mirror = _safeSuperclass(mirror);
+    }
+    if (declaration == null) {
+      _logger.severe("declaration doesn't exists ($type.$name).");
+      return null;
+    }
+    return new _MirrorDeclaration(mirror, declaration);
+  }
+
+  List<Declaration> query(Type type, QueryOptions options) {
+    var mirror = reflectType(type);
+    if (mirror is! ClassMirror) return null;
+    return _query(mirror, options);
+  }
+
+  List<Declaration> _query(ClassMirror cls, QueryOptions options) {
+    final visitParent = options.includeInherited && cls.superclass != null && 
+        // TODO(sigmund): use _toType(cls.superclass) != options.includeUpTo
+        // when dartbug.com/16925 gets fixed (_toType fails in dart2js if
+        // applied to classes with type-arguments).
+        cls.superclass != reflectClass(options.includeUpTo);
+    var result = visitParent ? _query(cls.superclass, options) : [];
+    for (var member in cls.declarations.values) {
+      if (member is! VariableMirror && member is! MethodMirror) continue;
+      if (member.isStatic || member.isPrivate) continue;
+      var name = member.simpleName;
+      bool isMethod = false;
+      if (member is VariableMirror) {
+        if (!options.includeFields) continue;
+        if (options.excludeFinal && member.isFinal) continue;
+      }
+
+      // TODO(sigmund): what if we have a setter but no getter?
+      if (member is MethodMirror && member.isSetter) continue;
+      if (member is MethodMirror && member.isConstructor) continue;
+
+      if (member is MethodMirror && member.isGetter) {
+        if (!options.includeProperties) continue;
+        if (options.excludeFinal && !_hasSetter(cls, member)) continue;
+      }
+
+      if (member is MethodMirror && member.isRegularMethod) {
+        if (!options.includeMethods) continue;
+        isMethod = true;
+      }
+
+      var annotations =
+          member.metadata.map((m) => m.reflectee).toList();
+      if (options.withAnnotations != null &&
+          !matchesAnnotation(annotations, options.withAnnotations)) {
+        continue;
+      }
+
+      // TODO(sigmund): should we cache parts of this declaration so we don't
+      // compute them twice?  For example, this chould be `new Declaration(name,
+      // type, ...)` and we could reuse what we computed above to implement the
+      // query filtering.  Note, when I tried to eagerly compute everything, I
+      // run into trouble with type (`type = _toType(member.type)`), dart2js
+      // failed when the underlying types had type-arguments (see
+      // dartbug.com/16925).
+      result.add(new _MirrorDeclaration(cls, member));
+    }
+
+    return result;
+  }
+}
+
+/// Implements [SymbolConverterService] using mirrors.
+class ReflectiveSymbolConverterService implements SymbolConverterService {
+  String symbolToName(Symbol symbol) => MirrorSystem.getName(symbol);
+  Symbol nameToSymbol(String name) => new Symbol(name);
+}
+
+
+// TODO(jmesserly): workaround for:
+// https://code.google.com/p/dart/issues/detail?id=10029
+Symbol _setterName(Symbol getter) =>
+    new Symbol('${MirrorSystem.getName(getter)}=');
+
+
+ClassMirror _safeSuperclass(ClassMirror type) {
+  try {
+    return type.superclass;
+  } on UnsupportedError catch (e) {
+    // Note: dart2js throws UnsupportedError when the type is not reflectable.
+    return _objectType;
+  }
+}
+
+MethodMirror _findMethod(ClassMirror type, Symbol name) {
+  do {
+    var member = type.declarations[name];
+    if (member is MethodMirror) return member;
+    type = type.superclass;
+  } while (type != null);
+}
+
+// When recursively looking for symbols up the type-hierarchy it's generally a
+// good idea to stop at Object, since we know it doesn't have what we want.
+// TODO(jmesserly): This is also a workaround for what appears to be a V8
+// bug introduced between Chrome 31 and 32. After 32
+// JsClassMirror.declarations on Object calls
+// JsClassMirror.typeVariables, which tries to get the _jsConstructor's
+// .prototype["<>"]. This ends up getting the "" property instead, maybe
+// because "<>" doesn't exist, and gets ";" which then blows up because
+// the code later on expects a List of ints.
+final _objectType = reflectClass(Object);
+
+bool _hasSetter(ClassMirror cls, MethodMirror getter) {
+  var mirror = cls.declarations[_setterName(getter.simpleName)];
+  return mirror is MethodMirror && mirror.isSetter;
+}
+
+Type _toType(TypeMirror t) {
+  // TODO(sigmund): this line can go away after dartbug.com/16962
+  if (t == _objectType) return Object;
+  if (t is ClassMirror) return t.reflectedType;
+  if (t == null || t.qualifiedName != #dynamic) {
+    _logger.warning('unknown type ($t).');
+  }
+  return dynamic;
+}
+
+class _MirrorDeclaration implements Declaration {
+  final ClassMirror _cls;
+  final _original;
+
+  _MirrorDeclaration(this._cls, DeclarationMirror this._original);
+
+  Symbol get name => _original.simpleName;
+
+  DeclarationKind get kind => isField ? FIELD : isProperty ? PROPERTY : METHOD;
+
+  bool get isField => _original is VariableMirror;
+
+  bool get isProperty =>
+      _original is MethodMirror && !_original.isRegularMethod;
+
+  bool get isMethod => !isField && !isProperty;
+
+  /// If this is a property, whether it's read only (final fields or properties
+  /// with no setter).
+  bool get isFinal =>
+      (_original is VariableMirror && _original.isFinal) ||
+      (_original is MethodMirror && _original.isGetter &&
+           !_hasSetter(_cls, _original));
+
+  /// If this is a property, it's declared type (including dynamic if it's not
+  /// declared). For methods, the returned type.
+  Type get type {
+    if (_original is MethodMirror && _original.isRegularMethod) {
+      return Function;
+    }
+    var typeMirror = _original is VariableMirror ? _original.type
+        : _original.returnType;
+    return _toType(typeMirror);
+  }
+
+  /// Whether this symbol is static.
+  bool get isStatic => _original.isStatic;
+
+  /// List of annotations in this declaration.
+  List get annotations => _original.metadata.map((a) => a.reflectee).toList();
+
+  String toString() {
+    return (new StringBuffer()
+        ..write('[declaration ')
+        ..write(name)
+        ..write(isField ? ' (field) '
+            : (isProperty ? ' (property) ' : ' (method) '))
+        ..write(isFinal ? 'final ' : '')
+        ..write(isStatic ? 'static ' : '')
+        ..write(annotations)
+        ..write(']')).toString();
+  }
+}
+
+class _MethodClosure extends Function {
+  final receiver;
+  final Symbol methodName;
+
+  _MethodClosure(this.receiver, this.methodName);
+
+  // Technically we could just use noSuchMethod to implement [call], but we
+  // don't for 3 reasons:
+  //   * noSuchMethod makes the code a lot bigger.
+  //   * even with noSuchMethod, an analyzer bug requires to declare [call] (see
+  //     dartbug.com/16078).
+  //   * having [call] also allows `is` checks to work for functions of 0
+  //     through 3 arguments.  We depend on this in
+  //     `polymer_expressions/lib/eval.dart` to check whether a function is a
+  //     filter (takes a single argument). (Note that it's possible to include
+  //     both [call] and [noSuchMethod], which would make instance-of checks
+  //     work with the signature of [call], but will allow invoking the function
+  //     using [noSuchMethod].
+  call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true);
+}
diff --git a/pkg/smoke/lib/smoke.dart b/pkg/smoke/lib/smoke.dart
new file mode 100644
index 0000000..9d47a3a
--- /dev/null
+++ b/pkg/smoke/lib/smoke.dart
@@ -0,0 +1,246 @@
+// 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.
+
+/// Collects services that can be used to access objects dynamically, inspect
+/// type information, and convert between symbols and strings.
+library smoke;
+
+import 'src/implementation.dart' as implementation;
+
+export 'src/common.dart' show minArgs, maxArgs, SUPPORTED_ARGS;
+
+/// Configures this library to use [objectAccessor] for all read/write/invoke
+/// APIs, [typeInspector] for all type query APIs, and [symbolConverter] for all
+/// symbol convertion operations.
+///
+/// This function doesn't need to be called during development, but frameworks
+/// should autogenerate a call to this function when running in deployment.
+void configure(ObjectAccessorService objectAccessor,
+    TypeInspectorService typeInspector,
+    SymbolConverterService symbolConverter) {
+  implementation.objectAccessor = objectAccessor;
+  implementation.typeInspector = typeInspector;
+  implementation.symbolConverter = symbolConverter;
+}
+
+/// Return the value of [field] in [object].
+read(Object object, Symbol field) =>
+    implementation.objectAccessor.read(object, field);
+
+/// Update the [value] of [field] in [object].
+void write(Object object, Symbol field, value) =>
+    implementation.objectAccessor.write(object, field, value);
+
+/// Invoke [method] in [receiver] with [args]. The [receiver] can be either an
+/// object (to invoke instance methods) or a type (to invoke static methods).
+/// This function optionally [adjust]s the list of arguments to match the number
+/// of formal parameters by either adding nulls for missing arguments, or by
+/// truncating the list.
+invoke(receiver, Symbol method, List args,
+    {Map namedArgs, bool adjust: false}) =>
+    implementation.objectAccessor.invoke(
+        receiver, method, args, namedArgs: namedArgs, adjust: adjust);
+
+/// Tells whether [type] is transitively a subclass of [supertype].
+bool isSubclassOf(Type type, Type supertype) =>
+    implementation.typeInspector.isSubclassOf(type, supertype);
+
+// TODO(sigmund): consider adding also:
+// * isImplementationOf(type, subtype) to tells whether [type] declares that it
+//   implements the [supertype] interface.
+// * isSubtypeOf(type, subtype): Tells whether [type]'s interface is a sybtype
+//   of [supertype]. That is, whether it is a subclass or if [type] implements
+//   [supertype].
+
+/// Tells whether [type] has a field or getter for [field].
+bool hasGetter(Type type, Symbol field) =>
+    implementation.typeInspector.hasGetter(type, field);
+
+/// Tells whether [type] has a field or setter for [field].
+bool hasSetter(Type type, Symbol field) =>
+    implementation.typeInspector.hasSetter(type, field);
+
+/// Tells whether [type] or a superclass (other than [Object]) defines
+/// `noSuchMethod`.
+bool hasNoSuchMethod(Type type) => hasInstanceMethod(type, #noSuchMethod);
+
+/// Tells whether [type] has or a superclass contains a specific instance
+/// [method] (excluding methods in [Object]).
+bool hasInstanceMethod(Type type, Symbol method) =>
+    implementation.typeInspector.hasInstanceMethod(type, method);
+
+/// Tells whether [type] has a specific static [method].
+bool hasStaticMethod(Type type, Symbol method) =>
+    implementation.typeInspector.hasStaticMethod(type, method);
+
+/// Get the declaration associated with field [name] found in [type] or a
+/// superclass of [type].
+Declaration getDeclaration(Type type, Symbol name) =>
+    implementation.typeInspector.getDeclaration(type, name);
+
+/// Retrieve all symbols of [type] that match [options].
+List<Declaration> query(Type type, QueryOptions options) =>
+    implementation.typeInspector.query(type, options);
+
+/// Returns the name associated with a [symbol].
+String symbolToName(Symbol symbol) =>
+    implementation.symbolConverter.symbolToName(symbol);
+
+/// Returns the symbol associated with a [name].
+Symbol nameToSymbol(String name) =>
+    implementation.symbolConverter.nameToSymbol(name);
+
+/// Establishes the parameters for [query] to search for symbols in a type
+/// hierarchy. For now only public instance symbols can be queried (no private,
+/// no static).
+class QueryOptions {
+  /// Whether to include fields (default is true).
+  final bool includeFields;
+
+  /// Whether to include getters and setters (default is true). Note that to
+  /// include fields you also need to enable [includeFields].
+  final bool includeProperties;
+
+  /// Whether to include symbols from the given type and its superclasses
+  /// (except [Object]).
+  final bool includeInherited;
+
+  /// If [includeInherited], walk up the type hierarchy up to this type
+  /// (defaults to [Object]).
+  final Type includeUpTo;
+
+  /// Whether to include final fields and getter-only properties.
+  final bool excludeFinal;
+
+  /// Whether to include methods (default is false).
+  final bool includeMethods;
+
+  /// If [withAnnotation] is not null, then it should be a list of types, so
+  /// only symbols that are annotated with instances of those types are
+  /// included.
+  final List withAnnotations;
+
+  const QueryOptions({
+      this.includeFields: true,
+      this.includeProperties: true,
+      this.includeInherited: true,
+      this.includeUpTo: Object,
+      this.excludeFinal: false,
+      this.includeMethods: false,
+      this.withAnnotations: null});
+}
+
+/// Information associated with a symbol declaration (like a property or
+/// method).
+class Declaration {
+  /// Name of the property or method
+  final Symbol name;
+
+  /// Kind of declaration (field, property, or method).
+  final DeclarationKind kind;
+
+  /// Whether the symbol is a field (and not a getter/setter property).
+  bool get isField => kind == FIELD;
+
+  /// Whether the symbol is a getter/setter and not a field.
+  bool get isProperty => kind == PROPERTY;
+
+  /// Whether the symbol is a method.
+  bool get isMethod => kind == METHOD;
+
+  /// For fields, whether they are final, for properties, whether they are
+  /// read-only (they have no setter).
+  final bool isFinal;
+
+  /// If this is a field or property, it's declared type (including dynamic if
+  /// it's not declared). For methods, the returned type.
+  final Type type;
+
+  /// Whether this symbol is static.
+  final bool isStatic;
+
+  /// List of annotations in this declaration.
+  final List annotations;
+
+  const Declaration(this.name, this.type, {this.kind: FIELD,
+      this.isFinal: false, this.isStatic: false, this.annotations: const []});
+
+  String toString() {
+    return (new StringBuffer()
+        ..write('[declaration ')
+        ..write(name)
+        ..write(isProperty ? ' (property) ' : ' (method) ')
+        ..write(isFinal ? 'final ' : '')
+        ..write(isStatic ? 'static ' : '')
+        ..write(annotations)
+        ..write(']')).toString();
+  }
+}
+
+/// Enumeration for declaration kinds (field, property, or method)
+class DeclarationKind {
+  final int kind;
+  const DeclarationKind(this.kind);
+}
+
+/// Declaration kind used to denote a raw field.
+const FIELD = const DeclarationKind(0);
+
+/// Declaration kind used to denote a getter/setter.
+const PROPERTY = const DeclarationKind(1);
+
+/// Declaration kind used to denote a method.
+const METHOD = const DeclarationKind(2);
+
+
+/// A service that provides a way to implement simple operations on objects like
+/// read, write, and invoke.
+abstract class ObjectAccessorService {
+  /// Return the value of [field] in [object].
+  read(Object object, Symbol field);
+
+  /// Update the [value] of [field] in [object].
+  void write(Object object, Symbol field, value);
+
+  /// Invoke [method] in [object] with [args]. It optionally [adjust]s the list
+  /// of arguments to match the number of formal parameters by either adding
+  /// nulls for missing arguments, or by truncating the list.
+  invoke(Object object, Symbol method, List args,
+      {Map namedArgs, bool adjust: false});
+}
+
+
+/// A service that provides partial inspection into Dart types.
+abstract class TypeInspectorService {
+  /// Tells whether [type] is transitively a subclass of [supertype].
+  bool isSubclassOf(Type type, Type supertype);
+
+  /// Tells whether [type] has a field or getter for [name].
+  bool hasGetter(Type type, Symbol name);
+
+  /// Tells whether [type] has a field or setter for [name].
+  bool hasSetter(Type type, Symbol name);
+
+  /// Tells whether [type] has a specific instance [method].
+  bool hasInstanceMethod(Type type, Symbol method);
+
+  /// Tells whether [type] has a specific static [method].
+  bool hasStaticMethod(Type type, Symbol method);
+
+  /// Get the declaration associated with field [name] in [type].
+  Declaration getDeclaration(Type type, Symbol name);
+
+  /// Retrieve all symbols of [type] that match [options].
+  List<Declaration> query(Type type, QueryOptions options);
+}
+
+
+/// A service that converts between [Symbol]s and [String]s. 
+abstract class SymbolConverterService {
+  /// Returns the name associated with a [symbol].
+  String symbolToName(Symbol symbol);
+
+  /// Returns the symbol associated with a [name].
+  Symbol nameToSymbol(String name);
+}
diff --git a/pkg/smoke/lib/src/common.dart b/pkg/smoke/lib/src/common.dart
new file mode 100644
index 0000000..2f0f9b4e
--- /dev/null
+++ b/pkg/smoke/lib/src/common.dart
@@ -0,0 +1,79 @@
+// 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.
+
+/// Some common utilities used by other libraries in this package.
+library smoke.src.common;
+
+import 'package:smoke/smoke.dart' as smoke show isSubclassOf;
+
+/// Returns [input] adjusted to be within [min] and [max] length. Truncating it
+/// if it's longer, or padding it with nulls if it's shorter. The returned list
+/// is a new copy if any modification is needed, otherwise [input] is returned.
+List adjustList(List input, int min, int max) {
+  if (input.length < min) {
+    return new List(min)..setRange(0, input.length, input);
+  }
+
+  if (input.length > max) {
+    return new List(max)..setRange(0, max, input);
+  }
+  return input;
+}
+
+/// Returns whether [metadata] contains any annotation that is either equal to
+/// an annotation in [queryAnnotations] or whose type is listed in
+/// [queryAnnotations].
+bool matchesAnnotation(Iterable metadata, Iterable queryAnnotations) {
+  for (var meta in metadata) {
+    for (var queryMeta in queryAnnotations) {
+      if (meta == queryMeta) return true;
+      if (queryMeta is Type &&
+          smoke.isSubclassOf(meta.runtimeType, queryMeta)) return true;
+    }
+  }
+  return false;
+}
+
+/// Number of arguments supported by [minArgs] and [maxArgs].
+const SUPPORTED_ARGS = 3;
+
+typedef _Func0();
+typedef _Func1(a);
+typedef _Func2(a, b);
+typedef _Func3(a, b, c);
+
+/// Returns the minimum number of arguments that [f] takes as input, in other
+/// words, the total number of required arguments of [f]. If [f] expects more
+/// than [SUPPORTED_ARGS], this function returns `SUPPORTED_ARGS + 1`.
+/// 
+/// For instance, the current implementation only supports calculating the
+/// number of arguments between `0` and `3`. If the function takes `4` or more,
+/// this function automatically returns `4`.
+int minArgs(Function f) {
+  if (f is _Func0) return 0;
+  if (f is _Func1) return 1;
+  if (f is _Func2) return 2;
+  if (f is _Func3) return 3;
+  return SUPPORTED_ARGS + 1;
+}
+
+/// Returns the maximum number of arguments that [f] takes as input, which is
+/// the total number of required and optional arguments of [f]. If
+/// [f] may take more than [SUPPORTED_ARGS] required arguments, this function
+/// returns `-1`. However, if it takes less required arguments, but more than
+/// [SUPPORTED_ARGS] arguments including optional arguments, the result will be
+/// [SUPPORTED_ARGS].
+///
+/// For instance, the current implementation only supports calculating the
+/// number of arguments between `0` and `3`.  If the function takes `4`
+/// mandatory arguments, this function returns `-1`, but if the funtion takes
+/// `2` mandatory arguments and 10 optional arguments, this function returns
+/// `3`.
+int maxArgs(Function f) {
+  if (f is _Func3) return 3;
+  if (f is _Func2) return 2;
+  if (f is _Func1) return 1;
+  if (f is _Func0) return 0;
+  return -1;
+}
diff --git a/pkg/smoke/lib/src/default_transformer.dart b/pkg/smoke/lib/src/default_transformer.dart
new file mode 100644
index 0000000..49962a9
--- /dev/null
+++ b/pkg/smoke/lib/src/default_transformer.dart
@@ -0,0 +1,39 @@
+// 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.
+
+/// Transformer that replaces the default mirror-based implementation of smoke,
+/// so that during deploy smoke doesn't include any dependency on dart:mirrors.
+library smoke.src.default_transformer;
+
+import 'dart:async';
+import 'package:barback/barback.dart';
+
+/// Replaces the default mirror-based implementation of smoke in
+/// `pacakge:smoke/implementation.dart`, so that during deploy smoke doesn't
+/// include any dependency on dart:mirrors.
+// TODO(sigmund): include tests that run this transformation automatically.
+class DefaultTransformer extends Transformer {
+  DefaultTransformer.asPlugin();
+
+  /// Only apply to `lib/src/implementation.dart`.
+  Future<bool> isPrimary(Asset input) => new Future.value(
+      input.id.package == 'smoke' &&
+      input.id.path == 'lib/src/implementation.dart');
+
+  Future apply(Transform transform) {
+    var id = transform.primaryInput.id;
+    return transform.primaryInput.readAsString().then((code) {
+      // Note: this rewrite is highly-coupled with how implementation.dart is
+      // written. Make sure both are updated in sync.
+      transform.addOutput(new Asset.fromString(id, code
+          .replaceAll(new RegExp('new Reflective[^;]*;'),
+              'throwNotConfiguredError();')
+          .replaceAll("import 'package:smoke/mirrors.dart';", '')));
+    });
+  }
+}
+
+/** Transformer phases which should be applied to the smoke package. */
+List<List<Transformer>> get phasesForSmoke =>
+    [[new DefaultTransformer.asPlugin()]];
diff --git a/pkg/smoke/lib/src/implementation.dart b/pkg/smoke/lib/src/implementation.dart
new file mode 100644
index 0000000..687a0f3
--- /dev/null
+++ b/pkg/smoke/lib/src/implementation.dart
@@ -0,0 +1,37 @@
+// 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.
+
+/// A library that is used to select the default implementation of smoke. During
+/// development we use a default mirror-based implementation, for deployment we
+/// let the main program set programatically what implementation to use (likely
+/// one based on static code generation).
+library smoke.src.implementation;
+
+// IMPORTANT NOTE: This file is edited by a transformer in this package
+// (default_transformer.dart), so any edits here should be coordinated with
+// changes there.
+
+import 'package:smoke/mirrors.dart';
+import 'package:smoke/smoke.dart';
+
+/// Implementation of [ObjectAccessorService] in use, initialized lazily so it
+/// can be replaced at deployment time with an efficient alternative.
+ObjectAccessorService objectAccessor =
+    new ReflectiveObjectAccessorService();
+
+/// Implementation of [TypeInspectorService] in use, initialized lazily so it
+/// can be replaced at deployment time with an efficient alternative.
+TypeInspectorService typeInspector =
+    new ReflectiveTypeInspectorService();
+
+/// Implementation of [SymbolConverterService] in use, initialized lazily so it
+/// can be replaced at deployment time with an efficient alternative.
+SymbolConverterService symbolConverter =
+    new ReflectiveSymbolConverterService();
+
+throwNotConfiguredError() {
+  throw new Exception('The "smoke" library has not been configured. '
+      'Make sure you import and configure one of the implementations ('
+      'package:smoke/mirrors.dart or package:smoke/static.dart).');
+}
diff --git a/pkg/smoke/lib/static.dart b/pkg/smoke/lib/static.dart
new file mode 100644
index 0000000..4b276fc
--- /dev/null
+++ b/pkg/smoke/lib/static.dart
@@ -0,0 +1,226 @@
+// 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.
+
+/// Static implementation of smoke services using code-generated data.
+library smoke.static;
+
+import 'dart:math' as math;
+
+import 'package:logging/logging.dart';
+import 'package:smoke/smoke.dart';
+
+import 'src/common.dart';
+
+typedef T Getter<T>(object);
+typedef void Setter<T>(object, value);
+
+StaticConfiguration _configuration;
+
+class StaticConfiguration {
+  /// Maps symbol to a function that reads that symbol of an object. For
+  /// instance, `#i: (o) => o.i`.
+  final Map<Symbol, Getter> getters;
+
+  /// Maps symbol to a function that updates that symbol of an object. For
+  /// instance, `#i: (o, v) { o.i = v; }`.
+  final Map<Symbol, Setter> setters;
+
+  /// Maps a type to it's super class. For example, String: Object.
+  final Map<Type, Type> parents;
+
+  /// For each type, a map of declarations per symbol (property or method).
+  final Map<Type, Map<Symbol, Declaration>> declarations;
+
+  /// A map from symbol to strings.
+  final Map<Symbol, String> names;
+
+  /// A map from strings to symbols (the reverse of [names]).
+  final Map<String, Symbol> symbols;
+  StaticConfiguration({
+      this.getters: const {}, this.setters: const {}, this.parents: const {},
+      this.declarations: const {}, this.names: const {}})
+      : this.symbols = {} {
+    names.forEach((k, v) { symbols[v] = k; });
+  }
+}
+
+/// Set up the smoke package to use a static implementation based on the given
+/// [configuration].
+useGeneratedCode(StaticConfiguration configuration) {
+  _configuration = configuration;
+  configure(new _GeneratedObjectAccessorService(),
+      new _GeneratedTypeInspectorService(),
+      new _GeneratedSymbolConverterService());
+}
+
+/// Implements [ObjectAccessorService] using a static configuration.
+class _GeneratedObjectAccessorService implements ObjectAccessorService {
+  read(Object object, Symbol name) {
+    var getter = _configuration.getters[name];
+    if (getter == null) {
+      throw new MissingCodeException('getter "$name" in $object');
+    }
+    return getter(object);
+  }
+  void write(Object object, Symbol name, value) {
+    var setter = _configuration.setters[name];
+    if (setter == null) {
+      throw new MissingCodeException('setter "$name" in $object');
+    }
+    setter(object, value);
+  }
+
+  invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) {
+    var method;
+    if (object is Type) {
+    } else {
+      var getter = _configuration.getters[name];
+      method = getter == null ? null : getter(object);
+    }
+    if (method == null) {
+      throw new MissingCodeException('method "$name" in $object');
+    }
+    var tentativeError;
+    if (adjust) {
+      var min = minArgs(method);
+      if (min > SUPPORTED_ARGS) {
+        tentativeError = 'we tried to adjust the arguments for calling "$name"'
+            ', but we couldn\'t determine the exact number of arguments it '
+            'expects (it is more than $SUPPORTED_ARGS).';
+        // The argument list might be correct, so we still invoke the function
+        // and let the user see the error.
+        args = adjustList(args, min, math.max(min, args.length));
+      } else {
+        var max = maxArgs(method);
+        args = adjustList(args, min, max >= 0 ? max : args.length);
+      }
+    }
+    if (namedArgs != null) {
+      throw new UnsupportedError(
+          'smoke.static doesn\'t support namedArguments in invoke');
+    }
+    try {
+      return Function.apply(method, args);
+    } on NoSuchMethodError catch (e) {
+      // TODO(sigmund): consider whether this should just be in a logger or if
+      // we should wrap `e` as a new exception (what's the best way to let users
+      // know about this tentativeError?)
+      if (tentativeError != null) print(tentativeError);
+      rethrow;
+    }
+  }
+}
+
+/// Implements [TypeInspectorService] using a static configuration.
+class _GeneratedTypeInspectorService implements TypeInspectorService {
+  bool isSubclassOf(Type type, Type supertype) {
+    if (type == supertype || supertype == Object) return true;
+    while (type != Object) {
+      var parentType = _configuration.parents[type];
+      if (parentType == supertype) return true;
+      if (parentType == null) {
+        throw new MissingCodeException('superclass of "$type" ($parentType)');
+      }
+      type = parentType;
+    }
+    return false;
+  }
+
+  bool hasGetter(Type type, Symbol name) {
+    var decl = _findDeclaration(type, name);
+    // No need to check decl.isProperty because methods are also automatically
+    // considered getters (auto-closures).
+    return decl != null && !decl.isStatic;
+  }
+
+  bool hasSetter(Type type, Symbol name) {
+    var decl = _findDeclaration(type, name);
+    return decl != null && !decl.isMethod && !decl.isFinal && !decl.isStatic;
+  }
+
+  bool hasInstanceMethod(Type type, Symbol name) {
+    var decl = _findDeclaration(type, name);
+    return decl != null && decl.isMethod && !decl.isStatic;
+  }
+
+  bool hasStaticMethod(Type type, Symbol name) {
+    final map = _configuration.declarations[type];
+    if (map == null) {
+      throw new MissingCodeException('declarations for $type');
+    }
+    final decl = map[name];
+    return decl != null && decl.isMethod && decl.isStatic;
+  }
+
+  Declaration getDeclaration(Type type, Symbol name) {
+    var decl = _findDeclaration(type, name);
+    if (decl == null) {
+      throw new MissingCodeException('declaration for $type.$name');
+    }
+    return decl;
+  }
+
+  List<Declaration> query(Type type, QueryOptions options) {
+    var result;
+    if (options.includeInherited) {
+      var superclass = _configuration.parents[type];
+      if (superclass == null) {
+        throw new MissingCodeException('superclass of "$type"');
+      }
+      result = (superclass == options.includeUpTo) ? []
+          : query(superclass, options);
+    } else {
+      result = [];
+    }
+    var map = _configuration.declarations[type];
+    if (map == null) {
+      throw new MissingCodeException('declarations for $type');
+    }
+    for (var decl in map.values) {
+      if (!options.includeFields && decl.isField) continue;
+      if (!options.includeProperties && decl.isProperty) continue;
+      if (options.excludeFinal && decl.isFinal) continue;
+      if (!options.includeMethods && decl.isMethod) continue;
+      if (options.withAnnotations != null &&
+          !matchesAnnotation(decl.annotations, options.withAnnotations)) {
+        continue;
+      }
+      result.add(decl);
+    }
+    return result;
+  }
+}
+
+/// Implements [SymbolConverterService] using a static configuration.
+class _GeneratedSymbolConverterService implements SymbolConverterService {
+  String symbolToName(Symbol symbol) => _configuration.names[symbol];
+  Symbol nameToSymbol(String name) => _configuration.symbols[name];
+}
+
+
+/// Exception thrown when trynig to access something that should be there, but
+/// the code generator didn't include it.
+class MissingCodeException implements Exception {
+  final String description;
+  MissingCodeException(this.description);
+
+  String toString() => 'Missing $description. '
+      'Code generation for the smoke package seems incomplete.';
+}
+
+Declaration _findDeclaration(Type type, Symbol name) {
+  while (type != Object) {
+    final declarations = _configuration.declarations[type];
+    if (declarations != null) {
+      final declaration = declarations[name];
+      if (declaration != null) return declaration;
+    }
+    var parentType = _configuration.parents[type];
+    if (parentType == null) {
+      throw new MissingCodeException('superclass of "$type"');
+    }
+    type = parentType;
+  }
+  return null;
+}
diff --git a/pkg/smoke/pubspec.yaml b/pkg/smoke/pubspec.yaml
new file mode 100644
index 0000000..194a3aa
--- /dev/null
+++ b/pkg/smoke/pubspec.yaml
@@ -0,0 +1,18 @@
+name: smoke
+version: 0.1.0-dev
+author: Polymer.dart Authors <web-ui-dev@dartlang.org>
+description: >
+  A restricted reflective system that uses mirrors at development time, but that
+  can be replaced with non-reflective calls using code generation. See README.md
+  for mode details.
+dependencies:
+  barback: ">=0.9.0 <0.12.0"
+  logging: ">=0.9.0 <0.10.0"
+#TODO(sigmund): uncomment this once we have some easier way to do global
+# app-level transformers or a way to enable this selectively from the
+# application package.
+#transformers: [smoke/src/default_transformer]
+dev_dependencies:
+  unittest: ">=0.9.0 <0.10.0"
+environment:
+  sdk: ">=1.1.0-dev.5.0 <2.0.0"
diff --git a/pkg/smoke/test/args_test.dart b/pkg/smoke/test/args_test.dart
new file mode 100644
index 0000000..f56270f
--- /dev/null
+++ b/pkg/smoke/test/args_test.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Tests for [minArgs] and [maxArgs].
+library smoke.test.args_test;
+
+import 'package:smoke/smoke.dart' show minArgs, maxArgs, SUPPORTED_ARGS;
+import 'package:unittest/unittest.dart';
+
+main() {
+  var a = new A();
+  var instanceMethods = [ a.m1, a.m2, a.m3, a.m4, a.m5, a.m6, a.m7, a.m8, a.m9,
+      a.m10, a.m11, a.m12, a.m13, a.m14, a.m15, a.m16, a.m17, a.m18, a.m19,
+      a.m20, a.m21];
+  group('instance methods', () => checkMethods(instanceMethods));
+  group('static methods', () => checkMethods(staticMethods));
+  group('closures', () => checkMethods(closures));
+  group('top level methods', () => checkMethods(topLevelMethods));
+}
+
+checkMethods(List methods) {
+  test('min args', () {
+    expect(methods.map((m) => minArgs(m)), expectedMin);
+  });
+
+  test('max args', () {
+    expect(methods.map((m) => maxArgs(m)), expectedMax);
+  });
+}
+
+class A {
+  // required args only
+  static s1() {}
+  static s2(p1) {}
+  static s3(p1, p2) {}
+  static s4(p1, p2, p3) {}
+  static s5(p1, p2, p3, p4) {}
+  static s6(p1, p2, p3, p4, p5) {}
+
+  // optional args only
+  static s7([o1]) {}
+  static s8([o1, o2]) {}
+  static s9([o1, o2, o3]) {}
+  static s10([o1, o2, o3, o4]) {}
+  static s11([o1, o2, o3, o4, o5]) {}
+
+  // 1 required, some optional
+  static s12(p1, [o2]) {}
+  static s13(p1, [o2, o3]) {}
+  static s14(p1, [o2, o3, o4]) {}
+  static s15(p1, [o2, o3, o4, o5]) {}
+
+  // 2 required, some optional
+  static s16(p1, p2, [o3]) {}
+  static s17(p1, p2, [o3, o4]) {}
+  static s18(p1, p2, [o3, o4, o5]) {}
+
+  // 3 required, some optional
+  static s19(p1, p2, p3, [o4]) {}
+  static s20(p1, p2, p3, [o4, o5]) {}
+
+  // 4 required, some optional
+  static s21(p1, p2, p3, p4, [o5]) {}
+
+  m1() {}
+  m2(p1) {}
+  m3(p1, p2) {}
+  m4(p1, p2, p3) {}
+  m5(p1, p2, p3, p4) {}
+  m6(p1, p2, p3, p4, p5) {}
+  m7([o1]) {}
+  m8([o1, o2]) {}
+  m9([o1, o2, o3]) {}
+  m10([o1, o2, o3, o4]) {}
+  m11([o1, o2, o3, o4, o5]) {}
+  m12(p1, [o2]) {}
+  m13(p1, [o2, o3]) {}
+  m14(p1, [o2, o3, o4]) {}
+  m15(p1, [o2, o3, o4, o5]) {}
+  m16(p1, p2, [o3]) {}
+  m17(p1, p2, [o3, o4]) {}
+  m18(p1, p2, [o3, o4, o5]) {}
+  m19(p1, p2, p3, [o4]) {}
+  m20(p1, p2, p3, [o4, o5]) {}
+  m21(p1, p2, p3, p4, [o5]) {}
+}
+
+t1() {}
+t2(p1) {}
+t3(p1, p2) {}
+t4(p1, p2, p3) {}
+t5(p1, p2, p3, p4) {}
+t6(p1, p2, p3, p4, p5) {}
+t7([o1]) {}
+t8([o1, o2]) {}
+t9([o1, o2, o3]) {}
+t10([o1, o2, o3, o4]) {}
+t11([o1, o2, o3, o4, o5]) {}
+t12(p1, [o2]) {}
+t13(p1, [o2, o3]) {}
+t14(p1, [o2, o3, o4]) {}
+t15(p1, [o2, o3, o4, o5]) {}
+t16(p1, p2, [o3]) {}
+t17(p1, p2, [o3, o4]) {}
+t18(p1, p2, [o3, o4, o5]) {}
+t19(p1, p2, p3, [o4]) {}
+t20(p1, p2, p3, [o4, o5]) {}
+t21(p1, p2, p3, p4, [o5]) {}
+
+List closures = [
+  () {},
+  (p1) {},
+  (p1, p2) {},
+  (p1, p2, p3) {},
+  (p1, p2, p3, p4) {},
+  (p1, p2, p3, p4, p5) {},
+  ([o1]) {},
+  ([o1, o2]) {},
+  ([o1, o2, o3]) {},
+  ([o1, o2, o3, o4]) {},
+  ([o1, o2, o3, o4, o5]) {},
+  (p1, [o2]) {},
+  (p1, [o2, o3]) {},
+  (p1, [o2, o3, o4]) {},
+  (p1, [o2, o3, o4, o5]) {},
+  (p1, p2, [o3]) {},
+  (p1, p2, [o3, o4]) {},
+  (p1, p2, [o3, o4, o5]) {},
+  (p1, p2, p3, [o4]) {},
+  (p1, p2, p3, [o4, o5]) {},
+  (p1, p2, p3, p4, [o5]) {},
+];
+
+List staticMethods = [ A.s1, A.s2, A.s3, A.s4, A.s5, A.s6, A.s7, A.s8, A.s9,
+     A.s10, A.s11, A.s12, A.s13, A.s14, A.s15, A.s16, A.s17, A.s18, A.s19,
+     A.s20, A.s21];
+
+List topLevelMethods = [ t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12,
+    t13, t14, t15, t16, t17, t18, t19, t20, t21];
+
+const MIN_NOT_KNOWN = SUPPORTED_ARGS + 1;
+List expectedMin = const [
+  0, 1, 2, 3, MIN_NOT_KNOWN, MIN_NOT_KNOWN, // required only
+  0, 0, 0, 0, 0, // optional only
+  1, 1, 1, 1, // 1 required
+  2, 2, 2, // 2 required
+  3, 3, // 3 required
+  MIN_NOT_KNOWN // 4 required
+];
+
+const MAX_NOT_KNOWN = -1;
+List expectedMax = const [
+  0, 1, 2, 3, MAX_NOT_KNOWN, MAX_NOT_KNOWN, // required only
+  1, 2, 3, 3, 3, // optional only
+  2, 3, 3, 3, // 1 required
+  3, 3, 3, // 2 required
+  3, 3, // 3 required
+  MAX_NOT_KNOWN // 4 required
+];
diff --git a/pkg/smoke/test/common.dart b/pkg/smoke/test/common.dart
new file mode 100644
index 0000000..d60679f
--- /dev/null
+++ b/pkg/smoke/test/common.dart
@@ -0,0 +1,376 @@
+// 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.
+
+/// Common test code that is run by 3 tests: mirrors_test.dart,
+/// mirrors_used_test.dart, and static_test.dart.
+library smoke.test.common;
+
+import 'package:smoke/smoke.dart' as smoke;
+import 'package:unittest/unittest.dart';
+
+main() {
+  test('read value', () {
+    var a = new A();
+    expect(smoke.read(a, #i), 42);
+    expect(smoke.read(a, #j), 44);
+    expect(smoke.read(a, #j2), 44);
+  });
+
+  test('write value', () {
+    var a = new A();
+    smoke.write(a, #i, 43);
+    expect(a.i, 43);
+    smoke.write(a, #j2, 46);
+    expect(a.j, 46);
+    expect(a.j2, 46);
+    expect(smoke.read(a, #j), 46);
+    expect(smoke.read(a, #j2), 46);
+  });
+
+  test('invoke', () {
+    var a = new A();
+
+    smoke.invoke(a, #inc0, []);
+    expect(a.i, 43);
+    expect(smoke.read(a, #i), 43);
+    expect(() => smoke.invoke(a, #inc0, [2]), throws);
+    expect(a.i, 43);
+    expect(() => smoke.invoke(a, #inc0, [1, 2, 3]), throws);
+    expect(a.i, 43);
+
+    expect(() => smoke.invoke(a, #inc1, []), throws);
+    expect(a.i, 43);
+    smoke.invoke(a, #inc1, [4]);
+    expect(a.i, 47);
+
+    smoke.invoke(a, #inc2, []);
+    expect(a.i, 37);
+    smoke.invoke(a, #inc2, [4]);
+    expect(a.i, 41);
+
+    expect(() => smoke.invoke(a, #inc1, [4, 5]), throws);
+    expect(a.i, 41);
+  });
+
+  test('read and invoke function', () {
+    var a = new A();
+    expect(a.i, 42);
+    var f = smoke.read(a, #inc1);
+    f(4);
+    expect(a.i, 46);
+    Function.apply(f, [4]);
+    expect(a.i, 50);
+  });
+
+  test('invoke with adjust', () {
+    var a = new A();
+    smoke.invoke(a, #inc0, [], adjust: true);
+    expect(a.i, 43);
+    smoke.invoke(a, #inc0, [2], adjust: true);
+    expect(a.i, 44);
+    smoke.invoke(a, #inc0, [1, 2, 3], adjust: true);
+    expect(a.i, 45);
+
+    smoke.invoke(a, #inc1, [], adjust: true); // treat as null (-10)
+    expect(a.i, 35);
+    smoke.invoke(a, #inc1, [4], adjust: true);
+    expect(a.i, 39);
+
+    smoke.invoke(a, #inc2, [], adjust: true); // default is null (-10)
+    expect(a.i, 29);
+    smoke.invoke(a, #inc2, [4, 5], adjust: true);
+    expect(a.i, 33);
+  });
+
+  test('has getter', () {
+    expect(smoke.hasGetter(A, #i), isTrue);
+    expect(smoke.hasGetter(A, #j2), isTrue);
+    expect(smoke.hasGetter(A, #inc2), isTrue);
+    expect(smoke.hasGetter(B, #a), isTrue);
+    expect(smoke.hasGetter(B, #i), isFalse);
+    expect(smoke.hasGetter(B, #f), isTrue);
+    expect(smoke.hasGetter(D, #i), isTrue);
+
+    expect(smoke.hasGetter(E, #x), isFalse);
+    expect(smoke.hasGetter(E, #y), isTrue);
+    expect(smoke.hasGetter(E, #z), isFalse); // don't consider noSuchMethod
+  });
+
+  test('has setter', () {
+    expect(smoke.hasSetter(A, #i), isTrue);
+    expect(smoke.hasSetter(A, #j2), isTrue);
+    expect(smoke.hasSetter(A, #inc2), isFalse);
+    expect(smoke.hasSetter(B, #a), isTrue);
+    expect(smoke.hasSetter(B, #i), isFalse);
+    expect(smoke.hasSetter(B, #f), isFalse);
+    expect(smoke.hasSetter(D, #i), isTrue);
+
+    // TODO(sigmund): should we support declaring a setter with no getter?
+    // expect(smoke.hasSetter(E, #x), isTrue);
+    expect(smoke.hasSetter(E, #y), isFalse);
+    expect(smoke.hasSetter(E, #z), isFalse); // don't consider noSuchMethod
+  });
+
+  test('no such method', () {
+    expect(smoke.hasNoSuchMethod(A), isFalse);
+    expect(smoke.hasNoSuchMethod(E), isTrue);
+    expect(smoke.hasNoSuchMethod(E2), isTrue);
+  });
+
+  test('has instance method', () {
+    expect(smoke.hasInstanceMethod(A, #inc0), isTrue);
+    expect(smoke.hasInstanceMethod(A, #inc3), isFalse);
+    expect(smoke.hasInstanceMethod(C, #inc), isTrue);
+    expect(smoke.hasInstanceMethod(D, #inc), isTrue);
+    expect(smoke.hasInstanceMethod(D, #inc0), isTrue);
+    expect(smoke.hasInstanceMethod(F, #staticMethod), isFalse);
+    expect(smoke.hasInstanceMethod(F2, #staticMethod), isFalse);
+  });
+
+  test('has static method', () {
+    expect(smoke.hasStaticMethod(A, #inc0), isFalse);
+    expect(smoke.hasStaticMethod(C, #inc), isFalse);
+    expect(smoke.hasStaticMethod(D, #inc), isFalse);
+    expect(smoke.hasStaticMethod(D, #inc0), isFalse);
+    expect(smoke.hasStaticMethod(F, #staticMethod), isTrue);
+    expect(smoke.hasStaticMethod(F2, #staticMethod), isFalse);
+  });
+
+  test('get declaration', () {
+    var d = smoke.getDeclaration(B, #a);
+    expect(d.name, #a);
+    expect(d.isField, isTrue);
+    expect(d.isProperty, isFalse);
+    expect(d.isMethod, isFalse);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isFalse);
+    expect(d.annotations, []);
+    expect(d.type, A);
+
+    d = smoke.getDeclaration(B, #w);
+    expect(d.name, #w);
+    expect(d.isField, isFalse);
+    expect(d.isProperty, isTrue);
+    expect(d.isMethod, isFalse);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isFalse);
+    expect(d.annotations, []);
+    expect(d.type, int);
+
+    d = smoke.getDeclaration(A, #inc1);
+    expect(d.name, #inc1);
+    expect(d.isField, isFalse);
+    expect(d.isProperty, isFalse);
+    expect(d.isMethod, isTrue);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isFalse);
+    expect(d.annotations, []);
+    expect(d.type, Function);
+
+    d = smoke.getDeclaration(F, #staticMethod);
+    expect(d.name, #staticMethod);
+    expect(d.isField, isFalse);
+    expect(d.isProperty, isFalse);
+    expect(d.isMethod, isTrue);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isTrue);
+    expect(d.annotations, []);
+    expect(d.type, Function);
+
+    d = smoke.getDeclaration(G, #b);
+    expect(d.name, #b);
+    expect(d.isField, isTrue);
+    expect(d.isProperty, isFalse);
+    expect(d.isMethod, isFalse);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isFalse);
+    expect(d.annotations, [const Annot()]);
+    expect(d.type, int);
+
+    d = smoke.getDeclaration(G, #d);
+    expect(d.name, #d);
+    expect(d.isField, isTrue);
+    expect(d.isProperty, isFalse);
+    expect(d.isMethod, isFalse);
+    expect(d.isFinal, isFalse);
+    expect(d.isStatic, isFalse);
+    expect(d.annotations, [32]);
+    expect(d.type, int);
+  });
+
+  test('isSuperclass', () {
+    expect(smoke.isSubclassOf(D, C), isTrue);
+    expect(smoke.isSubclassOf(H, G), isTrue);
+    expect(smoke.isSubclassOf(H, H), isTrue);
+    expect(smoke.isSubclassOf(H, Object), isTrue);
+    expect(smoke.isSubclassOf(B, Object), isTrue);
+    expect(smoke.isSubclassOf(A, Object), isTrue);
+    expect(smoke.isSubclassOf(AnnotB, Annot), isTrue);
+
+    expect(smoke.isSubclassOf(D, A), isFalse);
+    expect(smoke.isSubclassOf(H, B), isFalse);
+    expect(smoke.isSubclassOf(B, A), isFalse);
+    expect(smoke.isSubclassOf(Object, A), isFalse);
+  });
+
+  group('query', () {
+    test('default', () {
+      var options = new smoke.QueryOptions();
+      var res = smoke.query(A, options);
+      expect(res.map((e) => e.name), [#i, #j, #j2]);
+    });
+
+    test('only fields', () {
+      var options = new smoke.QueryOptions(includeProperties: false);
+      var res = smoke.query(A, options);
+      expect(res.map((e) => e.name), [#i, #j]);
+    });
+
+    test('only properties', () {
+      var options = new smoke.QueryOptions(includeFields: false);
+      var res = smoke.query(A, options);
+      expect(res.map((e) => e.name), [#j2]);
+    });
+
+    test('properties and methods', () {
+      var options = new smoke.QueryOptions(includeMethods: true);
+      var res = smoke.query(A, options);
+      expect(res.map((e) => e.name), [#i, #j, #j2, #inc0, #inc1, #inc2]);
+    });
+
+    test('inherited properties and fields', () {
+      var options = new smoke.QueryOptions(includeInherited: true);
+      var res = smoke.query(D, options);
+      expect(res.map((e) => e.name), [#x, #y, #b, #i, #j, #j2, #x2, #i2]);
+    });
+
+    test('inherited fields only', () {
+      var options = new smoke.QueryOptions(includeInherited: true,
+          includeProperties: false);
+      var res = smoke.query(D, options);
+      expect(res.map((e) => e.name), [#x, #y, #b, #i, #j]);
+    });
+
+    test('exact annotation', () {
+      var options = new smoke.QueryOptions(includeInherited: true,
+          withAnnotations: const [a1]);
+      var res = smoke.query(H, options);
+      expect(res.map((e) => e.name), [#b, #f, #g]);
+
+      options = new smoke.QueryOptions(includeInherited: true,
+          withAnnotations: const [a2]);
+      res = smoke.query(H, options);
+      expect(res.map((e) => e.name), [#d, #h]);
+
+      options = new smoke.QueryOptions(includeInherited: true,
+          withAnnotations: const [a1, a2]);
+      res = smoke.query(H, options);
+      expect(res.map((e) => e.name), [#b, #d, #f, #g, #h]);
+    });
+
+    test('type annotation', () {
+      var options = new smoke.QueryOptions(includeInherited: true,
+          withAnnotations: const [Annot]);
+      var res = smoke.query(H, options);
+      expect(res.map((e) => e.name), [#b, #f, #g, #i]);
+    });
+
+    test('mixed annotations (type and exact)', () {
+      var options = new smoke.QueryOptions(includeInherited: true,
+          withAnnotations: const [a2, Annot]);
+      var res = smoke.query(H, options);
+      expect(res.map((e) => e.name), [#b, #d, #f, #g, #h, #i]);
+    });
+
+    test('symbol to name', () {
+      expect(smoke.symbolToName(#i), 'i');
+    });
+
+    test('name to symbol', () {
+      expect(smoke.nameToSymbol('i'), #i);
+    });
+  });
+}
+
+class A {
+  int i = 42;
+  int j = 44;
+  int get j2 => j;
+  void set j2(int v) { j = v; }
+  void inc0() { i++; }
+  void inc1(int v) { i = i + (v == null ? -10 : v); }
+  void inc2([int v]) { i = i + (v == null ? -10 : v); }
+}
+
+class B {
+  final int f = 3;
+  int _w;
+  int get w => _w;
+  set w(int v) { _w = v; }
+
+  String z;
+  A a;
+
+  B(this._w, this.z, this.a);
+}
+
+class C {
+  int x;
+  String y;
+  B b;
+
+  inc(int n) {
+    x = x + n;
+  }
+  dec(int n) {
+    x = x - n;
+  }
+
+  C(this.x, this.y, this.b);
+}
+
+
+class D extends C with A {
+  int get x2 => x;
+  int get i2 => i;
+
+  D(x, y, b) : super(x, y, b);
+}
+
+class E {
+  set x(int v) { }
+  int get y => 1;
+
+  noSuchMethod(i) => y;
+}
+
+class E2 extends E {}
+
+class F {
+  static int staticMethod(A a) => a.i;
+}
+
+class F2 extends F {}
+
+class Annot { const Annot(); }
+class AnnotB extends Annot { const AnnotB(); }
+const a1 = const Annot();
+const a2 = 32;
+const a3 = const AnnotB();
+
+
+class G {
+  int a;
+  @a1 int b;
+  int c;
+  @a2 int d;
+}
+
+class H extends G {
+  int e;
+  @a1 int f;
+  @a1 int g;
+  @a2 int h;
+  @a3 int i;
+}
diff --git a/pkg/smoke/test/mirrors_test.dart b/pkg/smoke/test/mirrors_test.dart
new file mode 100644
index 0000000..cac643a
--- /dev/null
+++ b/pkg/smoke/test/mirrors_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library smoke.test.mirrors_test;
+
+import 'package:smoke/mirrors.dart';
+import 'package:unittest/unittest.dart';
+import 'common.dart' as common show main;
+
+main() {
+  setUp(useMirrors);
+  common.main();
+}
diff --git a/pkg/smoke/test/mirrors_used_test.dart b/pkg/smoke/test/mirrors_used_test.dart
new file mode 100644
index 0000000..ec3a019
--- /dev/null
+++ b/pkg/smoke/test/mirrors_used_test.dart
@@ -0,0 +1,21 @@
+// 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 smoke.test.mirrors_test;
+
+import 'package:smoke/mirrors.dart';
+import 'package:unittest/unittest.dart';
+import 'common.dart' hide main;
+import 'common.dart' as common show main;
+
+
+@MirrorsUsed(
+    targets: const [A, B, C, D, E, E2, F, F2, G, H],
+    override: 'smoke.mirrors')
+import 'dart:mirrors';
+
+main() {
+  setUp(useMirrors);
+  common.main();
+}
diff --git a/pkg/smoke/test/static_test.dart b/pkg/smoke/test/static_test.dart
new file mode 100644
index 0000000..9ede138
--- /dev/null
+++ b/pkg/smoke/test/static_test.dart
@@ -0,0 +1,113 @@
+// 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 smoke.test.static_test;
+
+import 'package:smoke/smoke.dart' show Declaration, PROPERTY, METHOD;
+import 'package:smoke/static.dart';
+import 'package:unittest/unittest.dart';
+import 'common.dart' hide main;
+import 'common.dart' as common show main;
+
+// Abstract class used to represent the mixing C&A in the smoke configuration.
+abstract class C_with_A {}
+
+// Static configuration that declares only the symbols, getters, methods, and
+// super-class relationships we want to preserve. This and the class above
+// should be automatically generated by transformers using smoke.
+var _config = new StaticConfiguration(
+    getters: {
+      #i: (o) => o.i,
+      #j: (o) => o.j,
+      #j2: (o) => o.j2,
+      #inc0: (o) => o.inc0,
+      #inc1: (o) => o.inc1,
+      #inc2: (o) => o.inc2,
+    },
+    setters: {
+      #i: (o, v) { o.i = v; },
+      #j2: (o, v) { o.j2 = v; },
+    },
+    // TODO(sigmund): this could be a const map, but that triggers
+    // dartbug.com/17123
+    // TODO(sigmund): before doing codegen for this, consider changing smoke's
+    // defaults so we don't need to specify obvious things like `int`, or `*:
+    // Object`.
+    parents: {
+      Annot: Object,
+      AnnotB: Annot,
+      A: Object,
+      B: Object,
+      C: Object,
+      C_with_A: C,
+      D: C_with_A,
+      E: Object,
+      E2: E,
+      F: Object,
+      F2: F,
+      G: Object,
+      H: G,
+      int: Object,
+    },
+    declarations: { 
+      B: {
+        #a: const Declaration(#a, A),
+        #w: const Declaration(#w, int, kind: PROPERTY),
+        #f: const Declaration(#f, int, isFinal: true),
+      },
+      A: {
+        #i: const Declaration(#i, int),
+        #j: const Declaration(#j, int),
+        #j2: const Declaration(#j2, int, kind: PROPERTY),
+        #inc0: const Declaration(#inc0, Function, kind: METHOD),
+        #inc1: const Declaration(#inc1, Function, kind: METHOD),
+        #inc2: const Declaration(#inc2, Function, kind: METHOD),
+      },
+      C: {
+        #x: const Declaration(#x, int),
+        #y: const Declaration(#y, String),
+        #b: const Declaration(#b, B),
+        #inc: const Declaration(#inc, Function, kind: METHOD),
+      },
+      C_with_A: {
+        #i: const Declaration(#i, int),
+        #j: const Declaration(#j, int),
+        #j2: const Declaration(#j2, int, kind: PROPERTY),
+        #inc0: const Declaration(#inc0, Function, kind: METHOD),
+        #inc1: const Declaration(#inc1, Function, kind: METHOD),
+        #inc2: const Declaration(#inc2, Function, kind: METHOD),
+      },
+      D: {
+        #x2: const Declaration(#x2, int, kind: PROPERTY),
+        #i2: const Declaration(#i2, int, kind: PROPERTY),
+      },
+      E: {
+        #y: const Declaration(#y, int, isFinal: true, kind: PROPERTY),
+        #noSuchMethod:
+           const Declaration(#noSuchMethody, Function, kind: METHOD),
+      },
+      E2: const {},
+      F: {#staticMethod: const Declaration(#staticMethod, Function,
+             kind: METHOD, isStatic: true)},
+      F2: const {},
+      G: {
+        #a: const Declaration(#a, int),
+        #b: const Declaration(#b, int, annotations: const [a1]),
+        #c: const Declaration(#c, int),
+        #d: const Declaration(#d, int, annotations: const [a2]),
+      },
+      H: {
+        #e: const Declaration(#e, int),
+        #f: const Declaration(#f, int, annotations: const [a1]),
+        #g: const Declaration(#g, int, annotations: const [a1]),
+        #h: const Declaration(#h, int, annotations: const [a2]),
+        #i: const Declaration(#i, int, annotations: const [a3]),
+      },
+    },
+    names: {#i: 'i'});
+
+main() {
+  setUp(() => useGeneratedCode(_config));
+  common.main();
+}
diff --git a/pkg/stack_trace/lib/src/chain.dart b/pkg/stack_trace/lib/src/chain.dart
index 4055bc8..2500e5e 100644
--- a/pkg/stack_trace/lib/src/chain.dart
+++ b/pkg/stack_trace/lib/src/chain.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'frame.dart';
 import 'stack_zone_specification.dart';
 import 'trace.dart';
 import 'utils.dart';
@@ -172,6 +173,32 @@
     return new Chain(nonEmptyTraces);
   }
 
+  /// Returns a new [Chain] based on [this] where multiple stack frames matching
+  /// [predicate] are folded together.
+  ///
+  /// This means that whenever there are multiple frames in a row that match
+  /// [predicate], only the last one is kept. In addition, traces that are
+  /// composed entirely of frames matching [predicate] are omitted.
+  ///
+  /// This is useful for limiting the amount of library code that appears in a
+  /// stack trace by only showing user code and code that's called by user code.
+  Chain foldFrames(bool predicate(Frame frame)) {
+    var foldedTraces = traces.map((trace) => trace.foldFrames(predicate));
+    var nonEmptyTraces = foldedTraces.where((trace) {
+      // Ignore traces that contain only folded frames. These traces will be
+      // folded into a single frame each.
+      return trace.frames.length > 1;
+    });
+
+    // If all the traces contain only internal processing, preserve the last
+    // (top-most) one so that the chain isn't empty.
+    if (nonEmptyTraces.isEmpty && foldedTraces.isNotEmpty) {
+      return new Chain([foldedTraces.last]);
+    }
+
+    return new Chain(nonEmptyTraces);
+  }
+
   /// Converts [this] to a [Trace].
   ///
   /// The trace version of a chain is just the concatenation of all the traces
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index 7b9c7b1..96a5ec5 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -47,6 +47,15 @@
 
 final _initialDot = new RegExp(r"^\.");
 
+/// "dart:" libraries that are incorrectly reported without a "dart:" prefix.
+///
+/// See issue 11901. All these libraries should be in "dart:io".
+final _ioLibraries = new Set.from([
+  new Uri(path: 'timer_impl.dart'),
+  new Uri(path: 'http_impl.dart'),
+  new Uri(path: 'http_parser.dart')
+]);
+
 /// A single stack frame. Each frame points to a precise location in Dart code.
 class Frame {
   /// The URI of the file in which the code is located.
@@ -130,10 +139,7 @@
     // always be found. The column is optional.
     var member = match[1].replaceAll("<anonymous closure>", "<fn>");
     var uri = Uri.parse(match[2]);
-    // Work around issue 11901.
-    if (uri == new Uri(path: 'timer_impl.dart')) {
-      uri = Uri.parse('dart:async/timer_impl.dart');
-    }
+    if (_ioLibraries.contains(uri)) uri = Uri.parse('dart:io/${uri.path}');
     var line = int.parse(match[3]);
     var column = null;
     var columnMatch = match[4];
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index c1d751f..c540d78 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -229,7 +229,7 @@
   ///
   /// This is useful for limiting the amount of library code that appears in a
   /// stack trace by only showing user code and code that's called by user code.
-  Trace foldFrames(bool predicate(frame)) {
+  Trace foldFrames(bool predicate(Frame frame)) {
     var newFrames = <Frame>[];
     for (var frame in frames.reversed) {
       if (!predicate(frame)) {
diff --git a/pkg/stack_trace/pubspec.yaml b/pkg/stack_trace/pubspec.yaml
index 5a023c0..1bd4776 100644
--- a/pkg/stack_trace/pubspec.yaml
+++ b/pkg/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@
 name: stack_trace
-version: 0.9.1-dev+1
+version: 0.9.2-dev
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/stack_trace/test/chain_test.dart b/pkg/stack_trace/test/chain_test.dart
index 9c16690..d9915eb 100644
--- a/pkg/stack_trace/test/chain_test.dart
+++ b/pkg/stack_trace/test/chain_test.dart
@@ -387,7 +387,7 @@
           'dart:core             Bar.baz\n'));
     });
 
-    test("doesn't return in an empty chain", () {
+    test("doesn't return an empty chain", () {
       var chain = new Chain([
         new Trace.parse(
             'dart:core 10:11                             Foo.bar\n'
@@ -403,6 +403,67 @@
     });
   });
 
+  group('Chain.foldFrames', () {
+    test('folds each trace', () {
+      var chain = new Chain([
+        new Trace.parse(
+            'a.dart 10:11  Foo.bar\n'
+            'a.dart 10:11  Bar.baz\n'
+            'b.dart 10:11  Bang.qux\n'
+            'a.dart 10:11  Zip.zap\n'
+            'a.dart 10:11  Zop.zoop'),
+        new Trace.parse(
+            'a.dart 10:11  Foo.bar\n'
+            'a.dart 10:11  Bar.baz\n'
+            'a.dart 10:11  Bang.qux\n'
+            'a.dart 10:11  Zip.zap\n'
+            'b.dart 10:11  Zop.zoop')
+      ]);
+
+      var folded = chain.foldFrames((frame) => frame.library == 'a.dart');
+      expect(folded.toString(), equals(
+          'a.dart 10:11  Bar.baz\n'
+          'b.dart 10:11  Bang.qux\n'
+          'a.dart 10:11  Zop.zoop\n'
+          '===== asynchronous gap ===========================\n'
+          'a.dart 10:11  Zip.zap\n'
+          'b.dart 10:11  Zop.zoop\n'));
+    });
+
+    test('eliminates completely-folded traces', () {
+      var chain = new Chain([
+        new Trace.parse(
+            'a.dart 10:11  Foo.bar\n'
+            'b.dart 10:11  Bang.qux'),
+        new Trace.parse(
+            'a.dart 10:11  Foo.bar\n'
+            'a.dart 10:11  Bang.qux'),
+        new Trace.parse(
+            'a.dart 10:11  Zip.zap\n'
+            'b.dart 10:11  Zop.zoop')
+      ]);
+
+      var folded = chain.foldFrames((frame) => frame.library == 'a.dart');
+      expect(folded.toString(), equals(
+          'a.dart 10:11  Foo.bar\n'
+          'b.dart 10:11  Bang.qux\n'
+          '===== asynchronous gap ===========================\n'
+          'a.dart 10:11  Zip.zap\n'
+          'b.dart 10:11  Zop.zoop\n'));
+    });
+
+    test("doesn't return an empty trace", () {
+      var chain = new Chain([
+        new Trace.parse(
+            'a.dart 10:11  Foo.bar\n'
+            'a.dart 10:11  Bang.qux')
+      ]);
+
+      var folded = chain.foldFrames((frame) => frame.library == 'a.dart');
+      expect(folded.toString(), equals('a.dart 10:11  Bang.qux\n'));
+    });
+  });
+
   test('Chain.toTrace eliminates asynchronous gaps', () {
     var trace = new Chain([
       new Trace.parse(
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index 482794c..b61e8bb 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -33,7 +33,25 @@
     test('parses a stack frame with timer_impl correctly', () {
       var frame = new Frame.parseVM("#1      Foo._bar "
           "(timer_impl.dart:24)");
-      expect(frame.uri, equals(Uri.parse("dart:async/timer_impl.dart")));
+      expect(frame.uri, equals(Uri.parse("dart:io/timer_impl.dart")));
+      expect(frame.line, equals(24));
+      expect(frame.column, null);
+      expect(frame.member, equals('Foo._bar'));
+    });
+
+    test('parses a stack frame with http_parser correctly', () {
+      var frame = new Frame.parseVM("#1      Foo._bar "
+          "(http_parser.dart:24)");
+      expect(frame.uri, equals(Uri.parse("dart:io/http_parser.dart")));
+      expect(frame.line, equals(24));
+      expect(frame.column, null);
+      expect(frame.member, equals('Foo._bar'));
+    });
+
+    test('parses a stack frame with http_impl correctly', () {
+      var frame = new Frame.parseVM("#1      Foo._bar "
+          "(http_impl.dart:24)");
+      expect(frame.uri, equals(Uri.parse("dart:io/http_impl.dart")));
       expect(frame.line, equals(24));
       expect(frame.column, null);
       expect(frame.member, equals('Foo._bar'));
diff --git a/pkg/third_party/html5lib/CHANGELOG.md b/pkg/third_party/html5lib/CHANGELOG.md
index 9bba04d..7c97280 100644
--- a/pkg/third_party/html5lib/CHANGELOG.md
+++ b/pkg/third_party/html5lib/CHANGELOG.md
@@ -3,6 +3,9 @@
 This file contains highlights of what changes on each version of the html5lib
 package.
 
-#### Pub version 0.10.0-dev
+#### Pub version 0.9.2-dev
+  * add Node.text, Node.append, Document.documentElement
+  * add Text.data, deprecate Node.value and Text.value.
+  * deprecate Node.$dom_nodeType
   * added querySelector/querySelectorAll, deprecated query/queryAll.
     This matches the current APIs in dart:html.
diff --git a/pkg/third_party/html5lib/lib/dom.dart b/pkg/third_party/html5lib/lib/dom.dart
index 9f70694..b81c1ff 100644
--- a/pkg/third_party/html5lib/lib/dom.dart
+++ b/pkg/third_party/html5lib/lib/dom.dart
@@ -1,7 +1,5 @@
-/**
- * A simple tree API that results from parsing html. Intended to be compatible
- * with dart:html, but right now it resembles the classic JS DOM.
- */
+/// A simple tree API that results from parsing html. Intended to be compatible
+/// with dart:html, but right now it resembles the classic JS DOM.
 library dom;
 
 import 'dart:collection';
@@ -18,13 +16,13 @@
 // TODO(jmesserly): this needs to be replaced by an AttributeMap for attributes
 // that exposes namespace info.
 class AttributeName implements Comparable {
-  /** The namespace prefix, e.g. `xlink`. */
+  /// The namespace prefix, e.g. `xlink`.
   final String prefix;
 
-  /** The attribute name, e.g. `title`. */
+  /// The attribute name, e.g. `title`.
   final String name;
 
-  /** The namespace url, e.g. `http://www.w3.org/1999/xlink` */
+  /// The namespace url, e.g. `http://www.w3.org/1999/xlink`
   final String namespace;
 
   const AttributeName(this.prefix, this.name, this.namespace);
@@ -62,7 +60,7 @@
   }
 }
 
-/** Really basic implementation of a DOM-core like Node. */
+/// Really basic implementation of a DOM-core like Node.
 abstract class Node {
   static const int ATTRIBUTE_NODE = 2;
   static const int CDATA_SECTION_NODE = 4;
@@ -77,60 +75,59 @@
   static const int PROCESSING_INSTRUCTION_NODE = 7;
   static const int TEXT_NODE = 3;
 
-  // TODO(jmesserly): this should be on Element
-  /** The tag name associated with the node. */
-  final String tagName;
+  /// Note: For now we use it to implement the deprecated tagName property.
+  final String _tagName;
 
-  /** The parent of the current node (or null for the document node). */
+  /// *Deprecated* use [Element.localName] instead.
+  /// Note: after removal, this will be replaced by a correct version that
+  /// returns uppercase [as specified](http://dom.spec.whatwg.org/#dom-element-tagname).
+  @deprecated String get tagName => _tagName;
+
+  /// The parent of the current node (or null for the document node).
   Node parent;
 
   // TODO(jmesserly): should move to Element.
-  /**
-   * A map holding name, value pairs for attributes of the node.
-   *
-   * Note that attribute order needs to be stable for serialization, so we use a
-   * LinkedHashMap. Each key is a [String] or [AttributeName].
-   */
+  /// A map holding name, value pairs for attributes of the node.
+  ///
+  /// Note that attribute order needs to be stable for serialization, so we use
+  /// a LinkedHashMap. Each key is a [String] or [AttributeName].
   LinkedHashMap<dynamic, String> attributes = new LinkedHashMap();
 
-  /**
-   * A list of child nodes of the current node. This must
-   * include all elements but not necessarily other node types.
-   */
+  /// A list of child nodes of the current node. This must
+  /// include all elements but not necessarily other node types.
   final NodeList nodes = new NodeList._();
 
   List<Element> _elements;
 
   // TODO(jmesserly): consider using an Expando for this, and put it in
   // dom_parsing. Need to check the performance affect.
-  /** The source span of this node, if it was created by the [HtmlParser]. */
+  /// The source span of this node, if it was created by the [HtmlParser].
   FileSpan sourceSpan;
 
-  /** The attribute spans if requested. Otherwise null. */
+  /// The attribute spans if requested. Otherwise null.
   LinkedHashMap<dynamic, FileSpan> _attributeSpans;
   LinkedHashMap<dynamic, FileSpan> _attributeValueSpans;
 
-  Node(this.tagName) {
+  /// *Deprecated* use [new Element.tag] instead.
+  @deprecated Node(String tagName) : this._(tagName);
+
+  Node._([this._tagName]) {
     nodes._parent = this;
   }
 
-  /**
-   * If [sourceSpan] is available, this contains the spans of each attribute.
-   * The span of an attribute is the entire attribute, including the name and
-   * quotes (if any). For example, the span of "attr" in `<a attr="value">`
-   * would be the text `attr="value"`.
-   */
+  /// If [sourceSpan] is available, this contains the spans of each attribute.
+  /// The span of an attribute is the entire attribute, including the name and
+  /// quotes (if any). For example, the span of "attr" in `<a attr="value">`
+  /// would be the text `attr="value"`.
   LinkedHashMap<dynamic, FileSpan> get attributeSpans {
     _ensureAttributeSpans();
     return _attributeSpans;
   }
 
-  /**
-   * If [sourceSpan] is available, this contains the spans of each attribute's
-   * value. Unlike [attributeSpans], this span will inlcude only the value.
-   * For example, the value span of "attr" in `<a attr="value">` would be the
-   * text `value`.
-   */
+  /// If [sourceSpan] is available, this contains the spans of each attribute's
+  /// value. Unlike [attributeSpans], this span will inlcude only the value.
+  /// For example, the value span of "attr" in `<a attr="value">` would be the
+  /// text `value`.
   LinkedHashMap<dynamic, FileSpan> get attributeValueSpans {
     _ensureAttributeSpans();
     return _attributeValueSpans;
@@ -144,42 +141,54 @@
   }
 
   // TODO(jmesserly): needs to support deep clone.
-  /**
-   * Return a shallow copy of the current node i.e. a node with the same
-   * name and attributes but with no parent or child nodes.
-   */
+  /// Return a shallow copy of the current node i.e. a node with the same
+  /// name and attributes but with no parent or child nodes.
   Node clone();
 
-  String get namespace => null;
-
-  // TODO(jmesserly): do we need this here?
-  /** The value of the current node (applies to text nodes and comments). */
-  String get value => null;
-
-  // TODO(jmesserly): this is a workaround for http://dartbug.com/4754
-  int get $dom_nodeType => nodeType;
+  /// *Deprecated* use [Element.namespaceUri] instead.
+  @deprecated String get namespace => null;
 
   int get nodeType;
 
-  String get outerHtml {
+  /// *Deprecated* use [text], [Text.data] or [Comment.data].
+  @deprecated String get value => null;
+
+  /// *Deprecated* use [nodeType].
+  @deprecated int get $dom_nodeType => nodeType;
+
+  /// *Deprecated* use [Element.outerHtml]
+  @deprecated String get outerHtml => _outerHtml;
+
+  /// *Deprecated* use [Element.innerHtml]
+  @deprecated String get innerHtml => _innerHtml;
+  @deprecated set innerHtml(String value) { _innerHtml = value; }
+
+  // http://domparsing.spec.whatwg.org/#extensions-to-the-element-interface
+  String get _outerHtml {
     var str = new StringBuffer();
     _addOuterHtml(str);
     return str.toString();
   }
 
-  String get innerHtml {
+  String get _innerHtml {
     var str = new StringBuffer();
     _addInnerHtml(str);
     return str.toString();
   }
 
-  set innerHtml(String value) {
+  set _innerHtml(String value) {
     nodes.clear();
     // TODO(jmesserly): should be able to get the same effect by adding the
     // fragment directly.
-    nodes.addAll(parseFragment(value, container: tagName).nodes);
+    nodes.addAll(parseFragment(value, container: _tagName).nodes);
   }
 
+  // Implemented per: http://dom.spec.whatwg.org/#dom-node-textcontent
+  String get text => null;
+  set text(String value) {}
+
+  void append(Node node) => nodes.add(node);
+
   Node get firstChild => nodes.isNotEmpty ? nodes[0] : null;
 
   void _addOuterHtml(StringBuffer str);
@@ -188,8 +197,6 @@
     for (Node child in nodes) child._addOuterHtml(str);
   }
 
-  String toString() => tagName;
-
   Node remove() {
     // TODO(jmesserly): is parent == null an error?
     if (parent != null) {
@@ -198,12 +205,10 @@
     return this;
   }
 
-  /**
-   * Insert [node] as a child of the current node, before [refNode] in the
-   * list of child nodes. Raises [UnsupportedOperationException] if [refNode]
-   * is not a child of the current node. If refNode is null, this adds to the
-   * end of the list.
-   */
+  /// Insert [node] as a child of the current node, before [refNode] in the
+  /// list of child nodes. Raises [UnsupportedOperationException] if [refNode]
+  /// is not a child of the current node. If refNode is null, this adds to the
+  /// end of the list.
   void insertBefore(Node node, Node refNode) {
     if (refNode == null) {
       nodes.add(node);
@@ -212,7 +217,7 @@
     }
   }
 
-  /** Replaces this node with another node. */
+  /// Replaces this node with another node.
   Node replaceWith(Node otherNode) {
     if (parent == null) {
       throw new UnsupportedError('Node must have a parent to replace it.');
@@ -222,46 +227,39 @@
   }
 
   // TODO(jmesserly): should this be a property or remove?
-  /** Return true if the node has children or text. */
+  /// Return true if the node has children or text.
   bool hasContent() => nodes.length > 0;
 
-  Pair<String, String> get nameTuple {
-    var ns = namespace != null ? namespace : Namespaces.html;
-    return new Pair(ns, tagName);
-  }
+  /// *Deprecated* construct a pair using the namespaceUri and the name.
+  @deprecated Pair<String, String> get nameTuple =>
+      this is Element ? getElementNameTuple(this) : null;
 
-  /**
-   * Move all the children of the current node to [newParent].
-   * This is needed so that trees that don't store text as nodes move the
-   * text in the correct way.
-   */
+  /// Move all the children of the current node to [newParent].
+  /// This is needed so that trees that don't store text as nodes move the
+  /// text in the correct way.
   void reparentChildren(Node newParent) {
     newParent.nodes.addAll(nodes);
     nodes.clear();
   }
 
-  /** *Deprecated* use [querySelector] instead. */
+  /// *Deprecated* use [querySelector] instead.
   @deprecated
   Element query(String selectors) => querySelector(selectors);
 
-  /** *Deprecated* use [querySelectorAll] instead. */
+  /// *Deprecated* use [querySelectorAll] instead.
   @deprecated
   List<Element> queryAll(String selectors) => querySelectorAll(selectors);
 
-  /**
-   * Seaches for the first descendant node matching the given selectors, using a
-   * preorder traversal. NOTE: right now, this supports only a single type
-   * selectors, e.g. `node.query('div')`.
-   */
+  /// Seaches for the first descendant node matching the given selectors, using a
+  /// preorder traversal. NOTE: right now, this supports only a single type
+  /// selectors, e.g. `node.query('div')`.
 
   Element querySelector(String selectors) =>
       _queryType(_typeSelector(selectors));
 
-  /**
-   * Returns all descendant nodes matching the given selectors, using a
-   * preorder traversal. NOTE: right now, this supports only a single type
-   * selectors, e.g. `node.queryAll('div')`.
-   */
+  /// Returns all descendant nodes matching the given selectors, using a
+  /// preorder traversal. NOTE: right now, this supports only a single type
+  /// selectors, e.g. `node.queryAll('div')`.
   List<Element> querySelectorAll(String selectors) {
     var results = new List<Element>();
     _queryAllType(_typeSelector(selectors), results);
@@ -280,12 +278,10 @@
     return selectors;
   }
 
-  /**
-   * Checks if this is a type selector.
-   * See <http://www.w3.org/TR/CSS2/grammar.html>.
-   * Note: this doesn't support '*', the universal selector, non-ascii chars or
-   * escape chars.
-   */
+  /// Checks if this is a type selector.
+  /// See <http://www.w3.org/TR/CSS2/grammar.html>.
+  /// Note: this doesn't support '*', the universal selector, non-ascii chars or
+  /// escape chars.
   bool _isTypeSelector(String selector) {
     // Parser:
 
@@ -325,7 +321,7 @@
   Element _queryType(String tag) {
     for (var node in nodes) {
       if (node is! Element) continue;
-      if (node.tagName == tag) return node;
+      if (node.localName == tag) return node;
       var result = node._queryType(tag);
       if (result != null) return result;
     }
@@ -335,12 +331,12 @@
   void _queryAllType(String tag, List<Element> results) {
     for (var node in nodes) {
       if (node is! Element) continue;
-      if (node.tagName == tag) results.add(node);
+      if (node.localName == tag) results.add(node);
       node._queryAllType(tag, results);
     }
   }
 
-  /** Initialize [attributeSpans] using [sourceSpan]. */
+  /// Initialize [attributeSpans] using [sourceSpan].
   void _ensureAttributeSpans() {
     if (_attributeSpans != null) return;
 
@@ -370,7 +366,7 @@
 }
 
 class Document extends Node {
-  Document() : super(null);
+  Document() : super._();
   factory Document.html(String html) => parse(html);
 
   int get nodeType => Node.DOCUMENT_NODE;
@@ -380,6 +376,14 @@
   Element get head => documentElement.querySelector('head');
   Element get body => documentElement.querySelector('body');
 
+  /// Returns a fragment of HTML or XML that represents the element and its
+  /// contents.
+  // TODO(jmesserly): this API is not specified in:
+  // <http://domparsing.spec.whatwg.org/> nor is it in dart:html, instead
+  // only Element has outerHtml. However it is quite useful. Should we move it
+  // to dom_parsing, where we keep other custom APIs?
+  String get outerHtml => _outerHtml;
+
   String toString() => "#document";
 
   void _addOuterHtml(StringBuffer str) => _addInnerHtml(str);
@@ -396,13 +400,19 @@
   String toString() => "#document-fragment";
 
   DocumentFragment clone() => new DocumentFragment();
+
+  String get text => _getText(this);
+  set text(String value) => _setText(this, value);
 }
 
 class DocumentType extends Node {
+  final String name;
   final String publicId;
   final String systemId;
 
-  DocumentType(String name, this.publicId, this.systemId) : super(name);
+  DocumentType(String name, this.publicId, this.systemId)
+      // Note: once Node.tagName is removed, don't pass "name" to super
+      : name = name, super._(name);
 
   int get nodeType => Node.DOCUMENT_TYPE_NODE;
 
@@ -412,9 +422,9 @@
       // it seems useful, and the parser can handle it, so for now keeping it.
       var pid = publicId != null ? publicId : '';
       var sid = systemId != null ? systemId : '';
-      return '<!DOCTYPE $tagName "$pid" "$sid">';
+      return '<!DOCTYPE $name "$pid" "$sid">';
     } else {
-      return '<!DOCTYPE $tagName>';
+      return '<!DOCTYPE $name>';
     }
   }
 
@@ -423,39 +433,44 @@
     str.write(toString());
   }
 
-  DocumentType clone() => new DocumentType(tagName, publicId, systemId);
+  DocumentType clone() => new DocumentType(name, publicId, systemId);
 }
 
 class Text extends Node {
-  // TODO(jmesserly): this should be text?
-  String value;
+  String data;
 
-  Text(this.value) : super(null);
+  Text(this.data) : super._();
+
+  /// *Deprecated* use [data].
+  @deprecated String get value => data;
+  @deprecated set value(String x) { data = x; }
 
   int get nodeType => Node.TEXT_NODE;
 
-  String toString() => '"$value"';
+  String toString() => '"$data"';
 
-  void _addOuterHtml(StringBuffer str) {
-    // Don't escape text for certain elements, notably <script>.
-    if (rcdataElements.contains(parent.tagName) ||
-        parent.tagName == 'plaintext') {
-      str.write(value);
-    } else {
-      str.write(htmlSerializeEscape(value));
-    }
-  }
+  void _addOuterHtml(StringBuffer str) => writeTextNodeAsHtml(str, this);
 
-  Text clone() => new Text(value);
+  Text clone() => new Text(data);
+
+  String get text => data;
+  set text(String value) { data = value; }
 }
 
 class Element extends Node {
-  final String namespace;
+  final String namespaceUri;
 
-  // TODO(jmesserly): deprecate in favor of Element.tag? Or rename?
-  Element(String name, [this.namespace]) : super(name);
+  @deprecated String get namespace => namespaceUri;
 
-  Element.tag(String name) : namespace = null, super(name);
+  /// The [local name](http://dom.spec.whatwg.org/#concept-element-local-name)
+  /// of this element.
+  String get localName => _tagName;
+
+  // TODO(jmesserly): deprecate in favor of [Document.createElementNS].
+  // However we need every element to have a Document before this can work.
+  Element(String name, [this.namespaceUri]) : super._(name);
+
+  Element.tag(String name) : namespaceUri = null, super._(name);
 
   static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 
@@ -514,22 +529,37 @@
   int get nodeType => Node.ELEMENT_NODE;
 
   String toString() {
-    if (namespace == null) return "<$tagName>";
-    return "<${Namespaces.getPrefix(namespace)} $tagName>";
+    if (namespaceUri == null) return "<$localName>";
+    return "<${Namespaces.getPrefix(namespaceUri)} $localName>";
   }
 
+  String get text => _getText(this);
+  set text(String value) => _setText(this, value);
+
+  /// Returns a fragment of HTML or XML that represents the element and its
+  /// contents.
+  String get outerHtml => _outerHtml;
+
+  /// Returns a fragment of HTML or XML that represents the element's contents.
+  /// Can be set, to replace the contents of the element with nodes parsed from
+  /// the given string.
+  String get innerHtml => _innerHtml;
+  // TODO(jmesserly): deprecate in favor of:
+  // <https://api.dartlang.org/apidocs/channels/stable/#dart-dom-html.Element@id_setInnerHtml>
+  set innerHtml(String value) { _innerHtml = value; }
+
   void _addOuterHtml(StringBuffer str) {
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
     // Element is the most complicated one.
-    if (namespace == null ||
-        namespace == Namespaces.html ||
-        namespace == Namespaces.mathml ||
-        namespace == Namespaces.svg) {
-      str.write('<$tagName');
+    if (namespaceUri == null ||
+        namespaceUri == Namespaces.html ||
+        namespaceUri == Namespaces.mathml ||
+        namespaceUri == Namespaces.svg) {
+      str.write('<$localName');
     } else {
       // TODO(jmesserly): the spec doesn't define "qualified name".
       // I'm not sure if this is correct, but it should parse reasonably.
-      str.write('<${Namespaces.getPrefix(namespace)}:$tagName');
+      str.write('<${Namespaces.getPrefix(namespaceUri)}:$localName');
     }
 
     if (attributes.length > 0) {
@@ -543,8 +573,10 @@
     str.write('>');
 
     if (nodes.length > 0) {
-      if (tagName == 'pre' || tagName == 'textarea' || tagName == 'listing') {
-        if (nodes[0] is Text && nodes[0].value.startsWith('\n')) {
+      if (localName == 'pre' || localName == 'textarea' ||
+          localName == 'listing') {
+        final first = nodes[0];
+        if (first is Text && first.data.startsWith('\n')) {
           // These nodes will remove a leading \n at parse time, so if we still
           // have one, it means we started with two. Add it back.
           str.write('\n');
@@ -556,10 +588,10 @@
 
     // void elements must not have an end tag
     // http://dev.w3.org/html5/markup/syntax.html#void-elements
-    if (!isVoidElement(tagName)) str.write('</$tagName>');
+    if (!isVoidElement(localName)) str.write('</$localName>');
   }
 
-  Element clone() => new Element(tagName, namespace)
+  Element clone() => new Element(localName, namespaceUri)
       ..attributes = new LinkedHashMap.from(attributes);
 
   String get id {
@@ -577,9 +609,9 @@
 }
 
 class Comment extends Node {
-  final String data;
+  String data;
 
-  Comment(this.data) : super(null);
+  Comment(this.data) : super._();
 
   int get nodeType => Node.COMMENT_NODE;
 
@@ -590,6 +622,11 @@
   }
 
   Comment clone() => new Comment(data);
+
+  String get text => data;
+  set text(String value) {
+    this.data = value;
+  }
 }
 
 
@@ -697,10 +734,8 @@
 }
 
 
-/**
- * An indexable collection of a node's descendants in the document tree,
- * filtered so that only elements are in the collection.
- */
+/// An indexable collection of a node's descendants in the document tree,
+/// filtered so that only elements are in the collection.
 // TODO(jmesserly): this was copied from dart:html
 // TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug.
 class FilteredElementList extends IterableBase<Element> with ListMixin<Element>
@@ -709,14 +744,12 @@
   final Node _node;
   final List<Node> _childNodes;
 
-  /**
-   * Creates a collection of the elements that descend from a node.
-   *
-   * Example usage:
-   *
-   *     var filteredElements = new FilteredElementList(query("#container"));
-   *     // filteredElements is [a, b, c].
-   */
+  /// Creates a collection of the elements that descend from a node.
+  ///
+  /// Example usage:
+  ///
+  ///     var filteredElements = new FilteredElementList(query("#container"));
+  ///     // filteredElements is [a, b, c].
   FilteredElementList(Node node): _childNodes = node.nodes, _node = node;
 
   // We can't memoize this, since it's possible that children will be messed
@@ -881,3 +914,23 @@
 
   Element get single => _filtered.single;
 }
+
+// http://dom.spec.whatwg.org/#dom-node-textcontent
+// For Element and DocumentFragment
+String _getText(Node node) =>
+    (new _ConcatTextVisitor()..visit(node)).toString();
+
+void _setText(Node node, String value) {
+  node.nodes.clear();
+  node.append(new Text(value));
+}
+
+class _ConcatTextVisitor extends TreeVisitor {
+  final _str = new StringBuffer();
+
+  String toString() => _str.toString();
+
+  visitText(Text node) {
+    _str.write(node.data);
+  }
+}
diff --git a/pkg/third_party/html5lib/lib/dom_parsing.dart b/pkg/third_party/html5lib/lib/dom_parsing.dart
index 3ff74bb..aed9fff 100644
--- a/pkg/third_party/html5lib/lib/dom_parsing.dart
+++ b/pkg/third_party/html5lib/lib/dom_parsing.dart
@@ -1,12 +1,11 @@
-/**
- * This library contains extra APIs that aren't in the DOM, but are useful
- * when interacting with the parse tree.
- */
+/// This library contains extra APIs that aren't in the DOM, but are useful
+/// when interacting with the parse tree.
 library dom_parsing;
 
 import 'dom.dart';
+import 'src/constants.dart' show rcdataElements;
 
-/** A simple tree visitor for the DOM nodes. */
+/// A simple tree visitor for the DOM nodes.
 class TreeVisitor {
   visit(Node node) {
     switch (node.nodeType) {
@@ -25,11 +24,9 @@
     for (var child in node.nodes.toList()) visit(child);
   }
 
-  /**
-   * The fallback handler if the more specific visit method hasn't been
-   * overriden. Only use this from a subclass of [TreeVisitor], otherwise
-   * call [visit] instead.
-   */
+  /// The fallback handler if the more specific visit method hasn't been
+  /// overriden. Only use this from a subclass of [TreeVisitor], otherwise
+  /// call [visit] instead.
   visitNodeFallback(Node node) => visitChildren(node);
 
   visitDocument(Document node) => visitNodeFallback(node);
@@ -47,20 +44,16 @@
   visitDocumentFragment(DocumentFragment node) => visitDocument(node);
 }
 
-/**
- * Converts the DOM tree into an HTML string with code markup suitable for
- * displaying the HTML's source code with CSS colors for different parts of the
- * markup. See also [CodeMarkupVisitor].
- */
+/// Converts the DOM tree into an HTML string with code markup suitable for
+/// displaying the HTML's source code with CSS colors for different parts of the
+/// markup. See also [CodeMarkupVisitor].
 String htmlToCodeMarkup(Node node) {
   return (new CodeMarkupVisitor()..visit(node)).toString();
 }
 
-/**
- * Converts the DOM tree into an HTML string with code markup suitable for
- * displaying the HTML's source code with CSS colors for different parts of the
- * markup. See also [htmlToCodeMarkup].
- */
+/// Converts the DOM tree into an HTML string with code markup suitable for
+/// displaying the HTML's source code with CSS colors for different parts of the
+/// markup. See also [htmlToCodeMarkup].
 class CodeMarkupVisitor extends TreeVisitor {
   final StringBuffer _str;
 
@@ -75,17 +68,17 @@
   }
 
   visitDocumentType(DocumentType node) {
-    _str.write('<code class="markup doctype">&lt;!DOCTYPE ${node.tagName}>'
+    _str.write('<code class="markup doctype">&lt;!DOCTYPE ${node.name}>'
         '</code>');
   }
 
   visitText(Text node) {
-    // TODO(jmesserly): would be nice to use _addOuterHtml directly.
-    _str.write(node.outerHtml);
+    writeTextNodeAsHtml(_str, node);
   }
 
   visitElement(Element node) {
-    _str.write('&lt;<code class="markup element-name">${node.tagName}</code>');
+    final tag = node.localName;
+    _str.write('&lt;<code class="markup element-name">$tag</code>');
     if (node.attributes.length > 0) {
       node.attributes.forEach((key, v) {
         v = htmlSerializeEscape(v, attributeMode: true);
@@ -96,12 +89,12 @@
     if (node.nodes.length > 0) {
       _str.write(">");
       visitChildren(node);
-    } else if (isVoidElement(node.tagName)) {
+    } else if (isVoidElement(tag)) {
       _str.write(">");
       return;
     }
     _str.write(
-        '&lt;/<code class="markup element-name">${node.tagName}</code>>');
+        '&lt;/<code class="markup element-name">$tag</code>>');
   }
 
   visitComment(Comment node) {
@@ -113,23 +106,21 @@
 
 // TODO(jmesserly): reconcile this with dart:web htmlEscape.
 // This one might be more useful, as it is HTML5 spec compliant.
-/**
- * Escapes [text] for use in the
- * [HTML fragment serialization algorithm][1]. In particular, as described
- * in the [specification][2]:
- *
- * - Replace any occurrence of the `&` character by the string `&amp;`.
- * - Replace any occurrences of the U+00A0 NO-BREAK SPACE character by the
- *   string `&nbsp;`.
- * - If the algorithm was invoked in [attributeMode], replace any occurrences of
- *   the `"` character by the string `&quot;`.
- * - If the algorithm was not invoked in [attributeMode], replace any
- *   occurrences of the `<` character by the string `&lt;`, and any occurrences
- *   of the `>` character by the string `&gt;`.
- *
- * [1]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
- * [2]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
- */
+/// Escapes [text] for use in the
+/// [HTML fragment serialization algorithm][1]. In particular, as described
+/// in the [specification][2]:
+///
+/// - Replace any occurrence of the `&` character by the string `&amp;`.
+/// - Replace any occurrences of the U+00A0 NO-BREAK SPACE character by the
+///   string `&nbsp;`.
+/// - If the algorithm was invoked in [attributeMode], replace any occurrences
+///   of the `"` character by the string `&quot;`.
+/// - If the algorithm was not invoked in [attributeMode], replace any
+///   occurrences of the `<` character by the string `&lt;`, and any occurrences
+///   of the `>` character by the string `&gt;`.
+///
+/// [1]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
+/// [2]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
 String htmlSerializeEscape(String text, {bool attributeMode: false}) {
   // TODO(jmesserly): is it faster to build up a list of codepoints?
   // StringBuffer seems cleaner assuming Dart can unbox 1-char strings.
@@ -156,12 +147,10 @@
 }
 
 
-/**
- * Returns true if this tag name is a void element.
- * This method is useful to a pretty printer, because void elements must not
- * have an end tag.
- * See <http://dev.w3.org/html5/markup/syntax.html#void-elements> for more info.
- */
+/// Returns true if this tag name is a void element.
+/// This method is useful to a pretty printer, because void elements must not
+/// have an end tag.
+/// See also: <http://dev.w3.org/html5/markup/syntax.html#void-elements>.
 bool isVoidElement(String tagName) {
   switch (tagName) {
     case "area": case "base": case "br": case "col": case "command":
@@ -172,3 +161,18 @@
   }
   return false;
 }
+
+/// Serialize text node according to:
+/// <http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm>
+void writeTextNodeAsHtml(StringBuffer str, Text node) {
+  // Don't escape text for certain elements, notably <script>.
+  final parent = node.parent;
+  if (parent is Element) {
+    var tag = parent.localName;
+    if (rcdataElements.contains(tag) || tag == 'plaintext') {
+      str.write(node.data);
+      return;
+    }
+  }
+  str.write(htmlSerializeEscape(node.data));
+}
diff --git a/pkg/third_party/html5lib/lib/parser.dart b/pkg/third_party/html5lib/lib/parser.dart
index 4e5e6d5..2d04f8e 100644
--- a/pkg/third_party/html5lib/lib/parser.dart
+++ b/pkg/third_party/html5lib/lib/parser.dart
@@ -1,18 +1,16 @@
-/**
- * This library has a parser for HTML5 documents, that lets you parse HTML
- * easily from a script or server side application:
- *
- *     import 'package:html5lib/parser.dart' show parse;
- *     import 'package:html5lib/dom.dart';
- *     main() {
- *       var document = parse(
- *           '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
- *       print(document.outerHtml);
- *     }
- *
- * The resulting document you get back has a DOM-like API for easy tree
- * traversal and manipulation.
- */
+/// This library has a parser for HTML5 documents, that lets you parse HTML
+/// easily from a script or server side application:
+///
+///     import 'package:html5lib/parser.dart' show parse;
+///     import 'package:html5lib/dom.dart';
+///     main() {
+///       var document = parse(
+///           '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
+///       print(document.outerHtml);
+///     }
+///
+/// The resulting document you get back has a DOM-like API for easy tree
+/// traversal and manipulation.
 library parser;
 
 import 'dart:collection';
@@ -27,19 +25,17 @@
 import 'src/utils.dart';
 import 'dom.dart';
 
-/**
- * Parse the [input] html5 document into a tree. The [input] can be
- * a [String], [List<int>] of bytes or an [HtmlTokenizer].
- *
- * If [input] is not a [HtmlTokenizer], you can optionally specify the file's
- * [encoding], which must be a string. If specified, that encoding will be used,
- * regardless of any BOM or later declaration (such as in a meta element).
- *
- * Set [generateSpans] if you want to generate [Span]s, otherwise the
- * [Node.sourceSpan] property will be `null`. When using [generateSpans] you can
- * additionally pass [sourceUrl] to indicate where the [input] was extracted
- * from.
- */
+/// Parse the [input] html5 document into a tree. The [input] can be
+/// a [String], [List<int>] of bytes or an [HtmlTokenizer].
+///
+/// If [input] is not a [HtmlTokenizer], you can optionally specify the file's
+/// [encoding], which must be a string. If specified that encoding will be
+/// used regardless of any BOM or later declaration (such as in a meta element).
+///
+/// Set [generateSpans] if you want to generate [Span]s, otherwise the
+/// [Node.sourceSpan] property will be `null`. When using [generateSpans] you
+/// can additionally pass [sourceUrl] to indicate where the [input] was
+/// extracted from.
 Document parse(input, {String encoding, bool generateSpans: false,
     String sourceUrl}) {
   var p = new HtmlParser(input, encoding: encoding,
@@ -48,20 +44,18 @@
 }
 
 
-/**
- * Parse the [input] html5 document fragment into a tree. The [input] can be
- * a [String], [List<int>] of bytes or an [HtmlTokenizer]. The [container]
- * element can optionally be specified, otherwise it defaults to "div".
- *
- * If [input] is not a [HtmlTokenizer], you can optionally specify the file's
- * [encoding], which must be a string. If specified, that encoding will be used,
- * regardless of any BOM or later declaration (such as in a meta element).
- *
- * Set [generateSpans] if you want to generate [Span]s, otherwise the
- * [Node.sourceSpan] property will be `null`. When using [generateSpans] you can
- * additionally pass [sourceUrl] to indicate where the [input] was extracted
- * from.
- */
+/// Parse the [input] html5 document fragment into a tree. The [input] can be
+/// a [String], [List<int>] of bytes or an [HtmlTokenizer]. The [container]
+/// element can optionally be specified, otherwise it defaults to "div".
+///
+/// If [input] is not a [HtmlTokenizer], you can optionally specify the file's
+/// [encoding], which must be a string. If specified, that encoding will be used,
+/// regardless of any BOM or later declaration (such as in a meta element).
+///
+/// Set [generateSpans] if you want to generate [Span]s, otherwise the
+/// [Node.sourceSpan] property will be `null`. When using [generateSpans] you can
+/// additionally pass [sourceUrl] to indicate where the [input] was extracted
+/// from.
 DocumentFragment parseFragment(input, {String container: "div",
     String encoding, bool generateSpans: false, String sourceUrl}) {
   var p = new HtmlParser(input, encoding: encoding,
@@ -70,15 +64,13 @@
 }
 
 
-/**
- * Parser for HTML, which generates a tree structure from a stream of
- * (possibly malformed) characters.
- */
+/// Parser for HTML, which generates a tree structure from a stream of
+/// (possibly malformed) characters.
 class HtmlParser {
-  /** Raise an exception on the first error encountered. */
+  /// Raise an exception on the first error encountered.
   final bool strict;
 
-  /** True to generate [Span]s for the [Node.sourceSpan] property. */
+  /// True to generate [Span]s for the [Node.sourceSpan] property.
   final bool generateSpans;
 
   final HtmlTokenizer tokenizer;
@@ -92,10 +84,10 @@
   bool firstStartTag = false;
 
   // TODO(jmesserly): use enum?
-  /** "quirks" / "limited quirks" / "no quirks" */
+  /// "quirks" / "limited quirks" / "no quirks"
   String compatMode = "no quirks";
 
-  /** innerHTML container when parsing document fragment. */
+  /// innerHTML container when parsing document fragment.
   String innerHTML;
 
   Phase phase;
@@ -133,23 +125,21 @@
   AfterAfterBodyPhase _afterAfterBodyPhase;
   AfterAfterFramesetPhase _afterAfterFramesetPhase;
 
-  /**
-   * Create a new HtmlParser and configure the [tree] builder and [strict] mode.
-   * The [input] can be a [String], [List<int>] of bytes or an [HtmlTokenizer].
-   *
-   * If [input] is not a [HtmlTokenizer], you can specify a few more arguments.
-   *
-   * The [encoding] must be a string that indicates the encoding. If specified,
-   * that encoding will be used, regardless of any BOM or later declaration
-   * (such as in a meta element).
-   *
-   * Set [parseMeta] to false if you want to disable parsing the meta element.
-   *
-   * Set [lowercaseElementName] or [lowercaseAttrName] to false to disable the
-   * automatic conversion of element and attribute names to lower case. Note
-   * that standard way to parse HTML is to lowercase, which is what the browser
-   * DOM will do if you request [Node.outerHTML], for example.
-   */
+  /// Create an HtmlParser and configure the [tree] builder and [strict] mode.
+  /// The [input] can be a [String], [List<int>] of bytes or an [HtmlTokenizer].
+  ///
+  /// If [input] is not a [HtmlTokenizer], you can specify a few more arguments.
+  ///
+  /// The [encoding] must be a string that indicates the encoding. If specified,
+  /// that encoding will be used, regardless of any BOM or later declaration
+  /// (such as in a meta element).
+  ///
+  /// Set [parseMeta] to false if you want to disable parsing the meta element.
+  ///
+  /// Set [lowercaseElementName] or [lowercaseAttrName] to false to disable the
+  /// automatic conversion of element and attribute names to lower case. Note
+  /// that standard way to parse HTML is to lowercase, which is what the browser
+  /// DOM will do if you request [Node.outerHTML], for example.
   HtmlParser(input, {String encoding, bool parseMeta: true,
       bool lowercaseElementName: true, bool lowercaseAttrName: true,
       this.strict: false, bool generateSpans: false, String sourceUrl,
@@ -194,21 +184,17 @@
 
   bool get innerHTMLMode => innerHTML != null;
 
-  /**
-   * Parse an html5 document into a tree.
-   * After parsing, [errors] will be populated with parse errors, if any.
-   */
+  /// Parse an html5 document into a tree.
+  /// After parsing, [errors] will be populated with parse errors, if any.
   Document parse() {
     innerHTML = null;
     _parse();
     return tree.getDocument();
   }
 
-  /**
-   * Parse an html5 document fragment into a tree.
-   * Pass a [container] to change the type of the containing element.
-   * After parsing, [errors] will be populated with parse errors, if any.
-   */
+  /// Parse an html5 document fragment into a tree.
+  /// Pass a [container] to change the type of the containing element.
+  /// After parsing, [errors] will be populated with parse errors, if any.
   DocumentFragment parseFragment([String container = "div"]) {
     if (container == null) throw new ArgumentError('container');
     innerHTML = container.toLowerCase();
@@ -263,28 +249,28 @@
     framesetOK = true;
   }
 
-  bool isHTMLIntegrationPoint(Node element) {
-    if (element.tagName == "annotation-xml" &&
-        element.namespace == Namespaces.mathml) {
+  bool isHTMLIntegrationPoint(Element element) {
+    if (element.localName == "annotation-xml" &&
+        element.namespaceUri == Namespaces.mathml) {
       var enc = element.attributes["encoding"];
       if (enc != null) enc = asciiUpper2Lower(enc);
       return enc == "text/html" || enc == "application/xhtml+xml";
     } else {
       return htmlIntegrationPointElements.contains(
-          new Pair(element.namespace, element.tagName));
+          new Pair(element.namespaceUri, element.localName));
     }
   }
 
-  bool isMathMLTextIntegrationPoint(Node element) {
+  bool isMathMLTextIntegrationPoint(Element element) {
     return mathmlTextIntegrationPointElements.contains(
-        new Pair(element.namespace, element.tagName));
+        new Pair(element.namespaceUri, element.localName));
   }
 
   bool inForeignContent(Token token, int type) {
     if (tree.openElements.length == 0) return false;
 
     var node = tree.openElements.last;
-    if (node.namespace == tree.defaultNamespace) return false;
+    if (node.namespaceUri == tree.defaultNamespace) return false;
 
     if (isMathMLTextIntegrationPoint(node)) {
       if (type == TokenKind.startTag &&
@@ -297,7 +283,7 @@
       }
     }
 
-    if (node.tagName == "annotation-xml" && type == TokenKind.startTag &&
+    if (node.localName == "annotation-xml" && type == TokenKind.startTag &&
         (token as StartTagToken).name == "svg") {
       return false;
     }
@@ -375,10 +361,8 @@
     }
   }
 
-  /**
-   * The last span available. Used for EOF errors if we don't have something
-   * better.
-   */
+  /// The last span available. Used for EOF errors if we don't have something
+  /// better.
   Span get _lastSpan {
     var pos = tokenizer.stream.position;
     return new FileSpan(tokenizer.stream.fileInfo, pos, pos);
@@ -507,8 +491,8 @@
   void resetInsertionMode() {
     // The name of this method is mostly historical. (It's also used in the
     // specification.)
-    for (Node node in tree.openElements.reversed) {
-      var nodeName = node.tagName;
+    for (var node in tree.openElements.reversed) {
+      var nodeName = node.localName;
       bool last = node == tree.openElements[0];
       if (last) {
         assert(innerHTMLMode);
@@ -521,7 +505,7 @@
           assert(innerHTMLMode);
           break;
       }
-      if (!last && node.namespace != tree.defaultNamespace) {
+      if (!last && node.namespaceUri != tree.defaultNamespace) {
         continue;
       }
       switch (nodeName) {
@@ -544,10 +528,8 @@
     phase = _inBodyPhase;
   }
 
-  /**
-   * Generic RCDATA/RAWTEXT Parsing algorithm
-   * [contentType] - RCDATA or RAWTEXT
-   */
+  /// Generic RCDATA/RAWTEXT Parsing algorithm
+  /// [contentType] - RCDATA or RAWTEXT
   void parseRCDataRawtext(Token token, String contentType) {
     assert(contentType == "RAWTEXT" || contentType == "RCDATA");
 
@@ -565,7 +547,7 @@
 }
 
 
-/** Base class for helper object that implements each phase of processing. */
+/// Base class for helper object that implements each phase of processing.
 class Phase {
   // Order should be (they can be omitted):
   // * EOF
@@ -592,18 +574,22 @@
     // For most phases the following is correct. Where it's not it will be
     // overridden.
     tree.insertComment(token, tree.openElements.last);
+    return null;
   }
 
   Token processDoctype(DoctypeToken token) {
     parser.parseError(token.span, "unexpected-doctype");
+    return null;
   }
 
   Token processCharacters(CharactersToken token) {
     tree.insertText(token.data, token.span);
+    return null;
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
     tree.insertText(token.data, token.span);
+    return null;
   }
 
   Token processStartTag(StartTagToken token) {
@@ -620,16 +606,17 @@
       tree.openElements[0].attributes.putIfAbsent(attr, () => value);
     });
     parser.firstStartTag = false;
+    return null;
   }
 
   Token processEndTag(EndTagToken token) {
     throw new UnimplementedError();
   }
 
-  /** Helper method for popping openElements. */
+  /// Helper method for popping openElements.
   void popOpenElementsUntil(String name) {
     var node = tree.openElements.removeLast();
-    while (node.tagName != name) {
+    while (node.localName != name) {
       node = tree.openElements.removeLast();
     }
   }
@@ -639,10 +626,12 @@
   InitialPhase(parser) : super(parser);
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
   }
 
   Token processComment(CommentToken token) {
     tree.insertComment(token, tree.document);
+    return null;
   }
 
   Token processDoctype(DoctypeToken token) {
@@ -743,6 +732,7 @@
       parser.compatMode = "limited quirks";
     }
     parser.phase = parser._beforeHtmlPhase;
+    return null;
   }
 
   void anythingElse() {
@@ -795,9 +785,11 @@
 
   Token processComment(CommentToken token) {
     tree.insertComment(token, tree.document);
+    return null;
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
   }
 
   Token processCharacters(CharactersToken token) {
@@ -852,6 +844,7 @@
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
   }
 
   Token processCharacters(CharactersToken token) {
@@ -978,7 +971,7 @@
 
   void endTagHead(EndTagToken token) {
     var node = parser.tree.openElements.removeLast();
-    assert(node.tagName == "head");
+    assert(node.localName == "head");
     parser.phase = parser._afterHeadPhase;
   }
 
@@ -1056,8 +1049,8 @@
       {"name": token.name});
     tree.openElements.add(tree.headPointer);
     parser._inHeadPhase.processStartTag(token);
-    for (Node node in tree.openElements.reversed) {
-      if (node.tagName == "head") {
+    for (var node in tree.openElements.reversed) {
+      if (node.localName == "head") {
         tree.openElements.remove(node);
         break;
       }
@@ -1203,8 +1196,9 @@
     }
   }
 
-  bool isMatchingFormattingElement(Node node1, Node node2) {
-    if (node1.tagName != node2.tagName || node1.namespace != node2.namespace) {
+  bool isMatchingFormattingElement(Element node1, Element node2) {
+    if (node1.localName != node2.localName ||
+        node1.namespaceUri != node2.namespaceUri) {
       return false;
     } else if (node1.attributes.length != node2.attributes.length) {
       return false;
@@ -1241,8 +1235,8 @@
 
   // the real deal
   bool processEOF() {
-    for (Node node in tree.openElements.reversed) {
-      switch (node.tagName) {
+    for (var node in tree.openElements.reversed) {
+      switch (node.localName) {
         case "dd": case "dt": case "li": case "p": case "tbody": case "td":
         case "tfoot": case "th": case "thead": case "tr": case "body":
         case "html":
@@ -1262,7 +1256,7 @@
     dropNewline = false;
     if (data.startsWith("\n")) {
       var lastOpen = tree.openElements.last;
-      if (const ["pre", "listing", "textarea"].contains(lastOpen.tagName)
+      if (const ["pre", "listing", "textarea"].contains(lastOpen.localName)
           && !lastOpen.hasContent()) {
         data = data.substring(1);
       }
@@ -1303,7 +1297,7 @@
   void startTagBody(StartTagToken token) {
     parser.parseError(token.span, "unexpected-start-tag", {"name": "body"});
     if (tree.openElements.length == 1
-        || tree.openElements[1].tagName != "body") {
+        || tree.openElements[1].localName != "body") {
       assert(parser.innerHTMLMode);
     } else {
       parser.framesetOK = false;
@@ -1316,13 +1310,13 @@
   void startTagFrameset(StartTagToken token) {
     parser.parseError(token.span, "unexpected-start-tag", {"name": "frameset"});
     if ((tree.openElements.length == 1 ||
-        tree.openElements[1].tagName != "body")) {
+        tree.openElements[1].localName != "body")) {
       assert(parser.innerHTMLMode);
     } else if (parser.framesetOK) {
       if (tree.openElements[1].parent != null) {
         tree.openElements[1].parent.nodes.remove(tree.openElements[1]);
       }
-      while (tree.openElements.last.tagName != "html") {
+      while (tree.openElements.last.localName != "html") {
         tree.openElements.removeLast();
       }
       tree.insertElement(token);
@@ -1365,13 +1359,13 @@
                                 "dt": const ["dt", "dd"],
                                 "dd": const ["dt", "dd"]};
     var stopNames = stopNamesMap[token.name];
-    for (Node node in tree.openElements.reversed) {
-      if (stopNames.contains(node.tagName)) {
-        parser.phase.processEndTag(new EndTagToken(node.tagName));
+    for (var node in tree.openElements.reversed) {
+      if (stopNames.contains(node.localName)) {
+        parser.phase.processEndTag(new EndTagToken(node.localName));
         break;
       }
-      if (specialElements.contains(node.nameTuple) &&
-          !const ["address", "div", "p"].contains(node.tagName)) {
+      if (specialElements.contains(getElementNameTuple(node)) &&
+          !const ["address", "div", "p"].contains(node.localName)) {
         break;
       }
     }
@@ -1395,7 +1389,7 @@
     if (tree.elementInScope("p", variant: "button")) {
       endTagP(new EndTagToken("p"));
     }
-    if (headingElements.contains(tree.openElements.last.tagName)) {
+    if (headingElements.contains(tree.openElements.last.localName)) {
       parser.parseError(token.span, "unexpected-start-tag",
           {"name": token.name});
       tree.openElements.removeLast();
@@ -1444,6 +1438,7 @@
       tree.insertElement(token);
       parser.framesetOK = false;
     }
+    return null;
   }
 
   void startTagAppletMarqueeObject(StartTagToken token) {
@@ -1556,13 +1551,13 @@
     startTagRawtext(token);
   }
 
-  /** iframe, noembed noframes, noscript(if scripting enabled). */
+  /// iframe, noembed noframes, noscript(if scripting enabled).
   void startTagRawtext(StartTagToken token) {
     parser.parseRCDataRawtext(token, "RAWTEXT");
   }
 
   void startTagOpt(StartTagToken token) {
-    if (tree.openElements.last.tagName == "option") {
+    if (tree.openElements.last.localName == "option") {
       parser.phase.processEndTag(new EndTagToken("option"));
     }
     tree.reconstructActiveFormattingElements();
@@ -1590,7 +1585,7 @@
     if (tree.elementInScope("ruby")) {
       tree.generateImpliedEndTags();
       var last = tree.openElements.last;
-      if (last.tagName != "ruby") {
+      if (last.localName != "ruby") {
         parser.parseError(last.sourceSpan, 'undefined-error');
       }
     }
@@ -1625,13 +1620,11 @@
     }
   }
 
-  /**
-   * Elements that should be children of other elements that have a
-   * different insertion mode; here they are ignored
-   * "caption", "col", "colgroup", "frame", "frameset", "head",
-   * "option", "optgroup", "tbody", "td", "tfoot", "th", "thead",
-   * "tr", "noscript"
-  */
+  /// Elements that should be children of other elements that have a
+  /// different insertion mode; here they are ignored
+  /// "caption", "col", "colgroup", "frame", "frameset", "head",
+  /// "option", "optgroup", "tbody", "td", "tfoot", "th", "thead",
+  /// "tr", "noscript"
   void startTagMisplaced(StartTagToken token) {
     parser.parseError(token.span, "unexpected-start-tag-ignored",
         {"name": token.name});
@@ -1640,6 +1633,7 @@
   Token startTagOther(StartTagToken token) {
     tree.reconstructActiveFormattingElements();
     tree.insertElement(token);
+    return null;
   }
 
   void endTagP(EndTagToken token) {
@@ -1649,7 +1643,7 @@
       endTagP(new EndTagToken("p"));
     } else {
       tree.generateImpliedEndTags("p");
-      if (tree.openElements.last.tagName != "p") {
+      if (tree.openElements.last.localName != "p") {
         parser.parseError(token.span, "unexpected-end-tag", {"name": "p"});
       }
       popOpenElementsUntil("p");
@@ -1660,9 +1654,9 @@
     if (!tree.elementInScope("body")) {
       parser.parseError(token.span, 'undefined-error');
       return;
-    } else if (tree.openElements.last.tagName != "body") {
-      for (Node node in slice(tree.openElements, 2)) {
-        switch (node.tagName) {
+    } else if (tree.openElements.last.localName != "body") {
+      for (Element node in slice(tree.openElements, 2)) {
+        switch (node.localName) {
           case "dd": case "dt": case "li": case "optgroup": case "option":
           case "p": case "rp": case "rt": case "tbody": case "td": case "tfoot":
           case "th": case "thead": case "tr": case "body": case "html":
@@ -1670,7 +1664,7 @@
         }
         // Not sure this is the correct name for the parse error
         parser.parseError(token.span, "expected-one-end-tag-but-got-another",
-            {"expectedName": "body", "gotName": node.tagName});
+            {"gotName": "body", "expectedName": node.localName});
         break;
       }
     }
@@ -1683,6 +1677,7 @@
       endTagBody(new EndTagToken("body"));
       return token;
     }
+    return null;
   }
 
   void endTagBlock(EndTagToken token) {
@@ -1694,7 +1689,7 @@
     if (inScope) {
       tree.generateImpliedEndTags();
     }
-    if (tree.openElements.last.tagName != token.name) {
+    if (tree.openElements.last.localName != token.name) {
       parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
     }
     if (inScope) {
@@ -1727,7 +1722,7 @@
       parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
     } else {
       tree.generateImpliedEndTags(token.name);
-      if (tree.openElements.last.tagName != token.name) {
+      if (tree.openElements.last.localName != token.name) {
         parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
       }
       popOpenElementsUntil(token.name);
@@ -1741,22 +1736,22 @@
         break;
       }
     }
-    if (tree.openElements.last.tagName != token.name) {
+    if (tree.openElements.last.localName != token.name) {
       parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
     }
 
     for (var item in headingElements) {
       if (tree.elementInScope(item)) {
-        item = tree.openElements.removeLast();
-        while (!headingElements.contains(item.tagName)) {
-          item = tree.openElements.removeLast();
+        var node = tree.openElements.removeLast();
+        while (!headingElements.contains(node.localName)) {
+          node = tree.openElements.removeLast();
         }
         break;
       }
     }
   }
 
-  /** The much-feared adoption agency algorithm. */
+  /// The much-feared adoption agency algorithm.
   endTagFormatting(EndTagToken token) {
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency
     // TODO(jmesserly): the comments here don't match the numbered steps in the
@@ -1772,7 +1767,7 @@
           token.name);
       if (formattingElement == null ||
           (tree.openElements.contains(formattingElement) &&
-           !tree.elementInScope(formattingElement.tagName))) {
+           !tree.elementInScope(formattingElement.localName))) {
         parser.parseError(token.span, "adoption-agency-1.1",
             {"name": token.name});
         return;
@@ -1795,7 +1790,7 @@
       var afeIndex = tree.openElements.indexOf(formattingElement);
       Node furthestBlock = null;
       for (Node element in slice(tree.openElements, afeIndex)) {
-        if (specialElements.contains(element.nameTuple)) {
+        if (specialElements.contains(getElementNameTuple(element))) {
           furthestBlock = element;
           break;
         }
@@ -1872,7 +1867,7 @@
       }
 
       if (const ["table", "tbody", "tfoot", "thead", "tr"].contains(
-          commonAncestor.tagName)) {
+          commonAncestor.localName)) {
         var nodePos = tree.getTableMisnestedNodePosition();
         nodePos[0].insertBefore(lastNode, nodePos[1]);
       } else {
@@ -1904,7 +1899,7 @@
     if (tree.elementInScope(token.name)) {
       tree.generateImpliedEndTags();
     }
-    if (tree.openElements.last.tagName != token.name) {
+    if (tree.openElements.last.localName != token.name) {
       parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
     }
     if (tree.elementInScope(token.name)) {
@@ -1922,17 +1917,17 @@
   }
 
   void endTagOther(EndTagToken token) {
-    for (Node node in tree.openElements.reversed) {
-      if (node.tagName == token.name) {
+    for (var node in tree.openElements.reversed) {
+      if (node.localName == token.name) {
         tree.generateImpliedEndTags(token.name);
-        if (tree.openElements.last.tagName != token.name) {
+        if (tree.openElements.last.localName != token.name) {
           parser.parseError(token.span, "unexpected-end-tag",
               {"name": token.name});
         }
         while (tree.openElements.removeLast() != node);
         break;
       } else {
-        if (specialElements.contains(node.nameTuple)) {
+        if (specialElements.contains(getElementNameTuple(node))) {
           parser.parseError(token.span, "unexpected-end-tag",
               {"name": token.name});
           break;
@@ -1956,12 +1951,13 @@
 
   Token processCharacters(CharactersToken token) {
     tree.insertText(token.data, token.span);
+    return null;
   }
 
   bool processEOF() {
     var last = tree.openElements.last;
     parser.parseError(last.sourceSpan, "expected-named-closing-tag-but-got-eof",
-        {'name': last.tagName});
+        {'name': last.localName});
     tree.openElements.removeLast();
     parser.phase = parser.originalPhase;
     return true;
@@ -1969,7 +1965,7 @@
 
   void endTagScript(EndTagToken token) {
     var node = tree.openElements.removeLast();
-    assert(node.tagName == "script");
+    assert(node.localName == "script");
     parser.phase = parser.originalPhase;
     //The rest of this method is all stuff that only happens if
     //document.write works
@@ -2014,8 +2010,8 @@
   // helper methods
   void clearStackToTableContext() {
     // "clear the stack back to a table context"
-    while (tree.openElements.last.tagName != "table" &&
-           tree.openElements.last.tagName != "html") {
+    while (tree.openElements.last.localName != "table" &&
+           tree.openElements.last.localName != "html") {
       //parser.parseError(token.span, "unexpected-implied-end-tag-in-table",
       //  {"name":  tree.openElements.last.name})
       tree.openElements.removeLast();
@@ -2026,7 +2022,7 @@
   // processing methods
   bool processEOF() {
     var last = tree.openElements.last;
-    if (last.tagName != "html") {
+    if (last.localName != "html") {
       parser.parseError(last.sourceSpan, "eof-in-table");
     } else {
       assert(parser.innerHTMLMode);
@@ -2040,6 +2036,7 @@
     parser.phase = parser._inTableTextPhase;
     parser._inTableTextPhase.originalPhase = originalPhase;
     parser.phase.processSpaceCharacters(token);
+    return null;
   }
 
   Token processCharacters(CharactersToken token) {
@@ -2047,6 +2044,7 @@
     parser.phase = parser._inTableTextPhase;
     parser._inTableTextPhase.originalPhase = originalPhase;
     parser.phase.processCharacters(token);
+    return null;
   }
 
   void insertText(CharactersToken token) {
@@ -2093,6 +2091,7 @@
     if (!parser.innerHTMLMode) {
       return token;
     }
+    return null;
   }
 
   Token startTagStyleScript(StartTagToken token) {
@@ -2132,11 +2131,11 @@
     if (tree.elementInScope("table", variant: "table")) {
       tree.generateImpliedEndTags();
       var last = tree.openElements.last;
-      if (last.tagName != "table") {
+      if (last.localName != "table") {
         parser.parseError(token.span, "end-tag-too-early-named",
-            {"gotName": "table", "expectedName": last.tagName});
+            {"gotName": "table", "expectedName": last.localName});
       }
-      while (tree.openElements.last.tagName != "table") {
+      while (tree.openElements.last.localName != "table") {
         tree.openElements.removeLast();
       }
       tree.openElements.removeLast();
@@ -2208,12 +2207,14 @@
       return null;
     }
     characterTokens.add(token);
+    return null;
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
     //pretty sure we should never reach here
     characterTokens.add(token);
     // XXX assert(false);
+    return null;
   }
 
   Token processStartTag(StartTagToken token) {
@@ -2287,12 +2288,12 @@
     if (!ignoreEndTagCaption()) {
       // AT this code is quite similar to endTagTable in "InTable"
       tree.generateImpliedEndTags();
-      if (tree.openElements.last.tagName != "caption") {
+      if (tree.openElements.last.localName != "caption") {
         parser.parseError(token.span, "expected-one-end-tag-but-got-another",
           {"gotName": "caption",
-           "expectedName": tree.openElements.last.tagName});
+           "expectedName": tree.openElements.last.localName});
       }
-      while (tree.openElements.last.tagName != "caption") {
+      while (tree.openElements.last.localName != "caption") {
         tree.openElements.removeLast();
       }
       tree.openElements.removeLast();
@@ -2346,7 +2347,7 @@
   }
 
   bool ignoreEndTagColgroup() {
-    return tree.openElements.last.tagName == "html";
+    return tree.openElements.last.localName == "html";
   }
 
   bool processEOF() {
@@ -2431,12 +2432,12 @@
   // helper methods
   void clearStackToTableBodyContext() {
     var tableTags = const ["tbody", "tfoot", "thead", "html"];
-    while (!tableTags.contains(tree.openElements.last.tagName)) {
+    while (!tableTags.contains(tree.openElements.last.localName)) {
       //XXX parser.parseError(token.span, "unexpected-implied-end-tag-in-table",
       //  {"name": tree.openElements.last.name})
       tree.openElements.removeLast();
     }
-    if (tree.openElements.last.tagName == "html") {
+    if (tree.openElements.last.localName == "html") {
       assert(parser.innerHTMLMode);
     }
   }
@@ -2491,7 +2492,7 @@
         tree.elementInScope("thead", variant: "table") ||
         tree.elementInScope("tfoot", variant: "table")) {
       clearStackToTableBodyContext();
-      endTagTableRowGroup(new EndTagToken(tree.openElements.last.tagName));
+      endTagTableRowGroup(new EndTagToken(tree.openElements.last.localName));
       return token;
     } else {
       // innerHTML case
@@ -2544,11 +2545,11 @@
   void clearStackToTableRowContext() {
     while (true) {
       var last = tree.openElements.last;
-      if (last.tagName == "tr" || last.tagName == "html") break;
+      if (last.localName == "tr" || last.localName == "html") break;
 
       parser.parseError(last.sourceSpan,
           "unexpected-implied-end-tag-in-table-row",
-          {"name": tree.openElements.last.tagName});
+          {"name": tree.openElements.last.localName});
       tree.openElements.removeLast();
     }
   }
@@ -2683,6 +2684,7 @@
       // innerHTML case
       assert(parser.innerHTMLMode);
       parser.parseError(token.span, "undefined-error");
+      return null;
     }
   }
 
@@ -2693,7 +2695,7 @@
   void endTagTableCell(EndTagToken token) {
     if (tree.elementInScope(token.name, variant: "table")) {
       tree.generateImpliedEndTags(token.name);
-      if (tree.openElements.last.tagName != token.name) {
+      if (tree.openElements.last.localName != token.name) {
         parser.parseError(token.span, "unexpected-cell-end-tag",
             {"name": token.name});
         popOpenElementsUntil(token.name);
@@ -2719,6 +2721,7 @@
       // sometimes innerHTML case
       parser.parseError(token.span, "undefined-error");
     }
+    return null;
   }
 
   Token endTagOther(EndTagToken token) {
@@ -2754,7 +2757,7 @@
   // http://www.whatwg.org/specs/web-apps/current-work///in-select
   bool processEOF() {
     var last = tree.openElements.last;
-    if (last.tagName != "html") {
+    if (last.localName != "html") {
       parser.parseError(last.sourceSpan, "eof-in-select");
     } else {
       assert(parser.innerHTMLMode);
@@ -2767,21 +2770,22 @@
       return null;
     }
     tree.insertText(token.data, token.span);
+    return null;
   }
 
   void startTagOption(StartTagToken token) {
     // We need to imply </option> if <option> is the current node.
-    if (tree.openElements.last.tagName == "option") {
+    if (tree.openElements.last.localName == "option") {
       tree.openElements.removeLast();
     }
     tree.insertElement(token);
   }
 
   void startTagOptgroup(StartTagToken token) {
-    if (tree.openElements.last.tagName == "option") {
+    if (tree.openElements.last.localName == "option") {
       tree.openElements.removeLast();
     }
-    if (tree.openElements.last.tagName == "optgroup") {
+    if (tree.openElements.last.localName == "optgroup") {
       tree.openElements.removeLast();
     }
     tree.insertElement(token);
@@ -2800,6 +2804,7 @@
     } else {
       assert(parser.innerHTMLMode);
     }
+    return null;
   }
 
   Token startTagScript(StartTagToken token) {
@@ -2809,10 +2814,11 @@
   Token startTagOther(StartTagToken token) {
     parser.parseError(token.span, "unexpected-start-tag-in-select",
         {"name": token.name});
+    return null;
   }
 
   void endTagOption(EndTagToken token) {
-    if (tree.openElements.last.tagName == "option") {
+    if (tree.openElements.last.localName == "option") {
       tree.openElements.removeLast();
     } else {
       parser.parseError(token.span, "unexpected-end-tag-in-select",
@@ -2822,12 +2828,12 @@
 
   void endTagOptgroup(EndTagToken token) {
     // </optgroup> implicitly closes <option>
-    if (tree.openElements.last.tagName == "option" &&
-      tree.openElements[tree.openElements.length - 2].tagName == "optgroup") {
+    if (tree.openElements.last.localName == "option" &&
+      tree.openElements[tree.openElements.length - 2].localName == "optgroup") {
       tree.openElements.removeLast();
     }
     // It also closes </optgroup>
-    if (tree.openElements.last.tagName == "optgroup") {
+    if (tree.openElements.last.localName == "optgroup") {
       tree.openElements.removeLast();
     // But nothing else
     } else {
@@ -2904,6 +2910,7 @@
       endTagOther(new EndTagToken("select"));
       return token;
     }
+    return null;
   }
 
   Token endTagOther(EndTagToken token) {
@@ -2976,7 +2983,7 @@
     } else if (parser.framesetOK && !allWhitespace(token.data)) {
       parser.framesetOK = false;
     }
-    super.processCharacters(token);
+    return super.processCharacters(token);
   }
 
   Token processStartTag(StartTagToken token) {
@@ -2989,7 +2996,7 @@
 
       parser.parseError(token.span,
           "unexpected-html-element-in-foreign-content", {'name': token.name});
-      while (tree.openElements.last.namespace !=
+      while (tree.openElements.last.namespaceUri !=
            tree.defaultNamespace &&
            !parser.isHTMLIntegrationPoint(tree.openElements.last) &&
            !parser.isMathMLTextIntegrationPoint(tree.openElements.last)) {
@@ -2998,32 +3005,33 @@
       return token;
 
     } else {
-      if (currentNode.namespace == Namespaces.mathml) {
+      if (currentNode.namespaceUri == Namespaces.mathml) {
         parser.adjustMathMLAttributes(token);
-      } else if (currentNode.namespace == Namespaces.svg) {
+      } else if (currentNode.namespaceUri == Namespaces.svg) {
         adjustSVGTagNames(token);
         parser.adjustSVGAttributes(token);
       }
       parser.adjustForeignAttributes(token);
-      token.namespace = currentNode.namespace;
+      token.namespace = currentNode.namespaceUri;
       tree.insertElement(token);
       if (token.selfClosing) {
         tree.openElements.removeLast();
         token.selfClosingAcknowledged = true;
       }
+      return null;
     }
   }
 
   Token processEndTag(EndTagToken token) {
     var nodeIndex = tree.openElements.length - 1;
     var node = tree.openElements.last;
-    if (node.tagName != token.name) {
+    if (node.localName != token.name) {
       parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
     }
 
     var newToken = null;
     while (true) {
-      if (asciiUpper2Lower(node.tagName) == token.name) {
+      if (asciiUpper2Lower(node.localName) == token.name) {
         //XXX this isn't in the spec but it seems necessary
         if (parser.phase == parser._inTableTextPhase) {
           InTableTextPhase inTableText = parser.phase;
@@ -3039,7 +3047,7 @@
       nodeIndex -= 1;
 
       node = tree.openElements[nodeIndex];
-      if (node.namespace != tree.defaultNamespace) {
+      if (node.namespaceUri != tree.defaultNamespace) {
         continue;
       } else {
         newToken = parser.phase.processEndTag(token);
@@ -3071,6 +3079,7 @@
     // This is needed because data is to be appended to the <html> element
     // here and not to whatever is currently open.
     tree.insertComment(token, tree.openElements[0]);
+    return null;
   }
 
   Token processCharacters(CharactersToken token) {
@@ -3129,7 +3138,7 @@
 
   bool processEOF() {
     var last = tree.openElements.last;
-    if (last.tagName != "html") {
+    if (last.localName != "html") {
       parser.parseError(last.sourceSpan, "eof-in-frameset");
     } else {
       assert(parser.innerHTMLMode);
@@ -3139,6 +3148,7 @@
 
   Token processCharacters(CharactersToken token) {
     parser.parseError(token.span, "unexpected-char-in-frameset");
+    return null;
   }
 
   void startTagFrameset(StartTagToken token) {
@@ -3157,17 +3167,19 @@
   Token startTagOther(StartTagToken token) {
     parser.parseError(token.span, "unexpected-start-tag-in-frameset",
         {"name": token.name});
+    return null;
   }
 
   void endTagFrameset(EndTagToken token) {
-    if (tree.openElements.last.tagName == "html") {
+    if (tree.openElements.last.localName == "html") {
       // innerHTML case
       parser.parseError(token.span,
           "unexpected-frameset-in-frameset-innerhtml");
     } else {
       tree.openElements.removeLast();
     }
-    if (!parser.innerHTMLMode && tree.openElements.last.tagName != "frameset") {
+    if (!parser.innerHTMLMode &&
+        tree.openElements.last.localName != "frameset") {
       // If we're not in innerHTML mode and the the current node is not a
       // "frameset" element (anymore) then switch.
       parser.phase = parser._afterFramesetPhase;
@@ -3205,6 +3217,7 @@
 
   Token processCharacters(CharactersToken token) {
     parser.parseError(token.span, "unexpected-char-after-frameset");
+    return null;
   }
 
   Token startTagNoframes(StartTagToken token) {
@@ -3239,6 +3252,7 @@
 
   Token processComment(CommentToken token) {
     tree.insertComment(token, tree.document);
+    return null;
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
@@ -3285,6 +3299,7 @@
 
   Token processComment(CommentToken token) {
     tree.insertComment(token, tree.document);
+    return null;
   }
 
   Token processSpaceCharacters(SpaceCharactersToken token) {
@@ -3293,6 +3308,7 @@
 
   Token processCharacters(CharactersToken token) {
     parser.parseError(token.span, "expected-eof-but-got-char");
+    return null;
   }
 
   Token startTagHtml(StartTagToken token) {
@@ -3311,11 +3327,12 @@
   Token processEndTag(EndTagToken token) {
     parser.parseError(token.span, "expected-eof-but-got-end-tag",
         {"name": token.name});
+    return null;
   }
 }
 
 
-/** Error in parsed document. */
+/// Error in parsed document.
 class ParseError implements Exception {
   final String errorCode;
   final Span span;
@@ -3327,14 +3344,12 @@
 
   int get column => span.start.column;
 
-  /**
-   * Gets the human readable error message for this error. Use
-   * [span.getLocationMessage] or [toString] to get a message including span
-   * information. If there is a file associated with the span, both
-   * [span.getLocationMessage] and [toString] are equivalent. Otherwise,
-   * [span.getLocationMessage] will not show any source url information, but
-   * [toString] will include 'ParserError:' as a prefix.
-   */
+  /// Gets the human readable error message for this error. Use
+  /// [span.getLocationMessage] or [toString] to get a message including span
+  /// information. If there is a file associated with the span, both
+  /// [span.getLocationMessage] and [toString] are equivalent. Otherwise,
+  /// [span.getLocationMessage] will not show any source url information, but
+  /// [toString] will include 'ParserError:' as a prefix.
   String get message => formatStr(errorMessages[errorCode], data);
 
   String toString() {
@@ -3342,3 +3357,11 @@
     return span.sourceUrl == null ? 'ParserError$res' : res;
   }
 }
+
+
+/// Convenience function to get the pair of namespace and localName.
+Pair<String, String> getElementNameTuple(Element e) {
+  var ns = e.namespaceUri;
+  if (ns == null) ns = Namespaces.html;
+  return new Pair(ns, e.localName);
+}
diff --git a/pkg/third_party/html5lib/lib/parser_console.dart b/pkg/third_party/html5lib/lib/parser_console.dart
index 7858ab2..515f891 100644
--- a/pkg/third_party/html5lib/lib/parser_console.dart
+++ b/pkg/third_party/html5lib/lib/parser_console.dart
@@ -1,19 +1,15 @@
-/**
- * This library adds `dart:io` support to the HTML5 parser. Call
- * [initDartIOSupport] before calling the [parse] methods and they will accept
- * a [RandomAccessFile] as input, in addition to the other input types.
- */
+/// This library adds `dart:io` support to the HTML5 parser. Call
+/// [initDartIOSupport] before calling the [parse] methods and they will accept
+/// a [RandomAccessFile] as input, in addition to the other input types.
 library parser_console;
 
 import 'dart:io';
 import 'parser.dart';
 import 'src/inputstream.dart' as inputstream;
 
-/**
- * Adds support to the [HtmlParser] for running on a console VM. In particular
- * this means it will be able to handle `dart:io` and [RandomAccessFile]s as
- * input to the various [parse] methods.
- */
+/// Adds support to the [HtmlParser] for running on a console VM. In particular
+/// this means it will be able to handle `dart:io` and [RandomAccessFile]s as
+/// input to the various [parse] methods.
 void useConsole() {
   inputstream.consoleSupport = new _ConsoleSupport();
 }
@@ -26,7 +22,7 @@
 }
 
 // TODO(jmesserly): this should be `RandomAccessFile.readAllBytes`.
-/** Synchronously reads all bytes from the [file]. */
+/// Synchronously reads all bytes from the [file].
 List<int> readAllBytesFromFile(RandomAccessFile file) {
   int length = file.lengthSync();
   var bytes = new List<int>(length);
diff --git a/pkg/third_party/html5lib/lib/src/char_encodings.dart b/pkg/third_party/html5lib/lib/src/char_encodings.dart
index 7fce8fd..9c04999 100644
--- a/pkg/third_party/html5lib/lib/src/char_encodings.dart
+++ b/pkg/third_party/html5lib/lib/src/char_encodings.dart
@@ -1,15 +1,13 @@
-/** Decodes bytes using the correct name. See [decodeBytes]. */
+/// Decodes bytes using the correct name. See [decodeBytes].
 library char_encodings;
 
 import 'dart:collection';
 import 'package:utf/utf.dart';
 
 // TODO(jmesserly): this function is conspicuously absent from dart:utf.
-/**
- * Returns true if the [bytes] starts with a UTF-8 byte order mark.
- * Since UTF-8 doesn't have byte order, it's somewhat of a misnomer, but it is
- * used in HTML to detect the UTF-
- */
+/// Returns true if the [bytes] starts with a UTF-8 byte order mark.
+/// Since UTF-8 doesn't have byte order, it's somewhat of a misnomer, but it is
+/// used in HTML to detect the UTF-
 bool hasUtf8Bom(List<int> bytes, [int offset = 0, int length]) {
   int end = length != null ? offset + length : bytes.length;
   return (offset + 3) <= end &&
@@ -20,11 +18,9 @@
 
 // TODO(jmesserly): it's unfortunate that this has to be one-shot on the entire
 // file, but dart:utf does not expose stream-based decoders yet.
-/**
- * Decodes the [bytes] with the provided [encoding] and returns an iterable for
- * the codepoints. Supports the major unicode encodings as well as ascii and
- * and windows-1252 encodings.
- */
+/// Decodes the [bytes] with the provided [encoding] and returns an iterable for
+/// the codepoints. Supports the major unicode encodings as well as ascii and
+/// and windows-1252 encodings.
 Iterable<int> decodeBytes(String encoding, List<int> bytes,
     [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -78,10 +74,8 @@
 
 
 // TODO(jmesserly): use dart:utf once http://dartbug.com/6476 is fixed.
-/**
- * Returns the code points for the [input]. This works like [String.charCodes]
- * but it decodes UTF-16 surrogate pairs.
- */
+/// Returns the code points for the [input]. This works like [String.charCodes]
+/// but it decodes UTF-16 surrogate pairs.
 List<int> toCodepoints(String input) {
   var newCodes = <int>[];
   for (int i = 0; i < input.length; i++) {
@@ -102,12 +96,10 @@
 }
 
 
-/**
- * Decodes [windows-1252](http://en.wikipedia.org/wiki/Windows-1252) bytes as an
- * iterable. Thus, the consumer can only convert as much of the input as needed.
- * Set the [replacementCharacter] to null to throw an [ArgumentError]
- * rather than replace the bad value.
- */
+/// Decodes [windows-1252](http://en.wikipedia.org/wiki/Windows-1252) bytes as
+/// an iterable. Thus, the consumer can only convert as much of the input as
+/// needed. Set the [replacementCharacter] to null to throw an [ArgumentError]
+/// rather than replace the bad value.
 IterableWindows1252Decoder decodeWindows1252AsIterable(List<int> bytes,
     [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -116,11 +108,9 @@
 }
 
 
-/**
- * Return type of [decodeWindows1252AsIterable] and variants. The Iterable type
- * provides an iterator on demand and the iterator will only translate bytes
- * as requested by the user of the iterator. (Note: results are not cached.)
- */
+/// Return type of [decodeWindows1252AsIterable] and variants. The Iterable type
+/// provides an iterator on demand and the iterator will only translate bytes
+/// as requested by the user of the iterator. (Note: results are not cached.)
 class IterableWindows1252Decoder extends IterableBase<int> {
   final List<int> bytes;
   final int offset;
@@ -136,14 +126,12 @@
 }
 
 
-/**
- * Provides an iterator of Unicode codepoints from windows-1252 encoded bytes.
- * The parameters can set an offset into a list of bytes (as int), limit the
- * length of the values to be decoded, and override the default Unicode
- * replacement character. Set the replacementCharacter to null to throw an
- * ArgumentError rather than replace the bad value. The return value
- * from this method can be used as an Iterable (e.g. in a for-loop).
- */
+/// Provides an iterator of Unicode codepoints from windows-1252 encoded bytes.
+/// The parameters can set an offset into a list of bytes (as int), limit the
+/// length of the values to be decoded, and override the default Unicode
+/// replacement character. Set the replacementCharacter to null to throw an
+/// ArgumentError rather than replace the bad value. The return value
+/// from this method can be used as an Iterable (e.g. in a for-loop).
 class Windows1252Decoder implements Iterator<int> {
   final int replacementCodepoint;
   final List<int> _bytes;
diff --git a/pkg/third_party/html5lib/lib/src/constants.dart b/pkg/third_party/html5lib/lib/src/constants.dart
index 9cc03ad..b8e4dbd 100644
--- a/pkg/third_party/html5lib/lib/src/constants.dart
+++ b/pkg/third_party/html5lib/lib/src/constants.dart
@@ -16,11 +16,9 @@
 
 // TODO(jmesserly): assuming the programmatic name is not important, it would be
 // good to make these "static const" fields on an ErrorMessage class.
-/**
- * These are error messages emitted by [HtmlParser]. The values use Python style
- * string formatting, as implemented by [formatStr]. That function only supports
- * the subset of format functionality used here.
- */
+/// These are error messages emitted by [HtmlParser]. The values use Python
+/// style string formatting, as implemented by [formatStr]. That function only
+/// supports the subset of format functionality used here.
 const Map<String, String> errorMessages = const {
   "null-character":
      "Null character in input stream, replaced with U+FFFD.",
diff --git a/pkg/third_party/html5lib/lib/src/encoding_parser.dart b/pkg/third_party/html5lib/lib/src/encoding_parser.dart
index 297e3f5..8bb861c 100644
--- a/pkg/third_party/html5lib/lib/src/encoding_parser.dart
+++ b/pkg/third_party/html5lib/lib/src/encoding_parser.dart
@@ -6,11 +6,9 @@
 
 // TODO(jmesserly): I converted StopIteration to StateError("No more elements").
 // Seems strange to throw this from outside of an iterator though.
-/**
- * String-like object with an associated position and various extra methods
- * If the position is ever greater than the string length then an exception is
- * raised.
- */
+/// String-like object with an associated position and various extra methods
+/// If the position is ever greater than the string length then an exception is
+/// raised.
 class EncodingBytes extends IterableBase<String> {
   final String _bytes;
   int _position = -1;
@@ -62,7 +60,7 @@
 
   String get currentByte => _bytes[position];
 
-  /** Skip past a list of characters. Defaults to skipping [isWhitespace]. */
+  /// Skip past a list of characters. Defaults to skipping [isWhitespace].
   String skipChars([CharPreciate skipChars]) {
     if (skipChars == null) skipChars = isWhitespace;
     var p = position;  // use property for the error-checking
@@ -91,11 +89,9 @@
     return null;
   }
 
-  /**
-   * Look for a sequence of bytes at the start of a string. If the bytes
-   * are found return true and advance the position to the byte after the
-   * match. Otherwise return false and leave the position alone.
-   */
+  /// Look for a sequence of bytes at the start of a string. If the bytes
+  /// are found return true and advance the position to the byte after the
+  /// match. Otherwise return false and leave the position alone.
   bool matchBytes(String bytes) {
     var p = position;
     if (_bytes.length < p + bytes.length) {
@@ -109,10 +105,8 @@
     return false;
   }
 
-  /**
-   * Look for the next sequence of bytes matching a given sequence. If
-   * a match is found advance the position to the last byte of the match
-   */
+  /// Look for the next sequence of bytes matching a given sequence. If
+  /// a match is found advance the position to the last byte of the match
   bool jumpTo(String bytes) {
     var newPosition = _bytes.indexOf(bytes, position);
     if (newPosition >= 0) {
@@ -130,12 +124,12 @@
   }
 }
 
-/** Mini parser for detecting character encoding from meta elements. */
+/// Mini parser for detecting character encoding from meta elements.
 class EncodingParser {
   final EncodingBytes data;
   String encoding;
 
-  /** [bytes] - the data to work on for encoding detection. */
+  /// [bytes] - the data to work on for encoding detection.
   EncodingParser(List<int> bytes)
       // Note: this is intentionally interpreting bytes as codepoints.
       : data = new EncodingBytes(new String.fromCharCodes(bytes).toLowerCase());
@@ -173,7 +167,7 @@
     return encoding;
   }
 
-  /** Skip over comments. */
+  /// Skip over comments.
   bool handleComment() => data.jumpTo("-->");
 
   bool handleMeta() {
@@ -204,6 +198,7 @@
         }
       }
     }
+    return true; // unreachable
   }
 
   bool handlePossibleStartTag() => handlePossibleTag(false);
@@ -242,10 +237,8 @@
 
   bool handleOther() => data.jumpTo(">");
 
-  /**
-   * Return a name,value pair for the next attribute in the stream,
-   * if one is found, or null
-   */
+  /// Return a name,value pair for the next attribute in the stream,
+  /// if one is found, or null
   List<String> getAttribute() {
     // Step 1 (skip chars)
     var c = data.skipChars((x) => x == "/" || isWhitespace(x));
@@ -327,6 +320,7 @@
         attrValue.add(c);
       }
     }
+    return null; // unreachable
   }
 }
 
diff --git a/pkg/third_party/html5lib/lib/src/inputstream.dart b/pkg/third_party/html5lib/lib/src/inputstream.dart
index a3d6046..5686abf 100644
--- a/pkg/third_party/html5lib/lib/src/inputstream.dart
+++ b/pkg/third_party/html5lib/lib/src/inputstream.dart
@@ -8,7 +8,7 @@
 import 'utils.dart';
 import 'encoding_parser.dart';
 
-/** Hooks to call into dart:io without directly referencing it. */
+/// Hooks to call into dart:io without directly referencing it.
 class ConsoleSupport {
   List<int> bytesFromFile(source) => null;
 }
@@ -16,36 +16,32 @@
 // TODO(jmesserly): use lazy init here when supported.
 ConsoleSupport consoleSupport = new ConsoleSupport();
 
-/**
- * Provides a unicode stream of characters to the HtmlTokenizer.
- *
- * This class takes care of character encoding and removing or replacing
- * incorrect byte-sequences and also provides column and line tracking.
- */
+/// Provides a unicode stream of characters to the HtmlTokenizer.
+///
+/// This class takes care of character encoding and removing or replacing
+/// incorrect byte-sequences and also provides column and line tracking.
 class HtmlInputStream {
-  /**
-   * Number of bytes to use when looking for a meta element with
-   * encoding information.
-   */
+  /// Number of bytes to use when looking for a meta element with
+  /// encoding information.
   static const int numBytesMeta = 512;
 
-  /** Encoding to use if no other information can be found. */
+  /// Encoding to use if no other information can be found.
   static const String defaultEncoding = 'windows-1252';
 
-  /** The name of the character encoding. */
+  /// The name of the character encoding.
   String charEncodingName;
 
-  /** True if we are certain about [charEncodingName], false for tenative. */
+  /// True if we are certain about [charEncodingName], false for tenative.
   bool charEncodingCertain = true;
 
   final bool generateSpans;
 
-  /** Location where the contents of the stream were found. */
+  /// Location where the contents of the stream were found.
   final String sourceUrl;
 
   List<int> _rawBytes;
 
-  /** Raw UTF-16 codes, used if a Dart String is passed in. */
+  /// Raw UTF-16 codes, used if a Dart String is passed in.
   Iterable<int> _rawChars;
 
   Queue<String> errors;
@@ -58,22 +54,20 @@
 
   int _offset;
 
-  /**
-   * Initialises the HtmlInputStream.
-   *
-   * HtmlInputStream(source, [encoding]) -> Normalized stream from source
-   * for use by html5lib.
-   *
-   * [source] can be either a [String] or a [List<int>] containing the raw
-   * bytes, or a file if [consoleSupport] is initialized.
-   *
-   * The optional encoding parameter must be a string that indicates
-   * the encoding.  If specified, that encoding will be used,
-   * regardless of any BOM or later declaration (such as in a meta
-   * element)
-   *
-   * [parseMeta] - Look for a <meta> element containing encoding information
-   */
+  /// Initialises the HtmlInputStream.
+  ///
+  /// HtmlInputStream(source, [encoding]) -> Normalized stream from source
+  /// for use by html5lib.
+  ///
+  /// [source] can be either a [String] or a [List<int>] containing the raw
+  /// bytes, or a file if [consoleSupport] is initialized.
+  ///
+  /// The optional encoding parameter must be a string that indicates
+  /// the encoding.  If specified, that encoding will be used,
+  /// regardless of any BOM or later declaration (such as in a meta
+  /// element)
+  ///
+  /// [parseMeta] - Look for a <meta> element containing encoding information
   HtmlInputStream(source, [String encoding, bool parseMeta = true,
         this.generateSpans = false, this.sourceUrl])
       : charEncodingName = codecName(encoding) {
@@ -195,11 +189,9 @@
     }
   }
 
-  /**
-   * Attempts to detect at BOM at the start of the stream. If
-   * an encoding can be determined from the BOM return the name of the
-   * encoding otherwise return null.
-   */
+  /// Attempts to detect at BOM at the start of the stream. If
+  /// an encoding can be determined from the BOM return the name of the
+  /// encoding otherwise return null.
   String detectBOM() {
     // Try detecting the BOM using bytes from the string
     if (hasUtf8Bom(_rawBytes)) {
@@ -216,7 +208,7 @@
     return null;
   }
 
-  /** Report the encoding declared by the meta element. */
+  /// Report the encoding declared by the meta element.
   String detectEncodingMeta() {
     var parser = new EncodingParser(slice(_rawBytes, 0, numBytesMeta));
     var encoding = parser.getEncoding();
@@ -228,16 +220,12 @@
     return encoding;
   }
 
-  /**
-   * Returns the current offset in the stream, i.e. the number of codepoints
-   * since the start of the file.
-   */
+  /// Returns the current offset in the stream, i.e. the number of codepoints
+  /// since the start of the file.
   int get position => _offset;
 
-  /**
-   * Read one character from the stream or queue if available. Return
-   * EOF when EOF is reached.
-   */
+  /// Read one character from the stream or queue if available. Return
+  /// EOF when EOF is reached.
   String char() {
     if (_offset >= _chars.length) return EOF;
     return new String.fromCharCodes([_chars[_offset++]]);
@@ -248,10 +236,8 @@
     return new String.fromCharCodes([_chars[_offset]]);
   }
 
-  /**
-   * Returns a string of characters from the stream up to but not
-   * including any character in 'characters' or EOF.
-   */
+  /// Returns a string of characters from the stream up to but not
+  /// including any character in 'characters' or EOF.
   String charsUntil(String characters, [bool opposite = false]) {
     int start = _offset;
     String c;
@@ -296,10 +282,8 @@
   return false;
 }
 
-/**
- * Return the python codec name corresponding to an encoding or null if the
- * string doesn't correspond to a valid encoding.
- */
+/// Return the python codec name corresponding to an encoding or null if the
+/// string doesn't correspond to a valid encoding.
 String codecName(String encoding) {
   final asciiPunctuation = new RegExp(
       "[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007E]");
diff --git a/pkg/third_party/html5lib/lib/src/list_proxy.dart b/pkg/third_party/html5lib/lib/src/list_proxy.dart
index d779043..0ba7073 100644
--- a/pkg/third_party/html5lib/lib/src/list_proxy.dart
+++ b/pkg/third_party/html5lib/lib/src/list_proxy.dart
@@ -1,7 +1,7 @@
 // TODO(jmesserly): remove this once we have a subclassable growable list
 // in our libraries.
 
-/** A [List] proxy that you can subclass. */
+/// A [List] proxy that you can subclass.
 library list_proxy;
 
 import 'dart:collection';
@@ -10,14 +10,12 @@
 // TOOD(jmesserly): this needs to be removed, but fixing NodeList is tricky.
 class ListProxy<E> extends IterableBase<E> implements List<E> {
 
-  /** The inner [List<T>] with the actual storage. */
+  /// The inner [List<T>] with the actual storage.
   final List<E> _list;
 
-  /**
-   * Creates a list proxy.
-   * You can optionally specify the list to use for [storage] of the items,
-   * otherwise this will create a [List<E>].
-   */
+  /// Creates a list proxy.
+  /// You can optionally specify the list to use for [storage] of the items,
+  /// otherwise this will create a [List<E>].
   ListProxy([List<E> storage])
      : _list = storage != null ? storage : <E>[];
 
diff --git a/pkg/third_party/html5lib/lib/src/token.dart b/pkg/third_party/html5lib/lib/src/token.dart
index 1e790da..b1ec1de 100644
--- a/pkg/third_party/html5lib/lib/src/token.dart
+++ b/pkg/third_party/html5lib/lib/src/token.dart
@@ -1,10 +1,10 @@
-/** This library contains token types used by the html5 tokenizer. */
+/// This library contains token types used by the html5 tokenizer.
 library token;
 
 import 'dart:collection';
 import 'package:source_maps/span.dart' show FileSpan;
 
-/** An html5 token. */
+/// An html5 token.
 abstract class Token {
   FileSpan span;
 
@@ -20,18 +20,16 @@
 }
 
 class StartTagToken extends TagToken {
-  /**
-   * The tag's attributes. A map from the name to the value, where the name
-   * can be a [String] or [AttributeName].
-   */
+  /// The tag's attributes. A map from the name to the value, where the name
+  /// can be a [String] or [AttributeName].
   LinkedHashMap<dynamic, String> data;
 
-  /** The attribute spans if requested. Otherwise null. */
+  /// The attribute spans if requested. Otherwise null.
   List<TagAttribute> attributeSpans;
 
   bool selfClosingAcknowledged;
 
-  /** The namespace. This is filled in later during tree building. */
+  /// The namespace. This is filled in later during tree building.
   String namespace;
 
   StartTagToken(String name, {this.data, bool selfClosing: false,
@@ -54,7 +52,7 @@
 }
 
 class ParseErrorToken extends StringToken {
-  /** Extra information that goes along with the error message. */
+  /// Extra information that goes along with the error message.
   Map messageParams;
 
   ParseErrorToken(String data, {this.messageParams}) : super(data);
@@ -91,11 +89,9 @@
   int get kind => TokenKind.doctype;
 }
 
-/**
- * These are used by the tokenizer to build up the attribute map.
- * They're also used by [StartTagToken.attributeSpans] if attribute spans are
- * requested.
- */
+/// These are used by the tokenizer to build up the attribute map.
+/// They're also used by [StartTagToken.attributeSpans] if attribute spans are
+/// requested.
 class TagAttribute {
   String name;
   String value;
diff --git a/pkg/third_party/html5lib/lib/src/tokenizer.dart b/pkg/third_party/html5lib/lib/src/tokenizer.dart
index 3f398e9..b486375 100644
--- a/pkg/third_party/html5lib/lib/src/tokenizer.dart
+++ b/pkg/third_party/html5lib/lib/src/tokenizer.dart
@@ -26,9 +26,7 @@
 // - use switch instead of the sequential if tests
 // - avoid string concat
 
-/**
- * This class takes care of tokenizing HTML.
- */
+/// This class takes care of tokenizing HTML.
 class HtmlTokenizer implements Iterator<Token> {
   // TODO(jmesserly): a lot of these could be made private
 
@@ -38,26 +36,22 @@
 
   final bool lowercaseAttrName;
 
-  /** True to generate spans in for [Token.span]. */
+  /// True to generate spans in for [Token.span].
   final bool generateSpans;
 
-  /** True to generate spans for attributes. */
+  /// True to generate spans for attributes.
   final bool attributeSpans;
 
-  /**
-   * This reference to the parser is used for correct CDATA handling.
-   * The [HtmlParser] will set this at construction time.
-   */
+  /// This reference to the parser is used for correct CDATA handling.
+  /// The [HtmlParser] will set this at construction time.
   HtmlParser parser;
 
   final Queue<Token> tokenQueue;
 
-  /** Holds the token that is currently being processed. */
+  /// Holds the token that is currently being processed.
   Token currentToken;
 
-  /**
-   * Holds a reference to the method to be invoked for the next parser state.
-   */
+  /// Holds a reference to the method to be invoked for the next parser state.
   // TODO(jmesserly): the type should be "Predicate" but a dart2js checked mode
   // bug prevents us from doing that. See http://dartbug.com/12465
   Function state;
@@ -124,13 +118,11 @@
     if (attributeSpans) attr.start = stream.position - name.length;
   }
 
-  /**
-   * This is where the magic happens.
-   *
-   * We do our usually processing through the states and when we have a token
-   * to return we yield the token which pauses processing until the next token
-   * is requested.
-   */
+  /// This is where the magic happens.
+  ///
+  /// We do our usually processing through the states and when we have a token
+  /// to return we yield the token which pauses processing until the next token
+  /// is requested.
   bool moveNext() {
     // Start processing. When EOF is reached state will return false;
     // instead of true and the loop will terminate.
@@ -149,10 +141,8 @@
     return true;
   }
 
-  /**
-   * Resets the tokenizer state. Calling this does not reset the [stream] or
-   * the [parser].
-   */
+  /// Resets the tokenizer state. Calling this does not reset the [stream] or
+  /// the [parser].
   void reset() {
     _lastOffset = 0;
     tokenQueue.clear();
@@ -163,7 +153,7 @@
     state = dataState;
   }
 
-  /** Adds a token to the queue. Sets the span if needed. */
+  /// Adds a token to the queue. Sets the span if needed.
   void _addToken(Token token) {
     if (generateSpans && token.span == null) {
       int offset = stream.position;
@@ -175,11 +165,9 @@
     tokenQueue.add(token);
   }
 
-  /**
-   * This function returns either U+FFFD or the character based on the
-   * decimal or hexadecimal representation. It also discards ";" if present.
-   * If not present it will add a [ParseErrorToken].
-   */
+  /// This function returns either U+FFFD or the character based on the
+  /// decimal or hexadecimal representation. It also discards ";" if present.
+  /// If not present it will add a [ParseErrorToken].
   String consumeNumberEntity(bool isHex) {
     var allowed = isDigit;
     var radix = 10;
@@ -345,16 +333,14 @@
     }
   }
 
-  /** This method replaces the need for "entityInAttributeValueState". */
+  /// This method replaces the need for "entityInAttributeValueState".
   void processEntityInAttribute(String allowedChar) {
     consumeEntity(allowedChar: allowedChar, fromAttribute: true);
   }
 
-  /**
-   * This method is a generic handler for emitting the tags. It also sets
-   * the state to "data" because that's what's needed after a token has been
-   * emitted.
-   */
+  /// This method is a generic handler for emitting the tags. It also sets
+  /// the state to "data" because that's what's needed after a token has been
+  /// emitted.
   void emitCurrentToken() {
     var token = currentToken;
     // Add token to the queue to be yielded
@@ -1301,7 +1287,7 @@
       }
     } else if (charStack.last == "[" &&
         parser != null && parser.tree.openElements.length > 0 &&
-        parser.tree.openElements.last.namespace
+        parser.tree.openElements.last.namespaceUri
             != parser.tree.defaultNamespace) {
       var matched = true;
       for (var expected in const ["C", "D", "A", "T", "A", "["]) {
diff --git a/pkg/third_party/html5lib/lib/src/treebuilder.dart b/pkg/third_party/html5lib/lib/src/treebuilder.dart
index adde3bf..708c08c 100644
--- a/pkg/third_party/html5lib/lib/src/treebuilder.dart
+++ b/pkg/third_party/html5lib/lib/src/treebuilder.dart
@@ -1,8 +1,9 @@
-/** Internals to the tree builders. */
+/// Internals to the tree builders.
 library treebuilder;
 
 import 'dart:collection';
 import 'package:html5lib/dom.dart';
+import 'package:html5lib/parser.dart' show getElementNameTuple;
 import 'package:source_maps/span.dart' show FileSpan;
 import 'constants.dart';
 import 'list_proxy.dart';
@@ -14,18 +15,18 @@
 // from "leaking" into tables, object elements, and marquees.
 const Node Marker = null;
 
-// TODO(jmesserly): this should extend ListBase<Node>, but my simple attempt
+// TODO(jmesserly): this should extend ListBase<Element>, but my simple attempt
 // didn't work.
-class ActiveFormattingElements extends ListProxy<Node> {
+class ActiveFormattingElements extends ListProxy<Element> {
   ActiveFormattingElements() : super();
 
   // Override the "add" method.
   // TODO(jmesserly): I'd rather not override this; can we do this in the
   // calling code instead?
-  void add(Node node) {
+  void add(Element node) {
     int equalCount = 0;
     if (node != Marker) {
-      for (Node element in reversed) {
+      for (var element in reversed) {
         if (element == Marker) {
           break;
         }
@@ -61,18 +62,18 @@
 }
 
 
-bool _nodesEqual(Node node1, Node node2) {
-  return node1.nameTuple == node2.nameTuple &&
+bool _nodesEqual(Element node1, Element node2) {
+  return getElementNameTuple(node1) == getElementNameTuple(node2) &&
       _mapEquals(node1.attributes, node2.attributes);
 }
 
-/** Basic treebuilder implementation. */
+/// Basic treebuilder implementation.
 class TreeBuilder {
   final String defaultNamespace;
 
   Document document;
 
-  final openElements = <Node>[];
+  final List<Element> openElements = <Element>[];
 
   final activeFormattingElements = new ActiveFormattingElements();
 
@@ -80,10 +81,8 @@
 
   Node formPointer;
 
-  /**
-   * Switch the function used to insert an element from the
-   * normal one to the misnested table one and back again
-   */
+  /// Switch the function used to insert an element from the
+  /// normal one to the misnested table one and back again
   bool insertFromTable;
 
   TreeBuilder(bool namespaceHTMLElements)
@@ -107,7 +106,7 @@
   bool elementInScope(target, {String variant}) {
     //If we pass a node in we match that. if we pass a string
     //match any node with that name
-    bool exactNode = target is Node && target.nameTuple != null;
+    bool exactNode = target is Node;
 
     List listElements1 = scopingElements;
     List listElements2 = const [];
@@ -135,13 +134,13 @@
       }
     }
 
-    for (Node node in openElements.reversed) {
-      if (node.tagName == target && !exactNode ||
-          node == target && exactNode) {
+    for (var node in openElements.reversed) {
+      if (!exactNode && node.localName == target ||
+          exactNode && node == target) {
         return true;
       } else if (invert !=
-          (listElements1.contains(node.nameTuple) ||
-           listElements2.contains(node.nameTuple))) {
+          (listElements1.contains(getElementNameTuple(node)) ||
+           listElements2.contains(getElementNameTuple(node)))) {
         return false;
       }
     }
@@ -187,8 +186,8 @@
 
       // TODO(jmesserly): optimize this. No need to create a token.
       var cloneToken = new StartTagToken(
-          entry.tagName,
-          namespace: entry.namespace,
+          entry.localName,
+          namespace: entry.namespaceUri,
           data: new LinkedHashMap.from(entry.attributes))
           ..span = entry.sourceSpan;
 
@@ -212,18 +211,16 @@
     }
   }
 
-  /**
-   * Check if an element exists between the end of the active
-   * formatting elements and the last marker. If it does, return it, else
-   * return null.
-   */
-  Node elementInActiveFormattingElements(String name) {
-    for (Node item in activeFormattingElements.reversed) {
+  /// Check if an element exists between the end of the active
+  /// formatting elements and the last marker. If it does, return it, else
+  /// return null.
+  Element elementInActiveFormattingElements(String name) {
+    for (var item in activeFormattingElements.reversed) {
       // Check for Marker first because if it's a Marker it doesn't have a
       // name attribute.
       if (item == Marker) {
         break;
-      } else if (item.tagName == name) {
+      } else if (item.localName == name) {
         return item;
       }
     }
@@ -249,7 +246,7 @@
     parent.nodes.add(new Comment(token.data)..sourceSpan = token.span);
   }
 
-  /** Create an element but don't insert it anywhere */
+  /// Create an element but don't insert it anywhere
   Element createElement(StartTagToken token) {
     var name = token.name;
     var namespace = token.namespace;
@@ -278,9 +275,9 @@
   }
 
   Element insertElementTable(token) {
-    /** Create an element and insert it into the tree */
+    /// Create an element and insert it into the tree
     var element = createElement(token);
-    if (!tableInsertModeElements.contains(openElements.last.tagName)) {
+    if (!tableInsertModeElements.contains(openElements.last.localName)) {
       return insertElementNormal(token);
     } else {
       // We should be in the InTable mode. This means we want to do
@@ -299,12 +296,12 @@
     return element;
   }
 
-  /** Insert text data. */
+  /// Insert text data.
   void insertText(String data, FileSpan span) {
     var parent = openElements.last;
 
     if (!insertFromTable || insertFromTable &&
-        !tableInsertModeElements.contains(openElements.last.tagName)) {
+        !tableInsertModeElements.contains(openElements.last.localName)) {
       _insertText(parent, data, span);
     } else {
       // We should be in the InTable mode. This means we want to do
@@ -314,17 +311,15 @@
     }
   }
 
-  /**
-   * Insert [data] as text in the current node, positioned before the
-   * start of node [refNode] or to the end of the node's text.
-   */
+  /// Insert [data] as text in the current node, positioned before the
+  /// start of node [refNode] or to the end of the node's text.
   static void _insertText(Node parent, String data, FileSpan span,
       [Element refNode]) {
     var nodes = parent.nodes;
     if (refNode == null) {
       if (nodes.length > 0 && nodes.last is Text) {
         Text last = nodes.last;
-        last.value = '${last.value}$data';
+        last.data = '${last.data}$data';
 
         if (span != null) {
           last.sourceSpan = span.file.span(last.sourceSpan.start.offset,
@@ -337,17 +332,15 @@
       int index = nodes.indexOf(refNode);
       if (index > 0 && nodes[index - 1] is Text) {
         Text last = nodes[index - 1];
-        last.value = '${last.value}$data';
+        last.data = '${last.data}$data';
       } else {
         nodes.insert(index, new Text(data)..sourceSpan = span);
       }
     }
   }
 
-  /**
-   * Get the foster parent element, and sibling to insert before
-   * (or null) when inserting a misnested table node
-   */
+  /// Get the foster parent element, and sibling to insert before
+  /// (or null) when inserting a misnested table node
   List<Node> getTableMisnestedNodePosition() {
     // The foster parent element is the one which comes before the most
     // recently opened table element
@@ -355,8 +348,8 @@
     Node lastTable = null;
     Node fosterParent = null;
     var insertBefore = null;
-    for (Node elm in openElements.reversed) {
-      if (elm.tagName == "table") {
+    for (var elm in openElements.reversed) {
+      if (elm.localName == "table") {
         lastTable = elm;
         break;
       }
@@ -377,7 +370,7 @@
   }
 
   void generateImpliedEndTags([String exclude]) {
-    var name = openElements.last.tagName;
+    var name = openElements.last.localName;
     // XXX td, th and tr are not actually needed
     if (name != exclude && const ["dd", "dt", "li", "option", "optgroup", "p",
         "rp", "rt"].contains(name)) {
@@ -388,10 +381,10 @@
     }
   }
 
-  /** Return the final tree. */
+  /// Return the final tree.
   Document getDocument() => document;
 
-  /** Return the final fragment. */
+  /// Return the final fragment.
   DocumentFragment getFragment() {
     //XXX assert innerHTML
     var fragment = new DocumentFragment();
diff --git a/pkg/third_party/html5lib/lib/src/utils.dart b/pkg/third_party/html5lib/lib/src/utils.dart
index 1a2bb9d..c998e0f 100644
--- a/pkg/third_party/html5lib/lib/src/utils.dart
+++ b/pkg/third_party/html5lib/lib/src/utils.dart
@@ -1,4 +1,4 @@
-/** Misc things that were useful when porting the code from Python. */
+/// Misc things that were useful when porting the code from Python.
 library utils;
 
 import 'constants.dart';
@@ -71,11 +71,9 @@
 
 // TODO(jmesserly): this implementation is pretty wrong, but I need something
 // quick until dartbug.com/1694 is fixed.
-/**
- * Format a string like Python's % string format operator. Right now this only
- * supports a [data] dictionary used with %s or %08x. Those were the only things
- * needed for [errorMessages].
- */
+/// Format a string like Python's % string format operator. Right now this only
+/// supports a [data] dictionary used with %s or %08x. Those were the only
+/// things needed for [errorMessages].
 String formatStr(String format, Map data) {
   if (data == null) return format;
   data.forEach((key, value) {
diff --git a/pkg/third_party/html5lib/test/browser/browser_test.dart b/pkg/third_party/html5lib/test/browser/browser_test.dart
deleted file mode 100644
index 8339f48..0000000
--- a/pkg/third_party/html5lib/test/browser/browser_test.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-library dom_compat_test;
-
-import 'dart:html';
-import 'package:unittest/html_config.dart';
-import 'package:unittest/unittest.dart';
-
-part '../dom_compat_test_definitions.dart';
-
-main() {
-  groupSep = ' - ';
-  useHtmlConfiguration();
-
-  registerDomCompatTests();
-}
diff --git a/pkg/third_party/html5lib/test/browser/browser_test.html b/pkg/third_party/html5lib/test/browser/browser_test.html
deleted file mode 100644
index bf8d297..0000000
--- a/pkg/third_party/html5lib/test/browser/browser_test.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-  <head>
-    <title>Run the unit tests</title>
-  </head>
-  <body>
-    <script>
-      // Webkit is migrating from layoutTestController to testRunner, we use
-      // layoutTestController as a fallback until that settles in.
-      var runner = window.testRunner || window.layoutTestController;
-      if (runner) {
-        runner.dumpAsText();
-        runner.waitUntilDone();
-        window.addEventListener("message", receiveMessage, false);
-      }
-
-      function receiveMessage(e) {
-        console.log(e.data);
-        if (e.data == 'unittest-suite-done' && runner) {
-          runner.notifyDone();
-        }
-      }
-    </script>
-    <script type="application/dart" src="browser_test.dart"></script>
-    <script src="packages/browser/dart.js"></script>
-  </body>
-</html>
diff --git a/pkg/third_party/html5lib/test/dom_compat_test.dart b/pkg/third_party/html5lib/test/dom_compat_test.dart
deleted file mode 100644
index 896576e..0000000
--- a/pkg/third_party/html5lib/test/dom_compat_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-library dom_compat_test;
-
-import 'dart:io';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/compact_vm_config.dart';
-import 'package:html5lib/dom.dart';
-
-part 'dom_compat_test_definitions.dart';
-
-main() {
-  useCompactVMConfiguration();
-
-  registerDomCompatTests();
-
-  test('content_shell', () {
-    _runDrt('test/browser/browser_test.html');
-  });
-}
-
-void _runDrt(String htmlFile) {
-  final allPassedRegExp = new RegExp('All \\d+ tests passed');
-
-  final future = Process.run('content_shell', ['--dump-render-tree', htmlFile])
-    .then((ProcessResult pr) {
-      expect(pr.exitCode, 0);
-      expect(pr.stdout, matches(allPassedRegExp), reason: pr.stdout);
-    });
-
-  expect(future, completion(isNull));
-}
diff --git a/pkg/third_party/html5lib/test/dom_compat_test_definitions.dart b/pkg/third_party/html5lib/test/dom_compat_test_definitions.dart
deleted file mode 100644
index f1d83e7..0000000
--- a/pkg/third_party/html5lib/test/dom_compat_test_definitions.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-part of dom_compat_test;
-
-void registerDomCompatTests() {
-  group('Element', () {
-    test('outerHtml', () {
-      final element = new Element.tag('div');
-      expect(element.outerHtml, '<div></div>');
-    });
-  });
-}
diff --git a/pkg/third_party/html5lib/test/dom_test.dart b/pkg/third_party/html5lib/test/dom_test.dart
index 301e822..43a9637 100644
--- a/pkg/third_party/html5lib/test/dom_test.dart
+++ b/pkg/third_party/html5lib/test/dom_test.dart
@@ -1,4 +1,4 @@
-/** Additional feature tests that aren't based on test data. */
+/// Additional feature tests that aren't based on test data.
 library dom_test;
 
 import 'package:unittest/unittest.dart';
diff --git a/pkg/third_party/html5lib/test/parser_feature_test.dart b/pkg/third_party/html5lib/test/parser_feature_test.dart
index f6ac344..212ae05 100644
--- a/pkg/third_party/html5lib/test/parser_feature_test.dart
+++ b/pkg/third_party/html5lib/test/parser_feature_test.dart
@@ -1,4 +1,4 @@
-/** Additional feature tests that aren't based on test data. */
+/// Additional feature tests that aren't based on test data.
 library parser_feature_test;
 
 import 'package:unittest/unittest.dart';
@@ -9,9 +9,9 @@
 
 main() {
   test('doctype is cloneable', () {
-    var doc = parse('<!DOCTYPE HTML>');
+    var doc = parse('<!doctype HTML>');
     DocumentType doctype = doc.nodes[0];
-    expect(doctype.clone().outerHtml, '<!DOCTYPE html>');
+    expect(doctype.clone().toString(), '<!DOCTYPE html>');
   });
 
   test('line counter', () {
@@ -22,12 +22,12 @@
 
   test('namespace html elements on', () {
     var doc = new HtmlParser('', tree: new TreeBuilder(true)).parse();
-    expect(doc.nodes[0].namespace, Namespaces.html);
+    expect(doc.nodes[0].namespaceUri, Namespaces.html);
   });
 
   test('namespace html elements off', () {
     var doc = new HtmlParser('', tree: new TreeBuilder(false)).parse();
-    expect(doc.nodes[0].namespace, null);
+    expect(doc.nodes[0].namespaceUri, null);
   });
 
   test('parse error spans - full', () {
@@ -81,9 +81,9 @@
     var textContent = '\n  hello {{name}}';
     var html = '<body><div>$textContent</div>';
     var doc = parse(html, generateSpans: true);
-    var text = doc.body.nodes[0].nodes[0];
+    Text text = doc.body.nodes[0].nodes[0];
     expect(text, new isInstanceOf<Text>());
-    expect(text.value, textContent);
+    expect(text.data, textContent);
     expect(text.sourceSpan.start.offset, html.indexOf(textContent));
     expect(text.sourceSpan.length, textContent.length);
   });
@@ -156,60 +156,62 @@
 
   test('empty document has html, body, and head', () {
     var doc = parse('');
-    expect(doc.outerHtml, '<html><head></head><body></body></html>');
+    var html = '<html><head></head><body></body></html>';
+    expect(doc.outerHtml, html);
+    expect(doc.documentElement.outerHtml, html);
     expect(doc.head.outerHtml, '<head></head>');
     expect(doc.body.outerHtml, '<body></body>');
   });
 
   test('strange table case', () {
-    var doc = parseFragment('<table><tbody><foo>');
-    expect(doc.outerHtml, '<foo></foo><table><tbody></tbody></table>');
+    var doc = parse('<table><tbody><foo>').body;
+    expect(doc.innerHtml, '<foo></foo><table><tbody></tbody></table>');
   });
 
   group('html serialization', () {
     test('attribute order', () {
       // Note: the spec only requires a stable order.
       // However, we preserve the input order via LinkedHashMap
-      var doc = parseFragment('<foo d=1 a=2 c=3 b=4>');
-      expect(doc.outerHtml, '<foo d="1" a="2" c="3" b="4"></foo>');
-      expect(doc.querySelector('foo').attributes.remove('a'), '2');
-      expect(doc.outerHtml, '<foo d="1" c="3" b="4"></foo>');
-      doc.querySelector('foo').attributes['a'] = '0';
-      expect(doc.outerHtml, '<foo d="1" c="3" b="4" a="0"></foo>');
+      var body = parse('<foo d=1 a=2 c=3 b=4>').body;
+      expect(body.innerHtml, '<foo d="1" a="2" c="3" b="4"></foo>');
+      expect(body.querySelector('foo').attributes.remove('a'), '2');
+      expect(body.innerHtml, '<foo d="1" c="3" b="4"></foo>');
+      body.querySelector('foo').attributes['a'] = '0';
+      expect(body.innerHtml, '<foo d="1" c="3" b="4" a="0"></foo>');
     });
 
     test('escaping Text node in <script>', () {
-      var doc = parseFragment('<script>a && b</script>');
-      expect(doc.outerHtml, '<script>a && b</script>');
+      Element e = parseFragment('<script>a && b</script>').firstChild;
+      expect(e.outerHtml, '<script>a && b</script>');
     });
 
     test('escaping Text node in <span>', () {
-      var doc = parseFragment('<span>a && b</span>');
-      expect(doc.outerHtml, '<span>a &amp;&amp; b</span>');
+      Element e = parseFragment('<span>a && b</span>').firstChild;
+      expect(e.outerHtml, '<span>a &amp;&amp; b</span>');
     });
 
     test('Escaping attributes', () {
-      var doc = parseFragment('<div class="a<b>">');
-      expect(doc.outerHtml, '<div class="a<b>"></div>');
-      doc = parseFragment('<div class=\'a"b\'>');
-      expect(doc.outerHtml, '<div class="a&quot;b"></div>');
+      Element e = parseFragment('<div class="a<b>">').firstChild;
+      expect(e.outerHtml, '<div class="a<b>"></div>');
+      e = parseFragment('<div class=\'a"b\'>').firstChild;
+      expect(e.outerHtml, '<div class="a&quot;b"></div>');
     });
 
     test('Escaping non-breaking space', () {
       var text = '<span>foO\u00A0bar</span>';
       expect(text.codeUnitAt(text.indexOf('O') + 1), 0xA0);
-      var doc = parseFragment(text);
-      expect(doc.outerHtml, '<span>foO&nbsp;bar</span>');
+      Element e = parseFragment(text).firstChild;
+      expect(e.outerHtml, '<span>foO&nbsp;bar</span>');
     });
 
     test('Newline after <pre>', () {
-      var doc = parseFragment('<pre>\n\nsome text</span>');
-      expect(doc.querySelector('pre').nodes[0].value, '\nsome text');
-      expect(doc.outerHtml, '<pre>\n\nsome text</pre>');
+      Element e = parseFragment('<pre>\n\nsome text</span>').firstChild;
+      expect((e.firstChild as Text).data, '\nsome text');
+      expect(e.outerHtml, '<pre>\n\nsome text</pre>');
 
-      doc = parseFragment('<pre>\nsome text</span>');
-      expect(doc.querySelector('pre').nodes[0].value, 'some text');
-      expect(doc.outerHtml, '<pre>some text</pre>');
+      e = parseFragment('<pre>\nsome text</span>').firstChild;
+      expect((e.firstChild as Text).data, 'some text');
+      expect(e.outerHtml, '<pre>some text</pre>');
     });
 
     test('xml namespaces', () {
@@ -246,4 +248,45 @@
         'ParserError:1:4: Unexpected non-space characters. '
         'Expected DOCTYPE.');
   });
+
+  test('Element.text', () {
+    var doc = parseFragment('<div>foo<div>bar</div>baz</div>');
+    var e = doc.firstChild;
+    var text = e.firstChild;
+    expect((text as Text).data, 'foo');
+    expect(e.text, 'foobarbaz');
+
+    e.text = 'FOO';
+    expect(e.nodes.length, 1);
+    expect(e.firstChild, isNot(text), reason: 'should create a new tree');
+    expect((e.firstChild as Text).data, 'FOO');
+    expect(e.text, 'FOO');
+  });
+
+  test('Text.text', () {
+    var doc = parseFragment('<div>foo<div>bar</div>baz</div>');
+    var e = doc.firstChild;
+    Text text = e.firstChild;
+    expect(text.data, 'foo');
+    expect(text.text, 'foo');
+
+    text.text = 'FOO';
+    expect(text.data, 'FOO');
+    expect(e.text, 'FOObarbaz');
+    expect(text.text, 'FOO');
+  });
+
+  test('Comment.text', () {
+    var doc = parseFragment('<div><!--foo-->bar</div>');
+    var e = doc.firstChild;
+    var c = e.firstChild;
+    expect((c as Comment).data, 'foo');
+    expect(c.text, 'foo');
+    expect(e.text, 'bar');
+
+    c.text = 'qux';
+    expect(c.data, 'qux');
+    expect(c.text, 'qux');
+    expect(e.text, 'bar');
+  });
 }
diff --git a/pkg/third_party/html5lib/test/parser_test.dart b/pkg/third_party/html5lib/test/parser_test.dart
index dbfb3fc..821eb2d 100644
--- a/pkg/third_party/html5lib/test/parser_test.dart
+++ b/pkg/third_party/html5lib/test/parser_test.dart
@@ -109,7 +109,7 @@
   }
 }
 
-/** Extract the name for the test based on the test input data. */
+/// Extract the name for the test based on the test input data.
 _nameFor(String input) {
   // Using JSON.decode to unescape other unicode characters
   var escapeQuote = input
diff --git a/pkg/third_party/html5lib/test/run_all.dart b/pkg/third_party/html5lib/test/run_all.dart
index f6fff1b..14e6b34 100644
--- a/pkg/third_party/html5lib/test/run_all.dart
+++ b/pkg/third_party/html5lib/test/run_all.dart
@@ -12,7 +12,6 @@
 import 'parser_feature_test.dart' as parser_feature_test;
 import 'parser_test.dart' as parser_test;
 import 'tokenizer_test.dart' as tokenizer_test;
-import 'dom_compat_test.dart' as dom_compat_test;
 
 main(List<String> args) {
   var pattern = new RegExp(args.length > 0 ? args[0] : '.');
@@ -25,7 +24,6 @@
   }
 
   addGroup('dom_test.dart', dom_test.main);
-  addGroup('dom_compat_test.dart', dom_compat_test.main);
   addGroup('parser_feature_test.dart', parser_feature_test.main);
   addGroup('parser_test.dart', parser_test.main);
   addGroup('tokenizer_test.dart', tokenizer_test.main);
diff --git a/pkg/third_party/html5lib/test/support.dart b/pkg/third_party/html5lib/test/support.dart
index 1146679..4d2cb5a 100644
--- a/pkg/third_party/html5lib/test/support.dart
+++ b/pkg/third_party/html5lib/test/support.dart
@@ -1,4 +1,4 @@
-/** Support code for the tests in this directory. */
+/// Support code for the tests in this directory.
 library support;
 
 import 'dart:io';
@@ -72,10 +72,8 @@
     return result;
   }
 
-  /**
-   * If the current heading is a test section heading return the heading,
-   * otherwise return null.
-   */
+  /// If the current heading is a test section heading return the heading,
+  /// otherwise return null.
   static String sectionHeading(String line) {
     return line.startsWith("#") ? line.substring(1).trim() : null;
   }
@@ -91,14 +89,12 @@
   }
 }
 
-/**
- * Serialize the [document] into the html5 test data format.
- */
+/// Serialize the [document] into the html5 test data format.
 testSerializer(Document document) {
   return (new TestSerializer()..visit(document)).toString();
 }
 
-/** Serializes the DOM into test format. See [testSerializer]. */
+/// Serializes the DOM into test format. See [testSerializer].
 class TestSerializer extends TreeVisitor {
   final StringBuffer _str;
   int _indent = 0;
diff --git a/pkg/third_party/html5lib/test/tokenizer_test.dart b/pkg/third_party/html5lib/test/tokenizer_test.dart
index 439e440..5c87e16 100644
--- a/pkg/third_party/html5lib/test/tokenizer_test.dart
+++ b/pkg/third_party/html5lib/test/tokenizer_test.dart
@@ -134,12 +134,10 @@
 }
 
 
-/**
- * Test whether the test has passed or failed
- *
- * If the ignoreErrorOrder flag is set to true we don't test the relative
- * positions of parse errors and non parse errors.
- */
+/// Test whether the test has passed or failed
+///
+/// If the ignoreErrorOrder flag is set to true we don't test the relative
+/// positions of parse errors and non parse errors.
 void expectTokensMatch(List expectedTokens, List receivedTokens,
     bool ignoreErrorOrder, [bool ignoreErrors = false, String message]) {
 
diff --git a/pkg/watcher/pubspec.yaml b/pkg/watcher/pubspec.yaml
index bf00d9e..1045bc5 100644
--- a/pkg/watcher/pubspec.yaml
+++ b/pkg/watcher/pubspec.yaml
@@ -9,7 +9,7 @@
   path: ">=0.9.0 <2.0.0"
   stack_trace: ">=0.9.1 <0.10.0"
 dev_dependencies:
-  scheduled_test: ">=0.9.3-dev <0.10.0"
+  scheduled_test: ">=0.9.3-dev <0.11.0"
   unittest: ">=0.9.2 <0.10.0"
 environment:
   sdk: ">=0.8.10+6 <2.0.0"
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 2a0b6be..590d37e 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -170,7 +170,7 @@
     {
       'target_name': 'libdart_io',
       'type': 'static_library',
-      'toolsets':['target', 'host'],
+      'toolsets': ['host', 'target'],
       'include_dirs': [
         '..',
       ],
@@ -256,7 +256,6 @@
       'dependencies': [
         'libdart_withcore',
         'libdart_builtin',
-        'libdart_io',
       ],
       'include_dirs': [
         '..',
@@ -492,7 +491,6 @@
     {
       'target_name': 'run_vm_tests',
       'type': 'executable',
-      'toolsets':['target'],
       'dependencies': [
         'libdart_withcore',
         'libdart_builtin',
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index 241aed0..4b4e4cc 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -7,8 +7,12 @@
 # io_impl_sources.gypi.
 {
   'sources': [
-    'io_buffer.cc',
-    'io_buffer.h',
+    'crypto.cc',
+    'crypto.h',
+    'crypto_android.cc',
+    'crypto_linux.cc',
+    'crypto_macos.cc',
+    'crypto_win.cc',
     'dartutils.cc',
     'dartutils.h',
     'dbg_connection.cc',
@@ -41,18 +45,15 @@
     'file_macos.cc',
     'file_win.cc',
     'file_test.cc',
-    'file_system_watcher.cc',
-    'file_system_watcher.h',
-    'file_system_watcher_android.cc',
-    'file_system_watcher_linux.cc',
-    'file_system_watcher_macos.cc',
-    'file_system_watcher_win.cc',
     'fdutils.h',
     'fdutils_android.cc',
     'fdutils_linux.cc',
     'fdutils_macos.cc',
     'hashmap_test.cc',
+    'io_buffer.cc',
+    'io_buffer.h',
     'isolate_data.h',
+    'signal_blocker.h',
     'thread.h',
     'utils.h',
     'utils_android.cc',
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 5681c0a..1c096ac 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -23,6 +23,7 @@
 // Advanced I/O classes like sockets and process management are implemented
 // using functions listed in io_natives.cc.
 #define BUILTIN_NATIVE_LIST(V)                                                 \
+  V(Crypto_GetRandomBytes, 1)                                                  \
   V(Directory_Exists, 1)                                                       \
   V(Directory_Create, 1)                                                       \
   V(Directory_Current, 0)                                                      \
@@ -61,13 +62,6 @@
   V(File_GetStdioHandleType, 1)                                                \
   V(File_GetType, 2)                                                           \
   V(File_AreIdentical, 2)                                                      \
-  V(FileSystemWatcher_CloseWatcher, 1)                                         \
-  V(FileSystemWatcher_GetSocketId, 2)                                          \
-  V(FileSystemWatcher_InitWatcher, 0)                                          \
-  V(FileSystemWatcher_IsSupported, 0)                                          \
-  V(FileSystemWatcher_ReadEvents, 2)                                           \
-  V(FileSystemWatcher_UnwatchPath, 2)                                          \
-  V(FileSystemWatcher_WatchPath, 4)                                            \
   V(Logger_PrintString, 1)
 
 BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);
@@ -117,10 +111,11 @@
     // an isolate gets interrupted by the embedder in the middle of
     // Dart_StringToUTF8?  We need to make sure not to swallow the
     // interrupt.
-    Platform::PrintBlocking(stdout, "%s\n", Dart_GetError(result));
+    fprintf(stdout, "%s\n", Dart_GetError(result));
   } else {
-    Platform::PrintBlocking(stdout, "%.*s\n", static_cast<int>(length), chars);
+    fprintf(stdout, "%.*s\n", static_cast<int>(length), chars);
   }
+  fflush(stdout);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 2b8e495..8bc5aea 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -811,6 +811,15 @@
 }
 
 
+bool DartUtils::PostInt64(Dart_Port port_id, int64_t value) {
+  // Post a message with the integer value.
+  Dart_CObject object;
+  object.type = Dart_CObject_kInt64;
+  object.value.as_int64 = value;
+  return Dart_PostCObject(port_id, &object);
+}
+
+
 Dart_Handle DartUtils::GetDartType(const char* library_url,
                                    const char* class_name) {
   return Dart_GetType(Dart_LookupLibrary(NewString(library_url)),
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index fc7963b..608700e 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -141,6 +141,7 @@
 
   static bool PostNull(Dart_Port port_id);
   static bool PostInt32(Dart_Port port_id, int32_t value);
+  static bool PostInt64(Dart_Port port_id, int64_t value);
 
   static Dart_Handle GetDartType(const char* library_url,
                                  const char* class_name);
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 7fb4b2ed..d0b6541 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -91,12 +91,11 @@
 }
 
 
-static int GetIntValue(Dart_Handle int_handle) {
+static int64_t GetIntValue(Dart_Handle int_handle) {
   int64_t int64_val = -1;
   ASSERT(Dart_IsInteger(int_handle));
   Dart_Handle res = Dart_IntegerToInt64(int_handle, &int64_val);
   ASSERT_NOT_ERROR(res);
-  // TODO(hausner): Range check.
   return int64_val;
 }
 
@@ -367,10 +366,10 @@
   res = Dart_ListLength(import_list, &list_length);
   RETURN_IF_ERROR(res);
   buf->Printf(",\"imports\":[");
-  for (int i = 0; i + 1 < list_length; i += 2) {
+  for (intptr_t i = 0; i + 1 < list_length; i += 2) {
     Dart_Handle lib_id = Dart_ListGetAt(import_list, i + 1);
     ASSERT_NOT_ERROR(lib_id);
-    buf->Printf("%s{\"libraryId\":%d,",
+    buf->Printf("%s{\"libraryId\":%" Pd64 ",",
                 (i > 0) ? ",": "",
                 GetIntValue(lib_id));
 
@@ -580,14 +579,15 @@
   intptr_t num_libs;
   Dart_Handle res = Dart_ListLength(lib_ids, &num_libs);
   ASSERT_NOT_ERROR(res);
-  for (int i = 0; i < num_libs; i++) {
+  for (intptr_t i = 0; i < num_libs; i++) {
     Dart_Handle lib_id_handle = Dart_ListGetAt(lib_ids, i);
     ASSERT(Dart_IsInteger(lib_id_handle));
-    int lib_id = GetIntValue(lib_id_handle);
-    Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
+    int64_t lib_id = GetIntValue(lib_id_handle);
+    ASSERT((lib_id >= kIntptrMin) && (lib_id <= kIntptrMax));
+    Dart_Handle lib_url = Dart_GetLibraryURL(static_cast<intptr_t>(lib_id));
     ASSERT_NOT_ERROR(lib_url);
     ASSERT(Dart_IsString(lib_url));
-    msg.Printf("%s{\"id\":%d,\"url\":", (i == 0) ? "" : ", ", lib_id);
+    msg.Printf("%s{\"id\":%" Pd64 ",\"url\":", (i == 0) ? "" : ", ", lib_id);
     FormatEncodedString(&msg, lib_url);
     msg.Printf("}");
   }
@@ -898,11 +898,11 @@
       num_elems = 0;
     } else {
       ASSERT(Dart_IsInteger(elem));
-      int value = GetIntValue(elem);
+      int64_t value = GetIntValue(elem);
       if (num_elems == 0) {
-        msg.Printf("%d", value);
+        msg.Printf("%" Pd64 "", value);
       } else {
-        msg.Printf(",%d", value);
+        msg.Printf(",%" Pd64 "", value);
       }
       num_elems++;
     }
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index 64f9306..6ac1ef4 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -65,10 +65,12 @@
   bool HasTimeout() const { return next_timeout_ != NULL; }
 
   int64_t CurrentTimeout() const {
+    ASSERT(next_timeout_ != NULL);
     return next_timeout_->timeout();
   }
 
   Dart_Port CurrentPort() const {
+    ASSERT(next_timeout_ != NULL);
     return next_timeout_->port();
   }
 
@@ -105,7 +107,7 @@
 class EventHandler {
  public:
   void SendData(intptr_t id, Dart_Port dart_port, int64_t data) {
-    delegate_.SendData(id, dart_port, data);
+    delegate_.Notify(id, dart_port, data);
   }
 
   /**
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index fb8cc25..4d7cda3 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -25,6 +25,12 @@
 #include "platform/utils.h"
 
 
+// Android doesn't define EPOLLRDHUP.
+#if !defined(EPOLLRDHUP)
+#define EPOLLRDHUP 0x2000
+#endif  // !defined(EPOLLRDHUP)
+
+
 namespace dart {
 namespace bin {
 
@@ -34,65 +40,39 @@
 static const int kShutdownId = -2;
 
 
-intptr_t SocketData::GetPollEvents() {
-  // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are
-  // triggered anyway.
-  intptr_t events = 0;
-  if (!IsClosedRead()) {
-    if ((mask_ & (1 << kInEvent)) != 0) {
-      events |= EPOLLIN;
-    }
-  }
-  if (!IsClosedWrite()) {
-    if ((mask_ & (1 << kOutEvent)) != 0) {
-      events |= EPOLLOUT;
-    }
-  }
-  return events;
-}
-
-
 // Unregister the file descriptor for a SocketData structure with epoll.
 static void RemoveFromEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
-  if (sd->tracked_by_epoll()) {
-    int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                              EPOLL_CTL_DEL,
-                                              sd->fd(),
-                                              NULL));
-    if (status == -1) {
-      FATAL("Failed unregistering events for file descriptor");
-    }
-    sd->set_tracked_by_epoll(false);
+  if (!sd->tracked_by_epoll()) return;
+  int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
+                                            EPOLL_CTL_DEL,
+                                            sd->fd(),
+                                            NULL));
+  if (status == -1) {
+    FATAL("Failed unregistering events for file descriptor");
   }
+  sd->set_tracked_by_epoll(false);
 }
 
 
-// Register the file descriptor for a SocketData structure with epoll
-// if events are requested.
-static void UpdateEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
+static void AddToEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
+  ASSERT(!sd->tracked_by_epoll());
   struct epoll_event event;
-  event.events = sd->GetPollEvents();
+  event.events = EPOLLET | EPOLLRDHUP;
+  if ((sd->mask() & (1 << kInEvent)) != 0) event.events |= EPOLLIN;
+  if ((sd->mask() & (1 << kOutEvent)) != 0) event.events |= EPOLLOUT;
   event.data.ptr = sd;
-  if (sd->port() != 0 && event.events != 0) {
-    int status = 0;
-    if (sd->tracked_by_epoll()) {
-      status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                            EPOLL_CTL_MOD,
-                                            sd->fd(),
-                                            &event));
-    } else {
-      status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
+  int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
                                             EPOLL_CTL_ADD,
                                             sd->fd(),
                                             &event));
-      sd->set_tracked_by_epoll(true);
-    }
-    if (status == -1) {
-      const int kBufferSize = 1024;
-      char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
-      FATAL1("Failed updating epoll instance: %s", error_message);
-    }
+  if (status == -1) {
+    // Epoll does not accept the file descriptor. It could be due to
+    // already closed file descriptor, or unuspported devices, such
+    // as /dev/null. In such case, mark the file descriptor as closed,
+    // so dart will handle it accordingly.
+    DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
+  } else {
+    sd->set_tracked_by_epoll(true);
   }
 }
 
@@ -136,7 +116,8 @@
 }
 
 
-SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
+SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd,
+                                                      bool* is_new) {
   ASSERT(fd >= 0);
   HashMap::Entry* entry = socket_map_.Lookup(
       GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
@@ -147,6 +128,7 @@
     // new SocketData for the file descriptor is inserted.
     sd = new SocketData(fd);
     entry->value = sd;
+    *is_new = true;
   }
   ASSERT(fd == sd->fd());
   return sd;
@@ -186,39 +168,30 @@
     } else if (msg[i].id == kShutdownId) {
       shutdown_ = true;
     } else {
-      SocketData* sd = GetSocketData(msg[i].id);
+      bool is_new = false;
+      SocketData* sd = GetSocketData(msg[i].id, &is_new);
+      if (is_new) {
+        sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
+        AddToEpollInstance(epoll_fd_, sd);
+      }
       if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kShutdownReadCommand));
         // Close the socket for reading.
         sd->ShutdownRead();
-        UpdateEpollInstance(epoll_fd_, sd);
       } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kShutdownWriteCommand));
         // Close the socket for writing.
         sd->ShutdownWrite();
-        UpdateEpollInstance(epoll_fd_, sd);
       } else if ((msg[i].data & (1 << kCloseCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kCloseCommand));
         // Close the socket and free system resources and move on to
         // next message.
         RemoveFromEpollInstance(epoll_fd_, sd);
         intptr_t fd = sd->fd();
-        if (fd == STDOUT_FILENO) {
-          // If stdout, redirect fd to /dev/null.
-          int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
-          ASSERT(null_fd >= 0);
-          VOID_TEMP_FAILURE_RETRY(dup2(null_fd, STDOUT_FILENO));
-          VOID_TEMP_FAILURE_RETRY(close(null_fd));
-        } else {
-          sd->Close();
-        }
+        sd->Close();
         socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
         delete sd;
         DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent);
-      } else {
-        // Setup events to wait for.
-        sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
-        UpdateEpollInstance(epoll_fd_, sd);
       }
     }
   }
@@ -261,64 +234,29 @@
     }
   } else {
     // Prioritize data events over close and error events.
-    if ((events & EPOLLIN) != 0) {
-      if (FDUtils::AvailableBytes(sd->fd()) != 0) {
+    if ((events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP)) != 0) {
+      // If we have EPOLLIN and we have available bytes, report that.
+      if ((events & EPOLLIN) != 0) {
         event_mask = (1 << kInEvent);
-      } else if ((events & EPOLLHUP) != 0) {
+      }
+      if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) {
         // If both EPOLLHUP and EPOLLERR are reported treat it as an
         // error.
         if ((events & EPOLLERR) != 0) {
           event_mask = (1 << kErrorEvent);
         } else {
-          event_mask = (1 << kCloseEvent);
+          event_mask |= (1 << kCloseEvent);
         }
-        sd->MarkClosedRead();
       } else if ((events & EPOLLERR) != 0) {
         event_mask = (1 << kErrorEvent);
-      } else {
-        if (sd->IsPipe()) {
-          // When reading from stdin (either from a terminal or piped
-          // input) treat EPOLLIN with 0 available bytes as
-          // end-of-file.
-          if (sd->fd() == STDIN_FILENO) {
-            event_mask = (1 << kCloseEvent);
-            sd->MarkClosedRead();
-          }
-        } else {
-          // If EPOLLIN is set with no available data and no EPOLLHUP use
-          // recv to peek for whether the other end of the socket
-          // actually closed.
-          char buffer;
-          ssize_t bytesPeeked =
-              TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK));
-          ASSERT(EAGAIN == EWOULDBLOCK);
-          if (bytesPeeked == 0) {
-            event_mask = (1 << kCloseEvent);
-            sd->MarkClosedRead();
-          } else if (errno != EWOULDBLOCK) {
-            const int kBufferSize = 1024;
-            char error_message[kBufferSize];
-            strerror_r(errno, error_message, kBufferSize);
-            Log::PrintErr("Error recv: %s\n", error_message);
-          }
-        }
-      }
-    }
-
-    // On pipes EPOLLHUP is reported without EPOLLIN when there is no
-    // more data to read.
-    if (sd->IsPipe()) {
-      if (((events & EPOLLIN) == 0) &&
-          ((events & EPOLLHUP) != 0)) {
-        event_mask = (1 << kCloseEvent);
-        sd->MarkClosedRead();
       }
     }
 
     if ((events & EPOLLOUT) != 0) {
       if ((events & EPOLLERR) != 0) {
-        event_mask = (1 << kErrorEvent);
-        sd->MarkClosedWrite();
+        if (!sd->IsPipe()) {
+          event_mask = (1 << kErrorEvent);
+        }
       } else {
         event_mask |= (1 << kOutEvent);
       }
@@ -339,10 +277,6 @@
       SocketData* sd = reinterpret_cast<SocketData*>(events[i].data.ptr);
       intptr_t event_mask = GetPollEvents(events[i].events, sd);
       if (event_mask != 0) {
-        // Unregister events for the file descriptor. Events will be
-        // registered again when the current event has been handled in
-        // Dart code.
-        RemoveFromEpollInstance(epoll_fd_, sd);
         Dart_Port port = sd->port();
         ASSERT(port != 0);
         DartUtils::PostInt32(port, event_mask);
@@ -416,13 +350,13 @@
 
 
 void EventHandlerImplementation::Shutdown() {
-  SendData(kShutdownId, 0, 0);
+  Notify(kShutdownId, 0, 0);
 }
 
 
-void EventHandlerImplementation::SendData(intptr_t id,
-                                          Dart_Port dart_port,
-                                          intptr_t data) {
+void EventHandlerImplementation::Notify(intptr_t id,
+                                        Dart_Port dart_port,
+                                        intptr_t data) {
   WakeupHandler(id, dart_port, data);
 }
 
diff --git a/runtime/bin/eventhandler_android.h b/runtime/bin/eventhandler_android.h
index 2056b27..5a80eef 100644
--- a/runtime/bin/eventhandler_android.h
+++ b/runtime/bin/eventhandler_android.h
@@ -28,46 +28,30 @@
 };
 
 
-enum PortDataFlags {
-  kClosedRead = 0,
-  kClosedWrite = 1,
-};
-
-
 class SocketData {
  public:
   explicit SocketData(intptr_t fd)
-      : tracked_by_epoll_(false), fd_(fd), port_(0), mask_(0), flags_(0) {
+      : tracked_by_epoll_(false), fd_(fd), port_(0), mask_(0) {
     ASSERT(fd_ != -1);
   }
 
-  intptr_t GetPollEvents();
-
   void ShutdownRead() {
     shutdown(fd_, SHUT_RD);
-    MarkClosedRead();
   }
 
   void ShutdownWrite() {
     shutdown(fd_, SHUT_WR);
-    MarkClosedWrite();
   }
 
   void Close() {
     port_ = 0;
     mask_ = 0;
-    flags_ = 0;
     close(fd_);
     fd_ = -1;
   }
 
   bool IsListeningSocket() { return (mask_ & (1 << kListeningSocket)) != 0; }
   bool IsPipe() { return (mask_ & (1 << kPipe)) != 0; }
-  bool IsClosedRead() { return (flags_ & (1 << kClosedRead)) != 0; }
-  bool IsClosedWrite() { return (flags_ & (1 << kClosedWrite)) != 0; }
-
-  void MarkClosedRead() { flags_ |= (1 << kClosedRead); }
-  void MarkClosedWrite() { flags_ |= (1 << kClosedWrite); }
 
   void SetPortAndMask(Dart_Port port, intptr_t mask) {
     ASSERT(fd_ != -1);
@@ -86,7 +70,6 @@
   intptr_t fd_;
   Dart_Port port_;
   intptr_t mask_;
-  intptr_t flags_;
 };
 
 
@@ -97,8 +80,8 @@
 
   // Gets the socket data structure for a given file
   // descriptor. Creates a new one if one is not found.
-  SocketData* GetSocketData(intptr_t fd);
-  void SendData(intptr_t id, Dart_Port dart_port, intptr_t data);
+  SocketData* GetSocketData(intptr_t fd, bool* is_new);
+  void Notify(intptr_t id, Dart_Port dart_port, intptr_t data);
   void Start(EventHandler* handler);
   void Shutdown();
 
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 0db1f53..612f3cb 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -20,7 +20,7 @@
 #include "bin/dartutils.h"
 #include "bin/fdutils.h"
 #include "bin/log.h"
-#include "bin/utils.h"
+#include "bin/socket.h"
 #include "platform/hashmap.h"
 #include "platform/thread.h"
 #include "platform/utils.h"
@@ -29,122 +29,56 @@
 namespace dart {
 namespace bin {
 
-static const int kInterruptMessageSize = sizeof(InterruptMessage);
 static const int kTimerId = -1;
-static const int kShutdownId = -2;
 
 
-intptr_t SocketData::GetPollEvents() {
-  // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are
-  // triggered anyway.
-  intptr_t events = 0;
-  if (!IsClosedRead()) {
-    if ((mask_ & (1 << kInEvent)) != 0) {
-      events |= EPOLLIN;
-    }
-  }
-  if (!IsClosedWrite()) {
-    if ((mask_ & (1 << kOutEvent)) != 0) {
-      events |= EPOLLOUT;
-    }
-  }
-  return events;
-}
-
-
-// Unregister the file descriptor for a SocketData structure with epoll.
-static void RemoveFromEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
-  if (sd->tracked_by_epoll()) {
-    int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                              EPOLL_CTL_DEL,
-                                              sd->fd(),
-                                              NULL));
-    if (status == -1) {
-      FATAL("Failed unregistering events for file descriptor");
-    }
-    sd->set_tracked_by_epoll(false);
-  }
-}
-
-
-// Register the file descriptor for a SocketData structure with epoll
-// if events are requested.
-static void UpdateEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
+static void AddToEpollInstance(intptr_t epoll_fd_,
+                               int fd, Dart_Port port,
+                               int mask) {
   struct epoll_event event;
-  event.events = sd->GetPollEvents();
-  event.data.ptr = sd;
-  if (sd->port() != 0 && event.events != 0) {
-    // Only report events once and wait for them to be re-enabled after the
-    // event has been handled by the Dart code.
-    event.events |= EPOLLONESHOT;
-    int status = 0;
-    if (sd->tracked_by_epoll()) {
-      status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                            EPOLL_CTL_MOD,
-                                            sd->fd(),
-                                            &event));
-    } else {
-      status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
+  event.events = EPOLLET | EPOLLRDHUP;
+  if ((mask & (1 << kInEvent)) != 0) event.events |= EPOLLIN;
+  if ((mask & (1 << kOutEvent)) != 0) event.events |= EPOLLOUT;
+  // Be sure we don't collide with the TIMER_BIT.
+  if (port == ILLEGAL_PORT) {
+    FATAL("Illigal port sent to event handler");
+  }
+  event.data.u64 = port;
+  int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
                                             EPOLL_CTL_ADD,
-                                            sd->fd(),
+                                            fd,
                                             &event));
-      sd->set_tracked_by_epoll(true);
-    }
-    if (status == -1) {
-      // Epoll does not accept the file descriptor. It could be due to
-      // already closed file descriptor, or unuspported devices, such
-      // as /dev/null. In such case, mark the file descriptor as closed,
-      // so dart will handle it accordingly.
-      sd->set_tracked_by_epoll(false);
-      sd->ShutdownRead();
-      sd->ShutdownWrite();
-      DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
-    }
+  if (status == -1) {
+    // Epoll does not accept the file descriptor. It could be due to
+    // already closed file descriptor, or unuspported devices, such
+    // as /dev/null. In such case, mark the file descriptor as closed,
+    // so dart will handle it accordingly.
+    DartUtils::PostInt32(port, 1 << kCloseEvent);
   }
 }
 
 
-EventHandlerImplementation::EventHandlerImplementation()
-    : socket_map_(&HashMap::SamePointerValue, 16) {
-  intptr_t result;
-  result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_));
-  if (result != 0) {
-    FATAL("Pipe creation failed");
-  }
-  FDUtils::SetNonBlocking(interrupt_fds_[0]);
-  FDUtils::SetCloseOnExec(interrupt_fds_[0]);
-  FDUtils::SetCloseOnExec(interrupt_fds_[1]);
-  shutdown_ = false;
+EventHandlerImplementation::EventHandlerImplementation() : shutdown_(false) {
   // The initial size passed to epoll_create is ignore on newer (>=
   // 2.6.8) Linux versions
   static const int kEpollInitialSize = 64;
   epoll_fd_ = TEMP_FAILURE_RETRY(epoll_create(kEpollInitialSize));
   if (epoll_fd_ == -1) {
-    FATAL("Failed creating epoll file descriptor");
+    FATAL1("Failed creating epoll file descriptor: %i", errno);
   }
   FDUtils::SetCloseOnExec(epoll_fd_);
-  // Register the interrupt_fd with the epoll instance.
-  struct epoll_event event;
-  event.events = EPOLLIN;
-  event.data.ptr = NULL;
-  int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                            EPOLL_CTL_ADD,
-                                            interrupt_fds_[0],
-                                            &event));
-  if (status == -1) {
-    FATAL("Failed adding interrupt fd to epoll instance");
-  }
   timer_fd_ = TEMP_FAILURE_RETRY(timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC));
-  if (epoll_fd_ == -1) {
-    FATAL("Failed creating timerfd file descriptor");
+  if (timer_fd_ == -1) {
+    FATAL1("Failed creating timerfd file descriptor: %i", errno);
   }
   // Register the timer_fd_ with the epoll instance.
+  struct epoll_event event;
   event.events = EPOLLIN;
-  event.data.fd = timer_fd_;
-  status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
-                                        EPOLL_CTL_ADD,
-                                        timer_fd_,
-                                        &event));
+  event.data.u64 = ILLEGAL_PORT;  // Use ILLEGAL_PORT to identify timer-fd.
+  int status = TEMP_FAILURE_RETRY(epoll_ctl(epoll_fd_,
+                                            EPOLL_CTL_ADD,
+                                            timer_fd_,
+                                            &event));
   if (status == -1) {
     FATAL2(
         "Failed adding timerfd fd(%i) to epoll instance: %i", timer_fd_, errno);
@@ -155,114 +89,12 @@
 EventHandlerImplementation::~EventHandlerImplementation() {
   TEMP_FAILURE_RETRY(close(epoll_fd_));
   TEMP_FAILURE_RETRY(close(timer_fd_));
-  TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
-  TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
-}
-
-
-SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
-  ASSERT(fd >= 0);
-  HashMap::Entry* entry = socket_map_.Lookup(
-      GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
-  ASSERT(entry != NULL);
-  SocketData* sd = reinterpret_cast<SocketData*>(entry->value);
-  if (sd == NULL) {
-    // If there is no data in the hash map for this file descriptor a
-    // new SocketData for the file descriptor is inserted.
-    sd = new SocketData(fd);
-    entry->value = sd;
-  }
-  ASSERT(fd == sd->fd());
-  return sd;
-}
-
-
-void EventHandlerImplementation::WakeupHandler(intptr_t id,
-                                               Dart_Port dart_port,
-                                               int64_t data) {
-  InterruptMessage msg;
-  msg.id = id;
-  msg.dart_port = dart_port;
-  msg.data = data;
-  // WriteToBlocking will write up to 512 bytes atomically, and since our msg
-  // is smaller than 512, we don't need a thread lock.
-  // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'.
-  ASSERT(kInterruptMessageSize < PIPE_BUF);
-  intptr_t result =
-      FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize);
-  if (result != kInterruptMessageSize) {
-    if (result == -1) {
-      perror("Interrupt message failure:");
-    }
-    FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result);
-  }
-}
-
-
-void EventHandlerImplementation::HandleInterruptFd() {
-  const intptr_t MAX_MESSAGES = kInterruptMessageSize;
-  InterruptMessage msg[MAX_MESSAGES];
-  ssize_t bytes = TEMP_FAILURE_RETRY(
-      read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize));
-  for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) {
-    if (msg[i].id == kTimerId) {
-      timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data);
-      struct itimerspec it;
-      memset(&it, 0, sizeof(it));
-      if (timeout_queue_.HasTimeout()) {
-        int64_t millis = timeout_queue_.CurrentTimeout();
-        it.it_value.tv_sec = millis / 1000;
-        it.it_value.tv_nsec = (millis % 1000) * 1000000;
-      }
-      timerfd_settime(timer_fd_, TFD_TIMER_ABSTIME, &it, NULL);
-    } else if (msg[i].id == kShutdownId) {
-      shutdown_ = true;
-    } else {
-      SocketData* sd = GetSocketData(msg[i].id);
-      if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) {
-        ASSERT(msg[i].data == (1 << kShutdownReadCommand));
-        // Close the socket for reading.
-        sd->ShutdownRead();
-        UpdateEpollInstance(epoll_fd_, sd);
-      } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) {
-        ASSERT(msg[i].data == (1 << kShutdownWriteCommand));
-        // Close the socket for writing.
-        sd->ShutdownWrite();
-        UpdateEpollInstance(epoll_fd_, sd);
-      } else if ((msg[i].data & (1 << kCloseCommand)) != 0) {
-        ASSERT(msg[i].data == (1 << kCloseCommand));
-        // Close the socket and free system resources and move on to
-        // next message.
-        RemoveFromEpollInstance(epoll_fd_, sd);
-        intptr_t fd = sd->fd();
-        if (fd == STDOUT_FILENO) {
-          // If stdout, redirect fd to /dev/null.
-          int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
-          ASSERT(null_fd >= 0);
-          VOID_TEMP_FAILURE_RETRY(dup2(null_fd, STDOUT_FILENO));
-          VOID_TEMP_FAILURE_RETRY(close(null_fd));
-        } else {
-          sd->Close();
-        }
-        socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
-        delete sd;
-        DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent);
-      } else {
-        if ((msg[i].data & (1 << kInEvent)) != 0 && sd->IsClosedRead()) {
-          DartUtils::PostInt32(msg[i].dart_port, 1 << kCloseEvent);
-        } else {
-          // Setup events to wait for.
-          sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
-          UpdateEpollInstance(epoll_fd_, sd);
-        }
-      }
-    }
-  }
 }
 
 #ifdef DEBUG_POLL
-static void PrintEventMask(intptr_t fd, intptr_t events) {
-  Log::Print("%d ", fd);
+static void PrintEventMask(intptr_t events) {
+  // TODO(ajohnsen): When DEBUG_POLL is enabled, we could add the fd to the
+  // epoll-data as well.
   if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN ");
   if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI ");
   if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT ");
@@ -274,123 +106,55 @@
   if ((events & ~all_events) != 0) {
     Log::Print("(and %08x) ", events & ~all_events);
   }
-  Log::Print("(available %d) ", FDUtils::AvailableBytes(fd));
 
   Log::Print("\n");
 }
 #endif
 
-intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events,
-                                                   SocketData* sd) {
+intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events) {
 #ifdef DEBUG_POLL
-  PrintEventMask(sd->fd(), events);
+  PrintEventMask(events);
 #endif
-  intptr_t event_mask = 0;
-  if (sd->IsListeningSocket()) {
-    // For listening sockets the EPOLLIN event indicate that there are
-    // connections ready for accept unless accompanied with one of the
-    // other flags.
-    if ((events & EPOLLIN) != 0) {
-      if ((events & EPOLLHUP) != 0) event_mask |= (1 << kCloseEvent);
-      if ((events & EPOLLERR) != 0) event_mask |= (1 << kErrorEvent);
-      if (event_mask == 0) event_mask |= (1 << kInEvent);
-    }
-  } else {
-    // Prioritize data events over close and error events.
-    if ((events & (EPOLLIN | EPOLLHUP | EPOLLERR)) != 0) {
-      // If we have EPOLLIN and we have available bytes, report that.
-      if ((events & EPOLLIN) && FDUtils::AvailableBytes(sd->fd()) != 0) {
-        event_mask = (1 << kInEvent);
-      } else if ((events & EPOLLHUP) != 0) {
-        // If both EPOLLHUP and EPOLLERR are reported treat it as an
-        // error.
-        if ((events & EPOLLERR) != 0) {
-          event_mask = (1 << kErrorEvent);
-        } else {
-          event_mask = (1 << kCloseEvent);
-        }
-        sd->MarkClosedRead();
-      } else if ((events & EPOLLERR) != 0) {
-        event_mask = (1 << kErrorEvent);
-      } else {
-        if (sd->IsPipe()) {
-          // When reading from stdin (either from a terminal or piped
-          // input) treat EPOLLIN with 0 available bytes as
-          // end-of-file.
-          if (sd->fd() == STDIN_FILENO) {
-            event_mask = (1 << kCloseEvent);
-            sd->MarkClosedRead();
-          }
-        } else {
-          // If EPOLLIN is set with no available data and no EPOLLHUP use
-          // recv to peek for whether the other end of the socket
-          // actually closed.
-          char buffer;
-          ssize_t bytesPeeked =
-              TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK));
-          ASSERT(EAGAIN == EWOULDBLOCK);
-          if (bytesPeeked == 0) {
-            event_mask = (1 << kCloseEvent);
-            sd->MarkClosedRead();
-          } else if (errno != EWOULDBLOCK) {
-            const int kBufferSize = 1024;
-            char error_buf[kBufferSize];
-            Log::PrintErr("Error recv: %s\n",
-                          strerror_r(errno, error_buf, kBufferSize));
-          }
-        }
-      }
-    }
-
-    if ((events & EPOLLOUT) != 0) {
-      if ((events & EPOLLERR) != 0) {
-        event_mask = (1 << kErrorEvent);
-        sd->MarkClosedWrite();
-      } else {
-        event_mask |= (1 << kOutEvent);
-      }
-    }
+  if (events & EPOLLERR) {
+    // Return only error if EPOLLIN is present.
+    return (events & EPOLLIN) ? (1 << kErrorEvent) : 0;
   }
-
+  intptr_t event_mask = 0;
+  if (events & EPOLLIN) event_mask |= (1 << kInEvent);
+  if (events & EPOLLOUT) event_mask |= (1 << kOutEvent);
+  if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent);
   return event_mask;
 }
 
 
 void EventHandlerImplementation::HandleEvents(struct epoll_event* events,
                                               int size) {
-  bool interrupt_seen = false;
   for (int i = 0; i < size; i++) {
-    if (events[i].data.ptr == NULL) {
-      interrupt_seen = true;
-    } else if (events[i].data.fd == timer_fd_) {
+    uint64_t data = events[i].data.u64;
+    // ILLEGAL_PORT is used to identify timer-fd.
+    if (data == ILLEGAL_PORT) {
       int64_t val;
       VOID_TEMP_FAILURE_RETRY(read(timer_fd_, &val, sizeof(val)));
+      timer_mutex_.Lock();
       if (timeout_queue_.HasTimeout()) {
         DartUtils::PostNull(timeout_queue_.CurrentPort());
         timeout_queue_.RemoveCurrent();
       }
+      timer_mutex_.Unlock();
     } else {
-      SocketData* sd = reinterpret_cast<SocketData*>(events[i].data.ptr);
-      intptr_t event_mask = GetPollEvents(events[i].events, sd);
-      if (event_mask == 0) {
-        // Event not handled, re-add to epoll.
-        UpdateEpollInstance(epoll_fd_, sd);
-      } else {
-        Dart_Port port = sd->port();
+      int32_t event_mask = GetPollEvents(events[i].events);
+      if (event_mask != 0) {
+        Dart_Port port = data;
         ASSERT(port != 0);
         DartUtils::PostInt32(port, event_mask);
       }
     }
   }
-  if (interrupt_seen) {
-    // Handle after socket events, so we avoid closing a socket before we handle
-    // the current events.
-    HandleInterruptFd();
-  }
 }
 
 
 void EventHandlerImplementation::Poll(uword args) {
+  // Main event-handler thread loop.
   static const intptr_t kMaxEvents = 16;
   struct epoll_event events[kMaxEvents];
   EventHandler* handler = reinterpret_cast<EventHandler*>(args);
@@ -424,26 +188,51 @@
 
 
 void EventHandlerImplementation::Shutdown() {
-  SendData(kShutdownId, 0, 0);
+  shutdown_ = true;
 }
 
 
-void EventHandlerImplementation::SendData(intptr_t id,
-                                          Dart_Port dart_port,
-                                          int64_t data) {
-  WakeupHandler(id, dart_port, data);
-}
-
-
-void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) {
-  // The hashmap does not support keys with value 0.
-  return reinterpret_cast<void*>(fd + 1);
-}
-
-
-uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) {
-  // The hashmap does not support keys with value 0.
-  return dart::Utils::WordHash(fd + 1);
+void EventHandlerImplementation::Notify(intptr_t id,
+                                        Dart_Port dart_port,
+                                        int64_t data) {
+  // This method is called by isolates, that is, not in the event-handler
+  // thread.
+  if (id == kTimerId) {
+    // Lock this region, as multiple isolates may attempt to update
+    // timeout_queue_.
+    // TODO(ajohnsen): Consider using a timer-fd per isolate to avoid the lock.
+    timer_mutex_.Lock();
+    timeout_queue_.UpdateTimeout(dart_port, data);
+    struct itimerspec it;
+    memset(&it, 0, sizeof(it));
+    if (timeout_queue_.HasTimeout()) {
+      int64_t millis = timeout_queue_.CurrentTimeout();
+      it.it_value.tv_sec = millis / 1000;
+      it.it_value.tv_nsec = (millis % 1000) * 1000000;
+    }
+    timerfd_settime(timer_fd_, TFD_TIMER_ABSTIME, &it, NULL);
+    timer_mutex_.Unlock();
+  } else {
+    if ((data & (1 << kShutdownReadCommand)) != 0) {
+      ASSERT(data == (1 << kShutdownReadCommand));
+      // Close the socket for reading.
+      shutdown(id, SHUT_RD);
+    } else if ((data & (1 << kShutdownWriteCommand)) != 0) {
+      ASSERT(data == (1 << kShutdownWriteCommand));
+      // Close the socket for writing.
+      shutdown(id, SHUT_WR);
+    } else if ((data & (1 << kCloseCommand)) != 0) {
+      ASSERT(data == (1 << kCloseCommand));
+      // Close the socket and free system resources and move on to
+      // next message.
+      // This will also remove the file descriptor from epoll.
+      Socket::Close(id);
+      DartUtils::PostInt32(dart_port, 1 << kDestroyedEvent);
+    } else {
+      // Add to epoll - this is the first time we see it.
+      AddToEpollInstance(epoll_fd_, id, dart_port, data);
+    }
+  }
 }
 
 }  // namespace bin
diff --git a/runtime/bin/eventhandler_linux.h b/runtime/bin/eventhandler_linux.h
index 2e811e8..f5386c3 100644
--- a/runtime/bin/eventhandler_linux.h
+++ b/runtime/bin/eventhandler_linux.h
@@ -14,109 +14,32 @@
 #include <sys/socket.h>
 
 #include "platform/hashmap.h"
+#include "platform/thread.h"
 
 
 namespace dart {
 namespace bin {
 
-class InterruptMessage {
- public:
-  intptr_t id;
-  Dart_Port dart_port;
-  int64_t data;
-};
-
-
-enum PortDataFlags {
-  kClosedRead = 0,
-  kClosedWrite = 1,
-};
-
-
-class SocketData {
- public:
-  explicit SocketData(intptr_t fd)
-      : tracked_by_epoll_(false), fd_(fd), port_(0), mask_(0), flags_(0) {
-    ASSERT(fd_ != -1);
-  }
-
-  intptr_t GetPollEvents();
-
-  void ShutdownRead() {
-    shutdown(fd_, SHUT_RD);
-    MarkClosedRead();
-  }
-
-  void ShutdownWrite() {
-    shutdown(fd_, SHUT_WR);
-    MarkClosedWrite();
-  }
-
-  void Close() {
-    port_ = 0;
-    mask_ = 0;
-    flags_ = 0;
-    close(fd_);
-    fd_ = -1;
-  }
-
-  bool IsListeningSocket() { return (mask_ & (1 << kListeningSocket)) != 0; }
-  bool IsPipe() { return (mask_ & (1 << kPipe)) != 0; }
-  bool IsClosedRead() { return (flags_ & (1 << kClosedRead)) != 0; }
-  bool IsClosedWrite() { return (flags_ & (1 << kClosedWrite)) != 0; }
-
-  void MarkClosedRead() { flags_ |= (1 << kClosedRead); }
-  void MarkClosedWrite() { flags_ |= (1 << kClosedWrite); }
-
-  void SetPortAndMask(Dart_Port port, intptr_t mask) {
-    ASSERT(fd_ != -1);
-    port_ = port;
-    mask_ = mask;
-  }
-
-  intptr_t fd() { return fd_; }
-  Dart_Port port() { return port_; }
-  intptr_t mask() { return mask_; }
-  bool tracked_by_epoll() { return tracked_by_epoll_; }
-  void set_tracked_by_epoll(bool value) { tracked_by_epoll_ = value; }
-
- private:
-  bool tracked_by_epoll_;
-  intptr_t fd_;
-  Dart_Port port_;
-  intptr_t mask_;
-  intptr_t flags_;
-};
-
-
 class EventHandlerImplementation {
  public:
   EventHandlerImplementation();
   ~EventHandlerImplementation();
 
-  // Gets the socket data structure for a given file
-  // descriptor. Creates a new one if one is not found.
-  SocketData* GetSocketData(intptr_t fd);
-  void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
+  void Notify(intptr_t id, Dart_Port dart_port, int64_t data);
   void Start(EventHandler* handler);
   void Shutdown();
 
  private:
   void HandleEvents(struct epoll_event* events, int size);
   static void Poll(uword args);
-  void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data);
-  void HandleInterruptFd();
   void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask);
-  intptr_t GetPollEvents(intptr_t events, SocketData* sd);
-  static void* GetHashmapKeyFromFd(intptr_t fd);
-  static uint32_t GetHashmapHashFromFd(intptr_t fd);
+  intptr_t GetPollEvents(intptr_t events);
 
-  HashMap socket_map_;
   TimeoutQueue timeout_queue_;
   bool shutdown_;
-  int interrupt_fds_[2];
   int epoll_fd_;
   int timer_fd_;
+  Mutex timer_mutex_;
 };
 
 }  // namespace bin
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index bf047a4..b7d4fde 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -34,105 +34,83 @@
 
 
 bool SocketData::HasReadEvent() {
-  return !IsClosedRead() && ((mask_ & (1 << kInEvent)) != 0);
+  return (mask_ & (1 << kInEvent)) != 0;
 }
 
 
 bool SocketData::HasWriteEvent() {
-  return !IsClosedWrite() && ((mask_ & (1 << kOutEvent)) != 0);
+  return (mask_ & (1 << kOutEvent)) != 0;
 }
 
 
 // Unregister the file descriptor for a SocketData structure with kqueue.
 static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) {
+  if (!sd->tracked_by_kqueue()) return;
   static const intptr_t kMaxChanges = 2;
   intptr_t changes = 0;
   struct kevent events[kMaxChanges];
-  if (sd->read_tracked_by_kqueue()) {
+  if (sd->HasReadEvent()) {
     EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL);
     ++changes;
-    sd->set_read_tracked_by_kqueue(false);
   }
-  if (sd->write_tracked_by_kqueue()) {
-    EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, sd);
+  if (sd->HasWriteEvent()) {
+    EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
     ++changes;
-    sd->set_write_tracked_by_kqueue(false);
   }
-  if (changes > 0) {
-    ASSERT(changes <= kMaxChanges);
-    int status =
-      TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
-    if (status == -1) {
-      const int kBufferSize = 1024;
-      char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
-      FATAL1("Failed deleting events from kqueue: %s\n", error_message);
-    }
+  ASSERT(changes > 0);
+  ASSERT(changes <= kMaxChanges);
+  int status =
+    TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
+  if (status == -1) {
+    const int kBufferSize = 1024;
+    char error_message[kBufferSize];
+    strerror_r(errno, error_message, kBufferSize);
+    FATAL1("Failed deleting events from kqueue: %s\n", error_message);
   }
+  sd->set_tracked_by_kqueue(false);
 }
 
 
 // Update the kqueue registration for SocketData structure to reflect
 // the events currently of interest.
-static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) {
+static void AddToKqueue(intptr_t kqueue_fd_, SocketData* sd) {
   static const intptr_t kMaxChanges = 2;
   intptr_t changes = 0;
   struct kevent events[kMaxChanges];
-  // Only report events once and wait for them to be re-enabled after the
-  // event has been handled by the Dart code. This is done by using EV_ONESHOT.
-  if (sd->port() != 0) {
-    // Register or unregister READ filter if needed.
-    if (sd->HasReadEvent()) {
-      if (!sd->read_tracked_by_kqueue()) {
-        EV_SET(events + changes,
-               sd->fd(),
-               EVFILT_READ,
-               EV_ADD | EV_ONESHOT,
-               0,
-               0,
-               sd);
-        ++changes;
-        sd->set_read_tracked_by_kqueue(true);
-      }
-    } else if (sd->read_tracked_by_kqueue()) {
-      EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL);
-      ++changes;
-      sd->set_read_tracked_by_kqueue(false);
-    }
-    // Register or unregister WRITE filter if needed.
-    if (sd->HasWriteEvent()) {
-      if (!sd->write_tracked_by_kqueue()) {
-        EV_SET(events + changes,
-               sd->fd(),
-               EVFILT_WRITE,
-               EV_ADD | EV_ONESHOT,
-               0,
-               0,
-               sd);
-        ++changes;
-        sd->set_write_tracked_by_kqueue(true);
-      }
-    } else if (sd->write_tracked_by_kqueue()) {
-      EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
-      ++changes;
-      sd->set_write_tracked_by_kqueue(false);
-    }
+  // Register or unregister READ filter if needed.
+  if (sd->HasReadEvent()) {
+    EV_SET(events + changes,
+           sd->fd(),
+           EVFILT_READ,
+           EV_ADD | EV_CLEAR,
+           0,
+           0,
+           sd);
+    ++changes;
   }
-  if (changes > 0) {
-    ASSERT(changes <= kMaxChanges);
-    int status =
-      TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
-    if (status == -1) {
-      // kQueue does not accept the file descriptor. It could be due to
-      // already closed file descriptor, or unuspported devices, such
-      // as /dev/null. In such case, mark the file descriptor as closed,
-      // so dart will handle it accordingly.
-      sd->set_write_tracked_by_kqueue(false);
-      sd->set_read_tracked_by_kqueue(false);
-      sd->ShutdownRead();
-      sd->ShutdownWrite();
-      DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
-    }
+  // Register or unregister WRITE filter if needed.
+  if (sd->HasWriteEvent()) {
+    EV_SET(events + changes,
+           sd->fd(),
+           EVFILT_WRITE,
+           EV_ADD | EV_CLEAR,
+           0,
+           0,
+           sd);
+    ++changes;
+  }
+  ASSERT(changes > 0);
+  ASSERT(changes <= kMaxChanges);
+  int status =
+    TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
+  if (status == -1) {
+    // kQueue does not accept the file descriptor. It could be due to
+    // already closed file descriptor, or unuspported devices, such
+    // as /dev/null. In such case, mark the file descriptor as closed,
+    // so dart will handle it accordingly.
+    DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
+  } else {
+    sd->set_tracked_by_kqueue(true);
   }
 }
 
@@ -174,7 +152,8 @@
 }
 
 
-SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
+SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd,
+                                                      bool* is_new) {
   ASSERT(fd >= 0);
   HashMap::Entry* entry = socket_map_.Lookup(
       GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
@@ -185,6 +164,7 @@
     // new SocketData for the file descriptor is inserted.
     sd = new SocketData(fd);
     entry->value = sd;
+    *is_new = true;
   }
   ASSERT(fd == sd->fd());
   return sd;
@@ -223,43 +203,31 @@
     } else if (msg[i].id == kShutdownId) {
       shutdown_ = true;
     } else {
-      SocketData* sd = GetSocketData(msg[i].id);
+      bool is_new = false;
+      SocketData* sd = GetSocketData(msg[i].id, &is_new);
+      if (is_new) {
+        sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
+      }
       if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kShutdownReadCommand));
         // Close the socket for reading.
         sd->ShutdownRead();
-        UpdateKqueue(kqueue_fd_, sd);
       } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kShutdownWriteCommand));
         // Close the socket for writing.
         sd->ShutdownWrite();
-        UpdateKqueue(kqueue_fd_, sd);
       } else if ((msg[i].data & (1 << kCloseCommand)) != 0) {
         ASSERT(msg[i].data == (1 << kCloseCommand));
         // Close the socket and free system resources.
         RemoveFromKqueue(kqueue_fd_, sd);
         intptr_t fd = sd->fd();
-        if (fd == STDOUT_FILENO) {
-          // If stdout, redirect fd to /dev/null.
-          int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
-          ASSERT(null_fd >= 0);
-          VOID_TEMP_FAILURE_RETRY(dup2(null_fd, STDOUT_FILENO));
-          VOID_TEMP_FAILURE_RETRY(close(null_fd));
-        } else {
-          sd->Close();
-        }
+        sd->Close();
         socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
         delete sd;
         DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent);
       } else {
-        if ((msg[i].data & (1 << kInEvent)) != 0 && sd->IsClosedRead()) {
-          DartUtils::PostInt32(msg[i].dart_port, 1 << kCloseEvent);
-        } else {
-          // Setup events to wait for.
-          ASSERT((msg[i].data > 0) && (msg[i].data < kIntptrMax));
-          sd->SetPortAndMask(msg[i].dart_port,
-                             static_cast<intptr_t>(msg[i].data));
-          UpdateKqueue(kqueue_fd_, sd);
+        if (is_new) {
+          AddToKqueue(kqueue_fd_, sd);
         }
       }
     }
@@ -269,12 +237,17 @@
 #ifdef DEBUG_KQUEUE
 static void PrintEventMask(intptr_t fd, struct kevent* event) {
   Log::Print("%d ", static_cast<int>(fd));
+  Log::Print("filter=0x%x:", event->filter);
   if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ ");
   if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE ");
   Log::Print("flags: %x: ", event->flags);
   if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF ");
   if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR ");
+  if ((event->flags & EV_CLEAR) != 0) Log::Print("EV_CLEAR ");
+  if ((event->flags & EV_ADD) != 0) Log::Print("EV_ADD ");
+  if ((event->flags & EV_DELETE) != 0) Log::Print("EV_DELETE ");
   Log::Print("- fflags: %d ", event->fflags);
+  Log::Print("- data: %ld ", event->data);
   Log::Print("(available %d) ",
       static_cast<int>(FDUtils::AvailableBytes(fd)));
   Log::Print("\n");
@@ -306,30 +279,20 @@
   } else {
     // Prioritize data events over close and error events.
     if (event->filter == EVFILT_READ) {
-      if (FDUtils::AvailableBytes(sd->fd()) != 0) {
-         event_mask = (1 << kInEvent);
-      } else if ((event->flags & EV_EOF) != 0) {
-        if (event->fflags != 0) {
-          event_mask |= (1 << kErrorEvent);
-        } else {
-          event_mask |= (1 << kCloseEvent);
-        }
-        sd->MarkClosedRead();
-      }
-    } else if (event->filter == EVFILT_WRITE) {
+      event_mask = (1 << kInEvent);
       if ((event->flags & EV_EOF) != 0) {
         if (event->fflags != 0) {
-          event_mask |= (1 << kErrorEvent);
+          event_mask = (1 << kErrorEvent);
         } else {
           event_mask |= (1 << kCloseEvent);
         }
-        // If the receiver closed for reading, close for writing,
-        // update the registration with kqueue, and do not report a
-        // write event.
-        sd->MarkClosedWrite();
-        UpdateKqueue(kqueue_fd_, sd);
-      } else {
-        event_mask |= (1 << kOutEvent);
+      }
+    } else if (event->filter == EVFILT_WRITE) {
+      event_mask |= (1 << kOutEvent);
+      if ((event->flags & EV_EOF) != 0) {
+        if (event->fflags != 0) {
+          event_mask = (1 << kErrorEvent);
+        }
       }
     } else {
       UNREACHABLE();
@@ -355,13 +318,8 @@
       interrupt_seen = true;
     } else {
       SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata);
-      sd->set_write_tracked_by_kqueue(false);
-      sd->set_read_tracked_by_kqueue(false);
       intptr_t event_mask = GetEvents(events + i, sd);
-      if (event_mask == 0) {
-        // Event not handled, re-add to kqueue.
-        UpdateKqueue(kqueue_fd_, sd);
-      } else {
+      if (event_mask != 0) {
         Dart_Port port = sd->port();
         ASSERT(port != 0);
         DartUtils::PostInt32(port, event_mask);
@@ -450,13 +408,13 @@
 
 
 void EventHandlerImplementation::Shutdown() {
-  SendData(kShutdownId, 0, 0);
+  Notify(kShutdownId, 0, 0);
 }
 
 
-void EventHandlerImplementation::SendData(intptr_t id,
-                                          Dart_Port dart_port,
-                                          int64_t data) {
+void EventHandlerImplementation::Notify(intptr_t id,
+                                        Dart_Port dart_port,
+                                        int64_t data) {
   WakeupHandler(id, dart_port, data);
 }
 
diff --git a/runtime/bin/eventhandler_macos.h b/runtime/bin/eventhandler_macos.h
index cb765c6..acbfc91 100644
--- a/runtime/bin/eventhandler_macos.h
+++ b/runtime/bin/eventhandler_macos.h
@@ -10,6 +10,7 @@
 #endif
 
 #include <unistd.h>
+#include <errno.h>
 #include <sys/event.h>  // NOLINT
 #include <sys/socket.h>
 
@@ -27,21 +28,13 @@
 };
 
 
-enum PortDataFlags {
-  kClosedRead = 0,
-  kClosedWrite = 1,
-};
-
-
 class SocketData {
  public:
   explicit SocketData(intptr_t fd)
       : fd_(fd),
         port_(0),
         mask_(0),
-        flags_(0),
-        read_tracked_by_kqueue_(false),
-        write_tracked_by_kqueue_(false) {
+        tracked_by_kqueue_(false) {
     ASSERT(fd_ != -1);
   }
 
@@ -50,29 +43,21 @@
 
   void ShutdownRead() {
     shutdown(fd_, SHUT_RD);
-    MarkClosedRead();
   }
 
   void ShutdownWrite() {
     shutdown(fd_, SHUT_WR);
-    MarkClosedWrite();
   }
 
   void Close() {
     port_ = 0;
     mask_ = 0;
-    flags_ = 0;
     close(fd_);
     fd_ = -1;
   }
 
   bool IsListeningSocket() { return (mask_ & (1 << kListeningSocket)) != 0; }
   bool IsPipe() { return (mask_ & (1 << kPipe)) != 0; }
-  bool IsClosedRead() { return (flags_ & (1 << kClosedRead)) != 0; }
-  bool IsClosedWrite() { return (flags_ & (1 << kClosedWrite)) != 0; }
-
-  void MarkClosedRead() { flags_ |= (1 << kClosedRead); }
-  void MarkClosedWrite() { flags_ |= (1 << kClosedWrite); }
 
   void SetPortAndMask(Dart_Port port, intptr_t mask) {
     ASSERT(fd_ != -1);
@@ -83,22 +68,16 @@
   intptr_t fd() { return fd_; }
   Dart_Port port() { return port_; }
   intptr_t mask() { return mask_; }
-  bool read_tracked_by_kqueue() { return read_tracked_by_kqueue_; }
-  void set_read_tracked_by_kqueue(bool value) {
-    read_tracked_by_kqueue_ = value;
-  }
-  bool write_tracked_by_kqueue() { return write_tracked_by_kqueue_; }
-  void set_write_tracked_by_kqueue(bool value) {
-    write_tracked_by_kqueue_ = value;
+  bool tracked_by_kqueue() { return tracked_by_kqueue_; }
+  void set_tracked_by_kqueue(bool value) {
+    tracked_by_kqueue_ = value;
   }
 
  private:
   intptr_t fd_;
   Dart_Port port_;
   intptr_t mask_;
-  intptr_t flags_;
-  bool read_tracked_by_kqueue_;
-  bool write_tracked_by_kqueue_;
+  bool tracked_by_kqueue_;
 };
 
 
@@ -109,8 +88,8 @@
 
   // Gets the socket data structure for a given file
   // descriptor. Creates a new one if one is not found.
-  SocketData* GetSocketData(intptr_t fd);
-  void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
+  SocketData* GetSocketData(intptr_t fd, bool* is_new);
+  void Notify(intptr_t id, Dart_Port dart_port, int64_t data);
   void Start(EventHandler* handler);
   void Shutdown();
 
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 993670c..534f328 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -160,7 +160,6 @@
                                             reinterpret_cast<ULONG_PTR>(this),
                                             0);
   if (completion_port_ == NULL) {
-    Log::PrintErr("Error CreateIoCompletionPort: %d\n", GetLastError());
     return false;
   }
   return true;
@@ -247,9 +246,6 @@
                      &bytes_read,
                      NULL);
   if (!ok) {
-    if (GetLastError() != ERROR_BROKEN_PIPE) {
-      Log::PrintErr("ReadFile failed %d\n", GetLastError());
-    }
     bytes_read = 0;
   }
   OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped();
@@ -373,6 +369,9 @@
 
 bool DirectoryWatchHandle::IssueRead() {
   ScopedLock lock(this);
+  // It may have been started before, as we start the directory-handler when
+  // we create it.
+  if (pending_read_ != NULL) return true;
   OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
 
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
@@ -420,7 +419,6 @@
                         NULL,
                         NULL);
   if (status == SOCKET_ERROR) {
-    Log::PrintErr("Error WSAIoctl failed: %d\n", WSAGetLastError());
     return false;
   }
   return true;
@@ -488,7 +486,6 @@
         accepted_tail_ = client_socket;
       }
     } else {
-      Log::PrintErr("setsockopt failed: %d\n", WSAGetLastError());
       closesocket(buffer->client());
     }
   } else {
@@ -529,6 +526,13 @@
   accepted_head_ = accepted_head_->next();
   if (accepted_head_ == NULL) accepted_tail_ = NULL;
   result->set_next(NULL);
+  if (!IsClosing()) {
+    while (pending_accept_count() < 5) {
+      if (!IssueAccept()) {
+        event_handler_->HandleError(this);
+      }
+    }
+  }
   return result;
 }
 
@@ -566,6 +570,7 @@
   if (data_ready_->IsEmpty()) {
     OverlappedBuffer::DisposeBuffer(data_ready_);
     data_ready_ = NULL;
+    if (!IsClosing() && !IsClosedRead()) IssueRead();
   }
   return num_bytes;
 }
@@ -588,6 +593,7 @@
   // entirety to match how recvfrom works in a socket.
   OverlappedBuffer::DisposeBuffer(data_ready_);
   data_ready_ = NULL;
+  if (!IsClosing() && !IsClosedRead()) IssueRecvFrom();
   return num_bytes;
 }
 
@@ -655,9 +661,6 @@
                       &bytes_written,
                       NULL);
   if (!ok) {
-    if (GetLastError() != ERROR_BROKEN_PIPE) {
-      Log::PrintErr("WriteFile failed %d\n", GetLastError());
-    }
     bytes_written = 0;
   }
   thread_wrote_ += bytes_written;
@@ -715,14 +718,7 @@
       locker.Wait(Monitor::kNoTimeout);
     }
   }
-  if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
-    int fd = _open("NUL", _O_WRONLY);
-    ASSERT(fd >= 0);
-    _dup2(fd, _fileno(stdout));
-    close(fd);
-  } else {
-    Handle::DoClose();
-  }
+  Handle::DoClose();
 }
 
 
@@ -740,7 +736,6 @@
                         NULL,
                         NULL);
   if (status == SOCKET_ERROR) {
-    Log::PrintErr("Error WSAIoctl failed: %d\n", WSAGetLastError());
     return false;
   }
   return true;
@@ -988,62 +983,49 @@
 
       Handle::ScopedLock lock(handle);
 
-      if (handle->IsError()) {
-        DartUtils::PostInt32(msg->dart_port, 1 << kErrorEvent);
-      } else {
-        if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
-          // Only set mask if we turned on kInEvent or kOutEvent.
-          handle->SetPortAndMask(msg->dart_port, msg->data);
+      // Only set mask if we turned on kInEvent or kOutEvent.
+      if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
+        handle->SetPortAndMask(msg->dart_port, msg->data);
+      }
 
-          // If in events (data available events) have been requested, and data
-          // is available, post an in event immediately. Otherwise make sure
-          // that a pending read is issued, unless the socket is already closed
-          // for read.
-          if ((msg->data & (1 << kInEvent)) != 0) {
-            if (handle->Available() > 0) {
-              int event_mask = (1 << kInEvent);
-              handle->set_mask(handle->mask() & ~event_mask);
-              DartUtils::PostInt32(handle->port(), event_mask);
-            } else if (handle->IsClosedRead()) {
-              int event_mask = (1 << kCloseEvent);
-              DartUtils::PostInt32(handle->port(), event_mask);
-            } else if (!handle->HasPendingRead()) {
-              if (handle->is_datagram_socket()) {
-                handle->IssueRecvFrom();
-              } else {
-                handle->IssueRead();
-              }
-            }
-          }
-
-          // If out events (can write events) have been requested, and there
-          // are no pending writes, post an out event immediately.
-          if ((msg->data & (1 << kOutEvent)) != 0) {
-            if (!handle->HasPendingWrite()) {
-              int event_mask = (1 << kOutEvent);
-              handle->set_mask(handle->mask() & ~event_mask);
-              DartUtils::PostInt32(handle->port(), event_mask);
-            }
-          }
-        }
-
-        if (handle->is_client_socket()) {
-          ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
-          if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
-            client_socket->Shutdown(SD_RECEIVE);
-          }
-
-          if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
-            client_socket->Shutdown(SD_SEND);
-          }
+      // Issue a read.
+      if ((msg->data & (1 << kInEvent)) != 0) {
+        handle->SetPortAndMask(msg->dart_port, msg->data);
+        if (handle->is_datagram_socket()) {
+          handle->IssueRecvFrom();
+        } else {
+          handle->IssueRead();
         }
       }
 
-      if ((msg->data & (1 << kCloseCommand)) != 0) {
+      // If out events (can write events) have been requested, and there
+      // are no pending writes, meaning any writes are already complete,
+      // post an out event immediately.
+      if ((msg->data & (1 << kOutEvent)) != 0) {
         handle->SetPortAndMask(msg->dart_port, msg->data);
-        handle->Close();
+        if (!handle->HasPendingWrite()) {
+          int event_mask = (1 << kOutEvent);
+          DartUtils::PostInt32(handle->port(), event_mask);
+        }
+      }
+
+      if (handle->is_client_socket()) {
+        ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
+        if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
+          client_socket->Shutdown(SD_RECEIVE);
+        }
+
+        if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
+          client_socket->Shutdown(SD_SEND);
+        }
       }
     }
+
+    if ((msg->data & (1 << kCloseCommand)) != 0) {
+      handle->SetPortAndMask(msg->dart_port, msg->data);
+      handle->Close();
+    }
+
     DeleteIfClosed(handle);
   }
 }
@@ -1129,15 +1111,13 @@
                                              OverlappedBuffer* buffer) {
   handle->WriteComplete(buffer);
 
-  if (bytes > 0) {
+  if (bytes >= 0) {
     if (!handle->IsError() && !handle->IsClosing()) {
       int event_mask = 1 << kOutEvent;
       if ((handle->mask() & event_mask) != 0) {
         DartUtils::PostInt32(handle->port(), event_mask);
       }
     }
-  } else if (bytes == 0) {
-    HandleClosed(handle);
   } else {
     HandleError(handle);
   }
@@ -1223,9 +1203,9 @@
 }
 
 
-void EventHandlerImplementation::SendData(intptr_t id,
-                                          Dart_Port dart_port,
-                                          int64_t data) {
+void EventHandlerImplementation::Notify(intptr_t id,
+                                        Dart_Port dart_port,
+                                        int64_t data) {
   InterruptMessage* msg = new InterruptMessage;
   msg->id = id;
   msg->dart_port = dart_port;
@@ -1309,7 +1289,7 @@
 
 
 void EventHandlerImplementation::Shutdown() {
-  SendData(kShutdownId, 0, 0);
+  Notify(kShutdownId, 0, 0);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 90e505a..b756e07 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -485,7 +485,7 @@
   EventHandlerImplementation();
   virtual ~EventHandlerImplementation();
 
-  void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
+  void Notify(intptr_t id, Dart_Port dart_port, int64_t data);
   void Start(EventHandler* handler);
   void Shutdown();
 
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index d7fcaed..9b9906a 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -31,7 +31,7 @@
   int64_t remaining = num_bytes;
   char* current_buffer = reinterpret_cast<char*>(buffer);
   while (remaining > 0) {
-    int bytes_read = Read(current_buffer, remaining);
+    int64_t bytes_read = Read(current_buffer, remaining);
     if (bytes_read <= 0) {
       return false;
     }
@@ -46,7 +46,7 @@
   int64_t remaining = num_bytes;
   const char* current_buffer = reinterpret_cast<const char*>(buffer);
   while (remaining > 0) {
-    int bytes_read = Write(current_buffer, remaining);
+    int64_t bytes_read = Write(current_buffer, remaining);
     if (bytes_read < 0) {
       return false;
     }
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index b00e22d..6c740c5 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -38,22 +38,27 @@
 
 
 File::~File() {
-  // Close the file (unless it's a standard stream).
-  if (handle_->fd() > STDERR_FILENO) {
-    Close();
-  }
+  Close();
   delete handle_;
 }
 
 
 void File::Close() {
   ASSERT(handle_->fd() >= 0);
-  int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
-  if (err != 0) {
-    const int kBufferSize = 1024;
-    char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
-    Log::PrintErr("%s\n", error_message);
+  if (handle_->fd() == STDOUT_FILENO) {
+    // If stdout, redirect fd to /dev/null.
+    int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
+    ASSERT(null_fd >= 0);
+    VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
+    VOID_TEMP_FAILURE_RETRY(close(null_fd));
+  } else {
+    int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
+    if (err != 0) {
+      const int kBufferSize = 1024;
+      char error_message[kBufferSize];
+      strerror_r(errno, error_message, kBufferSize);
+      Log::PrintErr("%s\n", error_message);
+    }
   }
   handle_->set_fd(kClosedFd);
 }
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index bc6f610..2e79248 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -38,21 +38,26 @@
 
 
 File::~File() {
-  // Close the file (unless it's a standard stream).
-  if (handle_->fd() > STDERR_FILENO) {
-    Close();
-  }
+  Close();
   delete handle_;
 }
 
 
 void File::Close() {
   ASSERT(handle_->fd() >= 0);
-  int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
-  if (err != 0) {
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
+  if (handle_->fd() == STDOUT_FILENO) {
+    // If stdout, redirect fd to /dev/null.
+    int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
+    ASSERT(null_fd >= 0);
+    VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
+    VOID_TEMP_FAILURE_RETRY(close(null_fd));
+  } else {
+    int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
+    if (err != 0) {
+      const int kBufferSize = 1024;
+      char error_buf[kBufferSize];
+      Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
+    }
   }
   handle_->set_fd(kClosedFd);
 }
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 6f704bf..46017fb 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -38,22 +38,27 @@
 
 
 File::~File() {
-  // Close the file (unless it's a standard stream).
-  if (handle_->fd() > STDERR_FILENO) {
-    Close();
-  }
+  Close();
   delete handle_;
 }
 
 
 void File::Close() {
   ASSERT(handle_->fd() >= 0);
-  int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
-  if (err != 0) {
-    const int kBufferSize = 1024;
-    char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
-    Log::PrintErr("%s\n", error_message);
+  if (handle_->fd() == STDOUT_FILENO) {
+    // If stdout, redirect fd to /dev/null.
+    intptr_t null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
+    ASSERT(null_fd >= 0);
+    VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
+    VOID_TEMP_FAILURE_RETRY(close(null_fd));
+  } else {
+    intptr_t err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd()));
+    if (err != 0) {
+      const int kBufferSize = 1024;
+      char error_message[kBufferSize];
+      strerror_r(errno, error_message, kBufferSize);
+      Log::PrintErr("%s\n", error_message);
+    }
   }
   handle_->set_fd(kClosedFd);
 }
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 4ded719..30dda6e 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -150,7 +150,8 @@
   }
 
   static Stream _listenOnSocket(int socketId, int id, int pathId) {
-    var socket = new _RawSocket(new _NativeSocket.watch(socketId));
+    var native = new _NativeSocket.watch(socketId);
+    var socket = new _RawSocket(native);
     return socket.expand((event) {
       var stops = [];
       var events = [];
@@ -182,9 +183,12 @@
             add(event[4], new FileSystemDeleteEvent._(getPath(event), isDir));
           }
         }
-        while (socket.available() > 0) {
+        int eventCount;
+        do {
+          eventCount = 0;
           for (var event in _readEvents(id, pathId)) {
             if (event == null) continue;
+            eventCount++;
             int pathId = event[4];
             bool isDir = getIsDir(event);
             var path = getPath(event);
@@ -222,7 +226,10 @@
               stops.add([event[4], null]);
             }
           }
-        }
+        } while (eventCount > 0);
+        // Be sure to clear this manually, as the sockets are not read through
+        // the _NativeSocket interface.
+        native.available = 0;
         for (var map in pair.values) {
           for (var event in map.values) {
             rewriteMove(event, getIsDir(event));
diff --git a/runtime/bin/file_system_watcher_linux.cc b/runtime/bin/file_system_watcher_linux.cc
index 8706702..2a5fee5 100644
--- a/runtime/bin/file_system_watcher_linux.cc
+++ b/runtime/bin/file_system_watcher_linux.cc
@@ -11,6 +11,7 @@
 #include <sys/inotify.h>  // NOLINT
 
 #include "bin/fdutils.h"
+#include "bin/socket.h"
 
 
 namespace dart {
@@ -70,7 +71,7 @@
   const intptr_t kEventSize = sizeof(struct inotify_event);
   const intptr_t kBufferSize = kEventSize + NAME_MAX + 1;
   uint8_t buffer[kBufferSize];
-  intptr_t bytes = TEMP_FAILURE_RETRY(read(id, buffer, kBufferSize));
+  intptr_t bytes = Socket::Read(id, buffer, kBufferSize);
   if (bytes < 0) {
     return DartUtils::NewDartOSError();
   }
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 98d4bf7..f4be349 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -37,19 +37,23 @@
 
 
 File::~File() {
-  // Close the file (unless it's a standard stream).
-  if (handle_->fd() > 2) {
-    Close();
-  }
+  Close();
   delete handle_;
 }
 
 
 void File::Close() {
   ASSERT(handle_->fd() >= 0);
-  int err = close(handle_->fd());
-  if (err != 0) {
-    Log::PrintErr("%s\n", strerror(errno));
+  if (handle_->fd() == _fileno(stdout)) {
+    int fd = _open("NUL", _O_WRONLY);
+    ASSERT(fd >= 0);
+    _dup2(fd, handle_->fd());
+    close(fd);
+  } else {
+    int err = close(handle_->fd());
+    if (err != 0) {
+      Log::PrintErr("%s\n", strerror(errno));
+    }
   }
   handle_->set_fd(kClosedFd);
 }
@@ -131,8 +135,17 @@
 
 
 File* File::OpenStdio(int fd) {
-  UNREACHABLE();
-  return NULL;
+  switch (fd) {
+    case 1:
+      fd = _fileno(stdout);
+      break;
+    case 2:
+      fd = _fileno(stderr);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  return new File(new FileHandle(fd));
 }
 
 
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index a720c7f..390b4ef 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -6,12 +6,6 @@
 # implementation files are in builtin_impl_sources.gypi.
 {
   'sources': [
-    'crypto.cc',
-    'crypto.h',
-    'crypto_android.cc',
-    'crypto_linux.cc',
-    'crypto_macos.cc',
-    'crypto_win.cc',
     'eventhandler.cc',
     'eventhandler.h',
     'eventhandler_android.cc',
@@ -21,6 +15,12 @@
     'eventhandler_macos.h',
     'eventhandler_win.cc',
     'eventhandler_win.h',
+    'file_system_watcher.cc',
+    'file_system_watcher.h',
+    'file_system_watcher_android.cc',
+    'file_system_watcher_linux.cc',
+    'file_system_watcher_macos.cc',
+    'file_system_watcher_win.cc',
     'filter.cc',
     'filter.h',
     'filter_unsupported.cc',
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 6a860b7..69a8123 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -20,8 +20,14 @@
 // Some classes, like File and Directory, list their implementations in
 // builtin_natives.cc instead.
 #define IO_NATIVE_LIST(V)                                                      \
-  V(Crypto_GetRandomBytes, 1)                                                  \
   V(EventHandler_SendData, 3)                                                  \
+  V(FileSystemWatcher_CloseWatcher, 1)                                         \
+  V(FileSystemWatcher_GetSocketId, 2)                                          \
+  V(FileSystemWatcher_InitWatcher, 0)                                          \
+  V(FileSystemWatcher_IsSupported, 0)                                          \
+  V(FileSystemWatcher_ReadEvents, 2)                                           \
+  V(FileSystemWatcher_UnwatchPath, 2)                                          \
+  V(FileSystemWatcher_WatchPath, 4)                                            \
   V(Filter_CreateZLibDeflate, 3)                                               \
   V(Filter_CreateZLibInflate, 1)                                               \
   V(Filter_End, 1)                                                             \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index c506ee4..41d6f13 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1035,8 +1035,6 @@
     free(environment);
   }
 
-  Platform::Cleanup();
-
   exit(Process::GlobalExitCode());
 }
 
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 9579072..ca723ae3 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -62,12 +62,6 @@
     return argv_;
   }
 
-  static void PrintBlocking(FILE* file, const char* format, ...)
-      PRINTF_ATTRIBUTE(2, 3);
-
-  // Perform platform-specific cleanups.
-  static void Cleanup();
-
  private:
   static const char* executable_name_;
   static const char* package_root_;
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index dbf56d2..b30e46d 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -66,24 +66,6 @@
   delete[] env;
 }
 
-
-void Platform::PrintBlocking(FILE* file, const char* format, ...) {
-  int fd = fileno(file);
-  FDUtils::SetBlocking(fd);
-  va_list args;
-  va_start(args, format);
-  vfprintf(file, format, args);
-  fflush(file);
-  va_end(args);
-  FDUtils::SetNonBlocking(fd);
-}
-
-
-void Platform::Cleanup() {
-  FDUtils::SetBlocking(fileno(stdout));
-  FDUtils::SetBlocking(fileno(stderr));
-}
-
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 89031a1..7f37936 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -66,24 +66,6 @@
   delete[] env;
 }
 
-
-void Platform::PrintBlocking(FILE* file, const char* format, ...) {
-  int fd = fileno(file);
-  FDUtils::SetBlocking(fd);
-  va_list args;
-  va_start(args, format);
-  vfprintf(file, format, args);
-  fflush(file);
-  va_end(args);
-  FDUtils::SetNonBlocking(fd);
-}
-
-
-void Platform::Cleanup() {
-  FDUtils::SetBlocking(fileno(stdout));
-  FDUtils::SetBlocking(fileno(stderr));
-}
-
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 0b920b6..365caf1 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -70,24 +70,6 @@
   delete[] env;
 }
 
-
-void Platform::PrintBlocking(FILE* file, const char* format, ...) {
-  int fd = fileno(file);
-  FDUtils::SetBlocking(fd);
-  va_list args;
-  va_start(args, format);
-  vfprintf(file, format, args);
-  fflush(file);
-  va_end(args);
-  FDUtils::SetNonBlocking(fd);
-}
-
-
-void Platform::Cleanup() {
-  FDUtils::SetBlocking(fileno(stdout));
-  FDUtils::SetBlocking(fileno(stderr));
-}
-
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 2d7a5a1..85b6694 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -64,20 +64,6 @@
   delete[] env;
 }
 
-
-void Platform::PrintBlocking(FILE* file, const char* format, ...) {
-  // No need to set blocking, as it's always blocking on Windows.
-  va_list args;
-  va_start(args, format);
-  vfprintf(file, format, args);
-  fflush(file);
-  va_end(args);
-}
-
-
-void Platform::Cleanup() {
-}
-
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index ebafedd..09476b9 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -209,7 +209,6 @@
   DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
   Dart_ExitIsolate();
   Dart_Cleanup();
-  Platform::Cleanup();
   exit(static_cast<int>(status));
 }
 
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index c2d8b20..185ca0b 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -744,7 +744,7 @@
     for (int i = 0; i < kSignalsCount; i++) {
       sigaddset(&act.sa_mask, kSignals[i]);
     }
-    int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
+    intptr_t status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
         sigaction(signal, &act, NULL));
     if (status < 0) {
       VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
diff --git a/runtime/bin/signal_blocker.h b/runtime/bin/signal_blocker.h
index 1ab816c..2b5fe1e 100644
--- a/runtime/bin/signal_blocker.h
+++ b/runtime/bin/signal_blocker.h
@@ -56,10 +56,10 @@
 
 #define TEMP_FAILURE_RETRY_BLOCK_SIGNALS(expression)                           \
     ({ ThreadSignalBlocker tsb(SIGPROF);                                       \
-       int64_t __result;                                                       \
+       intptr_t __result;                                                      \
        do {                                                                    \
-         __result = static_cast<int64_t>(expression);                          \
-       } while (__result == -1L && errno == EINTR);                            \
+         __result = (expression);                                              \
+       } while ((__result == -1L) && (errno == EINTR));                        \
        __result; })
 
 #define VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(expression)                      \
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 351bfc6..fc52839 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -99,50 +99,38 @@
   static bool short_socket_reads = Dart_IsVMFlagSet("short_socket_read");
   intptr_t socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
-  intptr_t available = Socket::Available(socket);
-  if (available > 0) {
-    int64_t length = 0;
-    if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
-      if (length == -1 || available < length) {
-        length = available;
-      }
-      if (short_socket_reads) {
-        length = (length + 1) / 2;
-      }
-      uint8_t* buffer = NULL;
-      Dart_Handle result = IOBuffer::Allocate(length, &buffer);
-      if (Dart_IsError(result)) Dart_PropagateError(result);
-      ASSERT(buffer != NULL);
-      intptr_t bytes_read = Socket::Read(socket, buffer, length);
-      if (bytes_read == length) {
-        Dart_SetReturnValue(args, result);
-      } else if (bytes_read < length) {
-        // On MacOS when reading from a tty Ctrl-D will result in reading one
-        // less byte then reported as available.
-        if (bytes_read == 0) {
-          Dart_SetReturnValue(args, Dart_Null());
-        } else {
-          uint8_t* new_buffer = NULL;
-          Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
-          if (Dart_IsError(new_result)) Dart_PropagateError(new_result);
-          ASSERT(new_buffer != NULL);
-          memmove(new_buffer, buffer, bytes_read);
-          Dart_SetReturnValue(args, new_result);
-        }
-      } else {
-        ASSERT(bytes_read == -1);
-        Dart_SetReturnValue(args, DartUtils::NewDartOSError());
-      }
-    } else {
-      OSError os_error(-1, "Invalid argument", OSError::kUnknown);
-      Dart_Handle err = DartUtils::NewDartOSError(&os_error);
-      if (Dart_IsError(err)) Dart_PropagateError(err);
-      Dart_SetReturnValue(args, err);
+  int64_t length = 0;
+  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
+    if (short_socket_reads) {
+      length = (length + 1) / 2;
     }
-  } else if (available == 0) {
-    Dart_SetReturnValue(args, Dart_Null());
+    uint8_t* buffer = NULL;
+    Dart_Handle result = IOBuffer::Allocate(length, &buffer);
+    if (Dart_IsError(result)) Dart_PropagateError(result);
+    ASSERT(buffer != NULL);
+    intptr_t bytes_read = Socket::Read(socket, buffer, length);
+    if (bytes_read == length) {
+      Dart_SetReturnValue(args, result);
+    } else if (bytes_read > 0) {
+      uint8_t* new_buffer = NULL;
+      Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
+      if (Dart_IsError(new_result)) Dart_PropagateError(new_result);
+      ASSERT(new_buffer != NULL);
+      memmove(new_buffer, buffer, bytes_read);
+      Dart_SetReturnValue(args, new_result);
+    } else if (bytes_read == 0) {
+      // On MacOS when reading from a tty Ctrl-D will result in reading one
+      // less byte then reported as available.
+      Dart_SetReturnValue(args, Dart_Null());
+    } else {
+      ASSERT(bytes_read == -1);
+      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    }
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
+    Dart_Handle err = DartUtils::NewDartOSError(&os_error);
+    if (Dart_IsError(err)) Dart_PropagateError(err);
+    Dart_SetReturnValue(args, err);
   }
 }
 
@@ -224,7 +212,9 @@
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
   intptr_t length =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+  bool short_write = false;
   if (short_socket_writes) {
+    if (length > 1) short_write = true;
     length = (length + 1) / 2;
   }
   Dart_TypedData_Type type;
@@ -238,7 +228,13 @@
   intptr_t bytes_written = Socket::Write(socket, buffer, length);
   if (bytes_written >= 0) {
     Dart_TypedDataReleaseData(buffer_obj);
-    Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
+    if (short_write) {
+      // If the write was forced 'short', indicate by returning the negative
+      // number of bytes. A forced short write may not trigger a write event.
+      Dart_SetReturnValue(args, Dart_NewInteger(-bytes_written));
+    } else {
+      Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
+    }
   } else {
     // Extract OSError before we release data, as it may override the error.
     OSError os_error;
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 0ab6af4..42937a4 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -225,7 +225,6 @@
 
 
 intptr_t Socket::GetStdioHandle(intptr_t num) {
-  Socket::SetNonBlocking(num);
   return num;
 }
 
@@ -238,16 +237,22 @@
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
-  hints.ai_flags = 0;
+  hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
   if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error = new OSError(status,
-                            gai_strerror(status),
-                            OSError::kGetAddressInfo);
-    return NULL;
+    // We failed, try without AI_ADDRCONFIG. This can happen when looking up
+    // e.g. '::1', when there are no IPv6 addresses.
+    hints.ai_flags = AI_V4MAPPED;
+    status = getaddrinfo(host, 0, &hints, &info);
+    if (status != 0) {
+      ASSERT(*os_error == NULL);
+      *os_error = new OSError(status,
+                              gai_strerror(status),
+                              OSError::kGetAddressInfo);
+      return NULL;
+    }
   }
   intptr_t count = 0;
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 08d8fe1..133e333 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -20,6 +20,7 @@
 #include "bin/log.h"
 #include "bin/signal_blocker.h"
 #include "bin/socket.h"
+#include "vm/thread.h"
 
 
 namespace dart {
@@ -59,8 +60,8 @@
 
 intptr_t Socket::Create(RawAddr addr) {
   intptr_t fd;
-  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(addr.ss.ss_family, SOCK_STREAM,
-                                               0));
+  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
+      addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
   if (fd < 0) {
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
@@ -68,8 +69,6 @@
                   strerror_r(errno, error_buf, kBufferSize));
     return -1;
   }
-
-  FDUtils::SetCloseOnExec(fd);
   return fd;
 }
 
@@ -93,9 +92,6 @@
   if (fd < 0) {
     return fd;
   }
-
-  Socket::SetNonBlocking(fd);
-
   return Socket::Connect(fd, addr, port);
 }
 
@@ -205,11 +201,13 @@
 
 void Socket::GetError(intptr_t fd, OSError* os_error) {
   int len = sizeof(errno);
+  int err = 0;
   getsockopt(fd,
              SOL_SOCKET,
              SO_ERROR,
-             &errno,
+             &err,
              reinterpret_cast<socklen_t*>(&len));
+  errno = err;
   os_error->SetCodeAndMessage(OSError::kSystem, errno);
 }
 
@@ -226,7 +224,6 @@
 
 
 intptr_t Socket::GetStdioHandle(intptr_t num) {
-  Socket::SetNonBlocking(num);
   return num;
 }
 
@@ -239,16 +236,22 @@
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
-  hints.ai_flags = 0;
+  hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
   if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error = new OSError(status,
-                            gai_strerror(status),
-                            OSError::kGetAddressInfo);
-    return NULL;
+    // We failed, try without AI_ADDRCONFIG. This can happen when looking up
+    // e.g. '::1', when there are no global IPv6 addresses.
+    hints.ai_flags = AI_V4MAPPED;
+    status = getaddrinfo(host, 0, &hints, &info);
+    if (status != 0) {
+      ASSERT(*os_error == NULL);
+      *os_error = new OSError(status,
+                              gai_strerror(status),
+                              OSError::kGetAddressInfo);
+      return NULL;
+    }
   }
   intptr_t count = 0;
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
@@ -307,12 +310,12 @@
     RawAddr* addr, intptr_t port, bool reuseAddress) {
   intptr_t fd;
 
-  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
-      socket(addr->addr.sa_family, SOCK_DGRAM, IPPROTO_UDP));
+  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
+      addr->addr.sa_family,
+      SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+      IPPROTO_UDP));
   if (fd < 0) return -1;
 
-  FDUtils::SetCloseOnExec(fd);
-
   if (reuseAddress) {
     int optval = 1;
     VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
@@ -327,8 +330,6 @@
     TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
     return -1;
   }
-
-  Socket::SetNonBlocking(fd);
   return fd;
 }
 
@@ -390,12 +391,10 @@
                                         bool v6_only) {
   intptr_t fd;
 
-  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(addr.ss.ss_family, SOCK_STREAM,
-                                               0));
+  fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
+      addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
   if (fd < 0) return -1;
 
-  FDUtils::SetCloseOnExec(fd);
-
   int optval = 1;
   TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
@@ -432,7 +431,6 @@
     return -1;
   }
 
-  Socket::SetNonBlocking(fd);
   return fd;
 }
 
@@ -451,7 +449,8 @@
   intptr_t socket;
   struct sockaddr clientaddr;
   socklen_t addrlen = sizeof(clientaddr);
-  socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept(fd, &clientaddr, &addrlen));
+  socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept4(
+        fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC));
   if (socket == -1) {
     if (IsTemporaryAcceptError(errno)) {
       // We need to signal to the caller that this is actually not an
@@ -460,8 +459,6 @@
       ASSERT(kTemporaryFailure != -1);
       socket = kTemporaryFailure;
     }
-  } else {
-    Socket::SetNonBlocking(socket);
   }
   return socket;
 }
@@ -478,16 +475,6 @@
 }
 
 
-bool Socket::SetNonBlocking(intptr_t fd) {
-  return FDUtils::SetNonBlocking(fd);
-}
-
-
-bool Socket::SetBlocking(intptr_t fd) {
-  return FDUtils::SetBlocking(fd);
-}
-
-
 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
   int on;
   socklen_t len = sizeof(on);
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 815b0f7..6194289 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -226,7 +226,6 @@
 
 
 intptr_t Socket::GetStdioHandle(intptr_t num) {
-  Socket::SetNonBlocking(num);
   return num;
 }
 
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 56f04d1..27329f1 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -256,13 +256,9 @@
   Completer closeCompleter = new Completer.sync();
 
   // Handlers and receive port for socket events from the event handler.
-  int eventMask = 0;
-  List eventHandlers;
+  final List eventHandlers = new List(EVENT_COUNT + 1);
   RawReceivePort eventPort;
 
-  // Indicates if native interrupts can be activated.
-  bool canActivateEvents = true;
-
   // The type flags for this socket.
   final int typeFlags;
 
@@ -272,6 +268,15 @@
   // Holds the address used to connect or bind the socket.
   InternetAddress address;
 
+  int available = 0;
+
+  bool sendReadEvents = false;
+  bool readEventIssued = false;
+
+  bool sendWriteEvents = false;
+  bool writeEventIssued = false;
+  bool writeAvailable = false;
+
   static Future<List<InternetAddress>> lookup(
       String host, {InternetAddressType type: InternetAddressType.ANY}) {
     return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value])
@@ -426,50 +431,32 @@
         });
   }
 
-  _NativeSocket.datagram(this.address)
-      : typeFlags = TYPE_NORMAL_SOCKET {
-    eventHandlers = new List(EVENT_COUNT + 1);
-  }
+  _NativeSocket.datagram(this.address) : typeFlags = TYPE_NORMAL_SOCKET;
 
-  _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET {
-    eventHandlers = new List(EVENT_COUNT + 1);
-  }
+  _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET;
 
-  _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET {
-    eventHandlers = new List(EVENT_COUNT + 1);
-  }
+  _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET;
 
-  _NativeSocket.pipe() : typeFlags = TYPE_PIPE {
-    eventHandlers = new List(EVENT_COUNT + 1);
-  }
+  _NativeSocket.pipe() : typeFlags = TYPE_PIPE;
 
   _NativeSocket.watch(int id) : typeFlags = TYPE_NORMAL_SOCKET {
-    eventHandlers = new List(EVENT_COUNT + 1);
     isClosedWrite = true;
     nativeSetSocketId(id);
   }
 
-  int available() {
-    if (isClosing || isClosed) return 0;
-    var result = nativeAvailable();
-    if (result is OSError) {
-      reportError(result, "Available failed");
-      return 0;
-    } else {
-      return result;
-    }
-  }
-
   List<int> read(int len) {
     if (len != null && len <= 0) {
       throw new ArgumentError("Illegal length $len");
     }
     if (isClosing || isClosed) return null;
-    var result = nativeRead(len == null ? -1 : len);
+    len = min(available, len == null ? available : len);
+    if (len == 0) return null;
+    var result = nativeRead(len);
     if (result is OSError) {
       reportError(result, "Read failed");
       return null;
     }
+    if (result != null) available -= result.length;
     return result;
   }
 
@@ -480,6 +467,15 @@
       reportError(result, "Receive failed");
       return null;
     }
+    if (result != null) {
+      if (Platform.isMacOS) {
+        // Mac includes the header size, so we need to query the actual
+        // available.
+        available = nativeAvailable();
+      } else {
+        available -= result.data.length;
+      }
+    }
     return result;
   }
 
@@ -510,6 +506,14 @@
       scheduleMicrotask(() => reportError(result, "Write failed"));
       result = 0;
     }
+    // The result may be negative, if we forced a short write for testing
+    // purpose. In such case, don't mark writeAvailable as false, as we don't
+    // know if we'll receive an event. It's better to just retry.
+    if (result >= 0 && result < bytes) {
+      writeAvailable = false;
+    }
+    // Negate the result, as stated above.
+    if (result < 0) result = -result;
     return result;
   }
 
@@ -554,17 +558,85 @@
     return new _InternetAddress(result[1], null, result[2]);
   }
 
+  void issueReadEvent() {
+    if (readEventIssued) return;
+    readEventIssued = true;
+    void issue() {
+      readEventIssued = false;
+      if (isClosing) return;
+      if (!sendReadEvents) return;
+      if (available == 0) {
+        if (isClosedRead) {
+          if (isClosedWrite) close();
+          var handler = eventHandlers[CLOSED_EVENT];
+          if (handler == null) return;
+          handler();
+        }
+        return;
+      }
+      var handler = eventHandlers[READ_EVENT];
+      if (handler == null) return;
+      readEventIssued = true;
+      handler();
+      scheduleMicrotask(issue);
+    }
+    scheduleMicrotask(issue);
+  }
+
+  void issueWriteEvent({bool delayed: true}) {
+    if (writeEventIssued) return;
+    if (!writeAvailable) return;
+    void issue() {
+      writeEventIssued = false;
+      if (!writeAvailable) return;
+      if (isClosing) return;
+      if (!sendWriteEvents) return;
+      sendWriteEvents = false;
+      var handler = eventHandlers[WRITE_EVENT];
+      if (handler == null) return;
+      handler();
+    }
+    if (delayed) {
+      writeEventIssued = true;
+      scheduleMicrotask(issue);
+    } else {
+      issue();
+    }
+  }
+
   // Multiplexes socket events to the socket handlers.
   void multiplex(int events) {
-    canActivateEvents = false;
     for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) {
       if (((events & (1 << i)) != 0)) {
         if ((i == CLOSED_EVENT || i == READ_EVENT) && isClosedRead) continue;
+        if (isClosing && i != DESTROYED_EVENT) continue;
         if (i == CLOSED_EVENT &&
             typeFlags != TYPE_LISTENING_SOCKET &&
             !isClosing &&
             !isClosed) {
           isClosedRead = true;
+          issueReadEvent();
+          continue;
+        }
+
+        if (i == WRITE_EVENT) {
+          writeAvailable = true;
+          issueWriteEvent(delayed: false);
+          continue;
+        }
+
+        if (i == READ_EVENT &&
+            typeFlags != TYPE_LISTENING_SOCKET) {
+          var avail = nativeAvailable();
+          if (avail is int) {
+            available = avail;
+          } else {
+            // Available failed. Mark socket as having data, to ensure read
+            // events, and thus reporting of this error.
+            available = 1;
+          }
+          issueReadEvent();
+          continue;
         }
 
         var handler = eventHandlers[i];
@@ -576,24 +648,7 @@
           if (handler != null) handler();
           continue;
         }
-        assert(handler != null);
-        if (i == WRITE_EVENT) {
-          // If the event was disabled before we had a chance to fire the event,
-          // discard it. If we register again, we'll get a new one.
-          if ((eventMask & (1 << i)) == 0) continue;
-          // Unregister the out handler before executing it. There is
-          // no need to notify the eventhandler as handlers are
-          // disabled while the event is handled.
-          eventMask &= ~(1 << i);
-        }
 
-        // Don't call the in handler if there is no data available
-        // after all.
-        if (i == READ_EVENT &&
-            typeFlags != TYPE_LISTENING_SOCKET &&
-            available() == 0) {
-          continue;
-        }
         if (i == ERROR_EVENT) {
           if (!isClosing) {
             reportError(nativeGetError(), "");
@@ -605,9 +660,6 @@
         }
       }
     }
-    if (isClosedRead && isClosedWrite) close();
-    canActivateEvents = true;
-    activateHandlers();
   }
 
   void setHandlers({read, write, error, closed, destroyed}) {
@@ -619,26 +671,15 @@
   }
 
   void setListening({read: true, write: true}) {
-    eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT);
-    if (read) eventMask |= (1 << READ_EVENT);
-    if (write) eventMask |= (1 << WRITE_EVENT);
-    activateHandlers();
-  }
-
-
-  void activateHandlers() {
-    if (canActivateEvents && !isClosing && !isClosed) {
-      if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) {
-        // If we don't listen for either read or write, disconnect as we won't
-        // get close and error events anyway.
-        if (eventPort != null) disconnectFromEventHandler();
-      } else {
-        int data = eventMask;
-        if (isClosedRead) data &= ~(1 << READ_EVENT);
-        if (isClosedWrite) data &= ~(1 << WRITE_EVENT);
-        data |= typeFlags;
-        sendToEventHandler(data);
-      }
+    sendReadEvents = read;
+    sendWriteEvents = write;
+    if (read) issueReadEvent();
+    if (write) issueWriteEvent();
+    if (eventPort == null) {
+      int flags = typeFlags;
+      if (!isClosedRead) flags |= 1 << READ_EVENT;
+      if (!isClosedWrite) flags |= 1 << WRITE_EVENT;
+      sendToEventHandler(flags);
     }
   }
 
@@ -673,9 +714,7 @@
       if (isClosedRead) {
         close();
       } else {
-        bool connected = eventPort != null;
         sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND);
-        if (!connected) disconnectFromEventHandler();
       }
       isClosedWrite = true;
     }
@@ -686,17 +725,15 @@
       if (isClosedWrite) {
         close();
       } else {
-        bool connected = eventPort != null;
         sendToEventHandler(1 << SHUTDOWN_READ_COMMAND);
-        if (!connected) disconnectFromEventHandler();
       }
       isClosedRead = true;
     }
   }
 
   void sendToEventHandler(int data) {
-    connectToEventHandler();
     assert(!isClosed);
+    connectToEventHandler();
     _EventHandler._sendData(this, eventPort, data);
   }
 
@@ -707,10 +744,9 @@
   }
 
   void disconnectFromEventHandler() {
-    if (eventPort != null) {
-      eventPort.close();
-      eventPort = null;
-    }
+    assert(eventPort != null);
+    eventPort.close();
+    eventPort = null;
   }
 
   // Check whether this is an error response from a native port call.
@@ -868,8 +904,11 @@
         onResume: _onPauseStateChange);
     _socket.setHandlers(
       read: zone.bindCallback(() {
-        var socket = _socket.accept();
-        if (socket != null) _controller.add(new _RawSocket(socket));
+        do {
+          var socket = _socket.accept();
+          if (socket == null) return;
+          _controller.add(new _RawSocket(socket));
+        } while (!_controller.isPaused);
       }),
       error: zone.bindUnaryCallback((e) {
         _controller.addError(e);
@@ -964,10 +1003,9 @@
     );
   }
 
-  factory _RawSocket._writePipe(int fd) {
+  factory _RawSocket._writePipe() {
     var native = new _NativeSocket.pipe();
     native.isClosedRead = true;
-    if (fd != null) _getStdioHandle(native, fd);
     return new _RawSocket(native);
   }
 
@@ -993,7 +1031,7 @@
         cancelOnError: cancelOnError);
   }
 
-  int available() => _socket.available();
+  int available() => _socket.available;
 
   List<int> read([int len]) {
     if (_isMacOSTerminalInput) {
@@ -1233,8 +1271,8 @@
     _raw.writeEventsEnabled = false;
   }
 
-  factory _Socket._writePipe([int fd]) {
-    return new _Socket(new _RawSocket._writePipe(fd));
+  factory _Socket._writePipe() {
+    return new _Socket(new _RawSocket._writePipe());
   }
 
   factory _Socket._readPipe([int fd]) {
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 3664830..2675dce 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -195,24 +195,12 @@
 
 
 intptr_t Socket::GetStdioHandle(intptr_t num) {
-  HANDLE handle;
-  switch (num) {
-    case 0:
-      handle = GetStdHandle(STD_INPUT_HANDLE);
-      break;
-    case 1:
-      handle = GetStdHandle(STD_OUTPUT_HANDLE);
-      break;
-    case 2:
-      handle = GetStdHandle(STD_ERROR_HANDLE);
-      break;
-    default: UNREACHABLE();
-  }
+  if (num != 0) return -1;
+  HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
   if (handle == INVALID_HANDLE_VALUE) {
     return -1;
   }
   StdHandle* std_handle = new StdHandle(handle);
-  if (std_handle == NULL) return -1;
   std_handle->MarkDoesNotSupportOverlappedIO();
   std_handle->EnsureInitialized(EventHandler::delegate());
   return reinterpret_cast<intptr_t>(std_handle);
diff --git a/runtime/bin/stdio_android.cc b/runtime/bin/stdio_android.cc
index b14dad8..12c87c9 100644
--- a/runtime/bin/stdio_android.cc
+++ b/runtime/bin/stdio_android.cc
@@ -18,12 +18,10 @@
 namespace bin {
 
 int Stdin::ReadByte() {
-  FDUtils::SetBlocking(STDIN_FILENO);
   int c = getchar();
   if (c == EOF) {
     c = -1;
   }
-  FDUtils::SetNonBlocking(STDIN_FILENO);
   return c;
 }
 
diff --git a/runtime/bin/stdio_linux.cc b/runtime/bin/stdio_linux.cc
index 5d1739a..f61cc30 100644
--- a/runtime/bin/stdio_linux.cc
+++ b/runtime/bin/stdio_linux.cc
@@ -18,12 +18,10 @@
 namespace bin {
 
 int Stdin::ReadByte() {
-  FDUtils::SetBlocking(STDIN_FILENO);
   int c = getchar();
   if (c == EOF) {
     c = -1;
   }
-  FDUtils::SetNonBlocking(STDIN_FILENO);
   return c;
 }
 
diff --git a/runtime/bin/stdio_macos.cc b/runtime/bin/stdio_macos.cc
index 623463a..4b27a1b 100644
--- a/runtime/bin/stdio_macos.cc
+++ b/runtime/bin/stdio_macos.cc
@@ -18,12 +18,10 @@
 namespace bin {
 
 int Stdin::ReadByte() {
-  FDUtils::SetBlocking(STDIN_FILENO);
   int c = getchar();
   if (c == EOF) {
     c = -1;
   }
-  FDUtils::SetNonBlocking(STDIN_FILENO);
   return c;
 }
 
diff --git a/runtime/bin/stdio_patch.dart b/runtime/bin/stdio_patch.dart
index 2364281..d400306 100644
--- a/runtime/bin/stdio_patch.dart
+++ b/runtime/bin/stdio_patch.dart
@@ -29,7 +29,6 @@
       case _STDIO_HANDLE_TYPE_TERMINAL:
       case _STDIO_HANDLE_TYPE_PIPE:
       case _STDIO_HANDLE_TYPE_SOCKET:
-        return wrap(new _Socket._writePipe(fd));
       case _STDIO_HANDLE_TYPE_FILE:
         return wrap(new IOSink(new _FileStreamConsumer.fromStdio(fd)));
       default:
@@ -44,6 +43,8 @@
     }
     return result;
   }
+
+  static _getStdioHandleType(int fd) native "File_GetStdioHandleType";
 }
 
 patch class Stdin {
@@ -87,5 +88,4 @@
 
 
 _getStdioHandle(_NativeSocket socket, int num) native "Socket_GetStdioHandle";
-_getStdioHandleType(int num) native "File_GetStdioHandleType";
 _getSocketType(_NativeSocket nativeSocket) native "Socket_GetType";
diff --git a/runtime/bin/vmservice/client/HACKING.txt b/runtime/bin/vmservice/client/HACKING.txt
new file mode 100644
index 0000000..0edca79
--- /dev/null
+++ b/runtime/bin/vmservice/client/HACKING.txt
@@ -0,0 +1,29 @@
+Dart Observatory Developer Guide
+---
+
+During development you do not need to run dart2js or rebuild the VM (unless
+you are also making changes to the backend). While you're working on your
+feature follow the steps:
+
+1. Open runtime/bin/vmservice/client in the Dart Editor
+2. Launch dart --enable-vm-service with a long running script in a terminal
+3. Launch web/index.html in Dartium
+
+At this point you should see the initial Observatory UI and that
+it is communicating with the VM you launched in step 2.
+
+Continue to develop and iterate until you're ready to upload your change
+for review. Upload your change and get an LGTM.
+
+4. Run dart build_.dart
+5. Run ./precommit.sh
+
+At this point you should rebuild your VM and using the build:
+
+6. Launch dart --enable-vm-service with a long running script.
+
+In a non-Dart enabled browser navigate to localhost:8181 and ensure
+that your feature works after being compiled to JavaScript.
+
+7. Commit your change
+
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html b/runtime/bin/vmservice/client/deployed/web/index.html
index 58ade8b..f0f8325 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html
+++ b/runtime/bin/vmservice/client/deployed/web/index.html
@@ -72,20 +72,75 @@
 </template>
 
 </polymer-element><polymer-element name="instance-ref" extends="service-ref">
-<template>
-<div>
-  <template if="{{ (ref['type'] == 'null') }}">
-    unexpected null
-  </template>
-  <template if="{{ (ref['type'] == '@Null') }}">
-    {{ name }}
-  </template>
-  <template if="{{ (ref['type'] != 'null') &amp;&amp; ref['type'] != '@Null' }}">
-    <a href="{{ url }}">{{ name }} </a>
-  </template>
- </div>
-</template>
+  <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
+    <div>
+      <template if="{{ isUnexpectedRef(ref['type']) }}">
+        unexpected reference type &lt;{{ ref['type'] }}&gt;
+      </template>
 
+      <template if="{{ isNullRef(ref['type']) }}">
+        {{ name }}
+      </template>
+
+      <template if="{{ (isStringRef(ref['type']) ||
+                        isBoolRef(ref['type']) ||
+                        isIntRef(ref['type'])) }}">
+        <a href="{{ url }}">{{ name }}</a>
+      </template>
+
+      <template if="{{ isClosureRef(ref['type']) }}">
+        <a href="{{ url }}">
+          {{ ref['closureFunc']['user_name'] }}
+        </a>
+      </template>
+
+      <template if="{{ isInstanceRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em></a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ field in ref['fields'] }}">
+
+              <td class="member">{{ field['decl']['user_name'] }}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+      </template>
+
+      <template if="{{ isListRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em> ({{ ref['length']}})</a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ element in ref['elements'] }}">
+              <td class="member">[{{ element['index']}}]</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ element['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+      </template>
+
+    </div>
+  </template>
+  
 </polymer-element>
 <polymer-element name="library-ref" extends="service-ref">
 <template>
@@ -302,7 +357,13 @@
   </div>
   </template>
   
-</polymer-element><polymer-element name="isolate-summary" extends="observatory-element">
+</polymer-element><polymer-element name="script-ref" extends="service-ref">
+<template>
+  <a title="{{ hoverText }}" href="{{ url }}">{{ name }}</a>
+</template>
+
+</polymer-element>
+<polymer-element name="isolate-summary" extends="observatory-element">
   <template>
     <div class="row">
       <div class="col-md-1">
@@ -382,12 +443,8 @@
       </div>
       <div class="col-md-6">
         <template if="{{ isolate.topFrame != null }}">
-          <a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['function']['id']) }}">
-            {{ isolate.topFrame['function']['user_name'] }}
-          </a>
-          (<a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['script']['id']) }}">
-            {{ isolate.topFrame | fileAndLine }}
-          </a>)
+          <function-ref app="{{ app }}" isolate="{{ isolate }}" ref="{{ isolate.topFrame['function'] }}"></function-ref>
+          (<script-ref app="{{ app }}" isolate="{{ isolate }}" ref="{{ isolate.topFrame['script'] }}" line="{{ isolate.topFrame['line'] }}"></script-ref>)
           <br>
           <pre>{{ isolate.topFrame['line'] }} &nbsp; {{ isolate.topFrame['lineString'] }}</pre>
         </template>
@@ -434,7 +491,7 @@
             <table class="table table-hover">
              <tbody>
                 <tr template="" repeat="{{ field in instance['fields'] }}">
-                  <td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
+                  <td><field-ref app="{{ app }}" ref="{{ field['decl'] }}"></field-ref></td>
                   <td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
                 </tr>
               </tbody>
@@ -480,12 +537,7 @@
   </template>
   
 </polymer-element>
-<polymer-element name="script-ref" extends="service-ref">
-<template>
-  <a href="{{ url }}">{{ name }}</a>
-</template>
-
-</polymer-element><polymer-element name="library-view" extends="observatory-element">
+<polymer-element name="library-view" extends="observatory-element">
   <template>
   <div class="alert alert-success">Library {{ library['name'] }}</div>
   <div class="alert alert-info">Scripts</div>
@@ -621,7 +673,7 @@
           <tr template="" repeat="{{ line in script.linesForDisplay }}">
             <td style="{{ hitsStyle(line) }}">  </td>
             <td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{line.line}}</td>
-            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;">{{line.text}}</td>
+            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{line.text}}</td>
           </tr>
           </tbody>
         </table>
@@ -632,6 +684,17 @@
 
 </polymer-element><polymer-element name="stack-frame" extends="observatory-element">
   <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
     <div class="row">
       <div class="col-md-1"></div>
       <div class="col-md-1">
@@ -639,29 +702,33 @@
       </div>
       <div class="col-md-9">
         <function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref>
-        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref>:{{ frame['line'] }} )
+        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}" line="{{ frame['line'] }}">
+        </script-ref> ) {
+        <a on-click="{{ toggleExpand }}">...</a>
+
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ v in frame['vars'] }}">
+              <td class="member">{{ v['name']}}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+
       </div>
       <div class="col-md-1"></div>
     </div>
 
-    <template repeat="{{ v in frame['vars'] }}">
-      <div class="row">
-        <div class="col-md-3"></div>
-        <div class="col-md-1">
-          {{ v['name'] }}
-        </div>
-        <div class="col-md-6">
-          <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
-        </div>
-        <div class="col-md-2"></div>
-      </div>
-    </template>
 
   </template>
   
 </polymer-element>
 <polymer-element name="stack-trace" extends="observatory-element">
   <template>
+    <button type="button" on-click="{{refresh}}">Refresh</button>
     <template if="{{ trace['members'].isEmpty }}">
       <div class="col-md-1"></div>
       <div class="col-md-11">
@@ -709,6 +776,9 @@
     <template if="{{ messageType == 'Field' }}">
       <field-view app="{{ app }}" field="{{ message }}"></field-view>
     </template>
+    <template if="{{ messageType == 'Closure' }}">
+      <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
+    </template>
     <template if="{{ messageType == 'Instance' }}">
       <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
     </template>
@@ -745,7 +815,8 @@
     <!-- Add new views and message types in the future here. -->
   </template>
   
-</polymer-element><polymer-element name="navigation-bar-isolate" extends="observatory-element">
+</polymer-element>
+<polymer-element name="navigation-bar-isolate" extends="observatory-element">
     <template>
       <ul class="nav navbar-nav">
         <li><a href="{{ currentIsolateLink('') }}"> {{currentIsolateName()}}</a></li>
@@ -771,34 +842,34 @@
   
 </polymer-element><polymer-element name="isolate-profile" extends="observatory-element">
   <template>
-    <p> P R O F I L E </p>
     <div>
       <button type="button" on-click="{{refreshData}}">Refresh profile data</button>
       <span>Top</span>
       <select selectedindex="{{methodCountSelected}}" value="{{methodCounts[methodCountSelected]}}">
         <option template="" repeat="{{count in methodCounts}}">{{count}}</option>
       </select>
-      <span>methods</span>
+      <span>exclusive methods</span>
     </div>
-    <blockquote><strong>Top Exclusive</strong></blockquote>
-    <table class="table table-hover">
+    <table id="tableTree" class="table table-hover">
       <thead>
         <tr>
-          <th>Ticks</th>
-          <th>Percent</th>
           <th>Method</th>
+          <th>Exclusive</th>
+          <th>Caller</th>
+          <th>Inclusive</th>
         </tr>
       </thead>
       <tbody>
-        <tr template="" repeat="{{ code in topExclusiveCodes }}">
-            <td>{{ codeTicks(code, false) }}</td>
-            <td>{{ codePercent(code, false) }}</td>
-            <td>
-            <span>{{ codeName(code) }}</span>
-            <code-ref app="{{ app }}" ref="{{ code.codeRef }}"></code-ref>
-            </td>
+        <tr template="" repeat="{{row in tree.rows }}" style="{{}}">
+          <td on-click="{{toggleExpanded}}" class="{{ coloring(row) }}" style="{{ padding(row) }}">
+            <code-ref app="{{ app }}" ref="{{ row.code.codeRef }}"></code-ref>
+          </td>
+          <td class="{{ coloring(row) }}">{{row.columns[0]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[1]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[2]}}</td>
         </tr>
-    </tbody></table>
+      </tbody>
+    </table>
   </template>
   
 </polymer-element>
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
index 54dc538..37570e3 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
@@ -197,7 +197,7 @@
       this.push(part);
     }, this);
 
-    if (hasEval && !hasObserve && this.length) {
+    if (hasEval && this.length) {
       this.getValueFrom = this.compiledGetValueFromFn();
     }
   }
@@ -235,17 +235,25 @@
       return this.join('.');
     },
 
-    getValueFrom: function(obj, observedSet) {
+    getValueFrom: function(obj, directObserver) {
       for (var i = 0; i < this.length; i++) {
         if (obj == null)
           return;
-        if (observedSet)
-          observedSet.observe(obj);
         obj = obj[this[i]];
       }
       return obj;
     },
 
+    iterateObjects: function(obj, observe) {
+      for (var i = 0; i < this.length; i++) {
+        if (i)
+          obj = obj[this[i - 1]];
+        if (!obj)
+          return;
+        observe(obj);
+      }
+    },
+
     compiledGetValueFromFn: function() {
       var accessors = this.map(function(ident) {
         return isIndex(ident) ? '["' + ident + '"]' : '.' + ident;
@@ -294,12 +302,13 @@
 
   function dirtyCheck(observer) {
     var cycles = 0;
-    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check()) {
-      observer.report();
+    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {
       cycles++;
     }
     if (global.testingExposeCycleCount)
       global.dirtyCheckCycleCount = cycles;
+
+    return cycles > 0;
   }
 
   function objectIsEmpty(object) {
@@ -352,104 +361,280 @@
     };
   }
 
-  function copyObject(object, opt_copy) {
-    var copy = opt_copy || (Array.isArray(object) ? [] : {});
-    for (var prop in object) {
-      copy[prop] = object[prop];
-    };
-    if (Array.isArray(object))
-      copy.length = object.length;
-    return copy;
+  var eomTasks = [];
+  function runEOMTasks() {
+    if (!eomTasks.length)
+      return false;
+
+    for (var i = 0; i < eomTasks.length; i++) {
+      eomTasks[i]();
+    }
+    eomTasks.length = 0;
+    return true;
   }
 
-  function Observer(object, callback, target, token) {
-    this.closed = false;
-    this.object = object;
-    this.callback = callback;
-    // TODO(rafaelw): Hold this.target weakly when WeakRef is available.
-    this.target = target;
-    this.token = token;
-    this.reporting = true;
-    if (hasObserve) {
-      var self = this;
-      this.boundInternalCallback = function(records) {
-        self.internalCallback(records);
-      };
+  var runEOM = hasObserve ? (function(){
+    var eomObj = { pingPong: true };
+    var eomRunScheduled = false;
+
+    Object.observe(eomObj, function() {
+      runEOMTasks();
+      eomRunScheduled = false;
+    });
+
+    return function(fn) {
+      eomTasks.push(fn);
+      if (!eomRunScheduled) {
+        eomRunScheduled = true;
+        eomObj.pingPong = !eomObj.pingPong;
+      }
+    };
+  })() :
+  (function() {
+    return function(fn) {
+      eomTasks.push(fn);
+    };
+  })();
+
+  var observedObjectCache = [];
+
+  function newObservedObject() {
+    var observer;
+    var object;
+    var discardRecords = false;
+    var first = true;
+
+    function callback(records) {
+      if (observer && observer.state_ === OPENED && !discardRecords)
+        observer.check_(records);
     }
 
-    addToAll(this);
+    return {
+      open: function(obs) {
+        if (observer)
+          throw Error('ObservedObject in use');
+
+        if (!first)
+          Object.deliverChangeRecords(callback);
+
+        observer = obs;
+        first = false;
+      },
+      observe: function(obj, arrayObserve) {
+        object = obj;
+        if (arrayObserve)
+          Array.observe(object, callback);
+        else
+          Object.observe(object, callback);
+      },
+      deliver: function(discard) {
+        discardRecords = discard;
+        Object.deliverChangeRecords(callback);
+        discardRecords = false;
+      },
+      close: function() {
+        observer = undefined;
+        Object.unobserve(object, callback);
+        observedObjectCache.push(this);
+      }
+    };
+  }
+
+  function getObservedObject(observer, object, arrayObserve) {
+    var dir = observedObjectCache.pop() || newObservedObject();
+    dir.open(observer);
+    dir.observe(object, arrayObserve);
+    return dir;
+  }
+
+  var emptyArray = [];
+  var observedSetCache = [];
+
+  function newObservedSet() {
+    var observers = [];
+    var observerCount = 0;
+    var objects = [];
+    var toRemove = emptyArray;
+    var resetNeeded = false;
+    var resetScheduled = false;
+
+    function observe(obj) {
+      if (!isObject(obj))
+        return;
+
+      var index = toRemove.indexOf(obj);
+      if (index >= 0) {
+        toRemove[index] = undefined;
+        objects.push(obj);
+      } else if (objects.indexOf(obj) < 0) {
+        objects.push(obj);
+        Object.observe(obj, callback);
+      }
+
+      observe(Object.getPrototypeOf(obj));
+    }
+
+    function reset() {
+      resetScheduled = false;
+      if (!resetNeeded)
+        return;
+
+      var objs = toRemove === emptyArray ? [] : toRemove;
+      toRemove = objects;
+      objects = objs;
+
+      var observer;
+      for (var id in observers) {
+        observer = observers[id];
+        if (!observer || observer.state_ != OPENED)
+          continue;
+
+        observer.iterateObjects_(observe);
+      }
+
+      for (var i = 0; i < toRemove.length; i++) {
+        var obj = toRemove[i];
+        if (obj)
+          Object.unobserve(obj, callback);
+      }
+
+      toRemove.length = 0;
+    }
+
+    function scheduleReset() {
+      if (resetScheduled)
+        return;
+
+      resetNeeded = true;
+      resetScheduled = true;
+      runEOM(reset);
+    }
+
+    function callback() {
+      var observer;
+
+      for (var id in observers) {
+        observer = observers[id];
+        if (!observer || observer.state_ != OPENED)
+          continue;
+
+        observer.check_();
+      }
+
+      scheduleReset();
+    }
+
+    var record = {
+      object: undefined,
+      objects: objects,
+      open: function(obs) {
+        observers[obs.id_] = obs;
+        observerCount++;
+        obs.iterateObjects_(observe);
+      },
+      close: function(obs) {
+        var anyLeft = false;
+
+        observers[obs.id_] = undefined;
+        observerCount--;
+
+        if (observerCount) {
+          scheduleReset();
+          return;
+        }
+        resetNeeded = false;
+
+        for (var i = 0; i < objects.length; i++) {
+          Object.unobserve(objects[i], callback);
+          Observer.unobservedCount++;
+        }
+
+        observers.length = 0;
+        objects.length = 0;
+        observedSetCache.push(this);
+      },
+      reset: scheduleReset
+    };
+
+    return record;
+  }
+
+  var lastObservedSet;
+
+  function getObservedSet(observer, obj) {
+    if (!lastObservedSet || lastObservedSet.object !== obj) {
+      lastObservedSet = observedSetCache.pop() || newObservedSet();
+      lastObservedSet.object = obj;
+    }
+    lastObservedSet.open(observer);
+    return lastObservedSet;
+  }
+
+  var UNOPENED = 0;
+  var OPENED = 1;
+  var CLOSED = 2;
+  var RESETTING = 3;
+
+  var nextObserverId = 1;
+
+  function Observer() {
+    this.state_ = UNOPENED;
+    this.callback_ = undefined;
+    this.target_ = undefined; // TODO(rafaelw): Should be WeakRef
+    this.directObserver_ = undefined;
+    this.value_ = undefined;
+    this.id_ = nextObserverId++;
   }
 
   Observer.prototype = {
-    internalCallback: function(records) {
-      if (this.closed)
-        return;
-      if (this.reporting && this.check(records)) {
-        this.report();
-        if (this.testingResults)
-          this.testingResults.anyChanged = true;
-      }
+    open: function(callback, target) {
+      if (this.state_ != UNOPENED)
+        throw Error('Observer has already been opened.');
+
+      addToAll(this);
+      this.callback_ = callback;
+      this.target_ = target;
+      this.state_ = OPENED;
+      this.connect_();
+      return this.value_;
     },
 
     close: function() {
-      if (this.closed)
-        return;
-      if (this.object && typeof this.object.close === 'function')
-        this.object.close();
-
-      this.disconnect();
-      this.object = undefined;
-      this.closed = true;
-    },
-
-    deliver: function(testingResults) {
-      if (this.closed)
-        return;
-      if (hasObserve) {
-        this.testingResults = testingResults;
-        Object.deliverChangeRecords(this.boundInternalCallback);
-        this.testingResults = undefined;
-      } else {
-        dirtyCheck(this);
-      }
-    },
-
-    report: function() {
-      if (!this.reporting)
+      if (this.state_ != OPENED)
         return;
 
-      this.sync(false);
-      if (this.callback) {
-        this.reportArgs.push(this.token);
-        this.invokeCallback(this.reportArgs);
-      }
-      this.reportArgs = undefined;
+      removeFromAll(this);
+      this.state_ = CLOSED;
+      this.disconnect_();
+      this.value_ = undefined;
+      this.callback_ = undefined;
+      this.target_ = undefined;
     },
 
-    invokeCallback: function(args) {
+    deliver: function() {
+      if (this.state_ != OPENED)
+        return;
+
+      dirtyCheck(this);
+    },
+
+    report_: function(changes) {
       try {
-        this.callback.apply(this.target, args);
+        this.callback_.apply(this.target_, changes);
       } catch (ex) {
         Observer._errorThrownDuringCallback = true;
-        console.error('Exception caught during observer callback: ' + (ex.stack || ex));
+        console.error('Exception caught during observer callback: ' +
+                       (ex.stack || ex));
       }
     },
 
-    reset: function() {
-      if (this.closed)
-        return;
-
-      if (hasObserve) {
-        this.reporting = false;
-        Object.deliverChangeRecords(this.boundInternalCallback);
-        this.reporting = true;
-      }
-
-      this.sync(true);
+    discardChanges: function() {
+      this.check_(undefined, true);
+      return this.value_;
     }
   }
 
-  var collectObservers = !hasObserve || global.forceCollectObservers;
+  var collectObservers = !hasObserve;
   var allObservers;
   Observer._allObserversCount = 0;
 
@@ -458,11 +643,15 @@
   }
 
   function addToAll(observer) {
+    Observer._allObserversCount++;
     if (!collectObservers)
       return;
 
     allObservers.push(observer);
-    Observer._allObserversCount++;
+  }
+
+  function removeFromAll(observer) {
+    Observer._allObserversCount--;
   }
 
   var runningMicrotaskCheckpoint = false;
@@ -486,34 +675,31 @@
     runningMicrotaskCheckpoint = true;
 
     var cycles = 0;
-    var results = {};
+    var anyChanged, toCheck;
 
     do {
       cycles++;
-      var toCheck = allObservers;
+      toCheck = allObservers;
       allObservers = [];
-      results.anyChanged = false;
+      anyChanged = false;
 
       for (var i = 0; i < toCheck.length; i++) {
         var observer = toCheck[i];
-        if (observer.closed)
+        if (observer.state_ != OPENED)
           continue;
 
-        if (hasObserve) {
-          observer.deliver(results);
-        } else if (observer.check()) {
-          results.anyChanged = true;
-          observer.report();
-        }
+        if (observer.check_())
+          anyChanged = true;
 
         allObservers.push(observer);
       }
-    } while (cycles < MAX_DIRTY_CHECK_CYCLES && results.anyChanged);
+      if (runEOMTasks())
+        anyChanged = true;
+    } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
 
     if (global.testingExposeCycleCount)
       global.dirtyCheckCycleCount = cycles;
 
-    Observer._allObserversCount = allObservers.length;
     runningMicrotaskCheckpoint = false;
   };
 
@@ -523,26 +709,38 @@
     };
   }
 
-  function ObjectObserver(object, callback, target, token) {
-    Observer.call(this, object, callback, target, token);
-    this.connect();
-    this.sync(true);
+  function ObjectObserver(object) {
+    Observer.call(this);
+    this.value_ = object;
+    this.oldObject_ = undefined;
   }
 
   ObjectObserver.prototype = createObject({
     __proto__: Observer.prototype,
 
-    connect: function() {
-      if (hasObserve)
-        Object.observe(this.object, this.boundInternalCallback);
+    arrayObserve: false,
+
+    connect_: function(callback, target) {
+      if (hasObserve) {
+        this.directObserver_ = getObservedObject(this, this.value_,
+                                                 this.arrayObserve);
+      } else {
+        this.oldObject_ = this.copyObject(this.value_);
+      }
+
     },
 
-    sync: function(hard) {
-      if (!hasObserve)
-        this.oldObject = copyObject(this.object);
+    copyObject: function(object) {
+      var copy = Array.isArray(object) ? [] : {};
+      for (var prop in object) {
+        copy[prop] = object[prop];
+      };
+      if (Array.isArray(object))
+        copy.length = object.length;
+      return copy;
     },
 
-    check: function(changeRecords) {
+    check_: function(changeRecords, skipChanges) {
       var diff;
       var oldValues;
       if (hasObserve) {
@@ -550,67 +748,94 @@
           return false;
 
         oldValues = {};
-        diff = diffObjectFromChangeRecords(this.object, changeRecords,
+        diff = diffObjectFromChangeRecords(this.value_, changeRecords,
                                            oldValues);
       } else {
-        oldValues = this.oldObject;
-        diff = diffObjectFromOldObject(this.object, this.oldObject);
+        oldValues = this.oldObject_;
+        diff = diffObjectFromOldObject(this.value_, this.oldObject_);
       }
 
       if (diffIsEmpty(diff))
         return false;
 
-      this.reportArgs =
-          [diff.added || {}, diff.removed || {}, diff.changed || {}];
-      this.reportArgs.push(function(property) {
-        return oldValues[property];
-      });
+      if (!hasObserve)
+        this.oldObject_ = this.copyObject(this.value_);
+
+      this.report_([
+        diff.added || {},
+        diff.removed || {},
+        diff.changed || {},
+        function(property) {
+          return oldValues[property];
+        }
+      ]);
 
       return true;
     },
 
-    disconnect: function() {
-      if (!hasObserve)
-        this.oldObject = undefined;
-      else if (this.object)
-        Object.unobserve(this.object, this.boundInternalCallback);
+    disconnect_: function() {
+      if (hasObserve) {
+        this.directObserver_.close();
+        this.directObserver_ = undefined;
+      } else {
+        this.oldObject_ = undefined;
+      }
+    },
+
+    deliver: function() {
+      if (this.state_ != OPENED)
+        return;
+
+      if (hasObserve)
+        this.directObserver_.deliver(false);
+      else
+        dirtyCheck(this);
+    },
+
+    discardChanges: function() {
+      if (this.directObserver_)
+        this.directObserver_.deliver(true);
+      else
+        this.oldObject_ = this.copyObject(this.value_);
+
+      return this.value_;
     }
   });
 
-  function ArrayObserver(array, callback, target, token) {
+  function ArrayObserver(array) {
     if (!Array.isArray(array))
       throw Error('Provided object is not an Array');
-    ObjectObserver.call(this, array, callback, target, token);
+    ObjectObserver.call(this, array);
   }
 
   ArrayObserver.prototype = createObject({
+
     __proto__: ObjectObserver.prototype,
 
-    connect: function() {
-      if (hasObserve)
-        Array.observe(this.object, this.boundInternalCallback);
+    arrayObserve: true,
+
+    copyObject: function(arr) {
+      return arr.slice();
     },
 
-    sync: function() {
-      if (!hasObserve)
-        this.oldObject = this.object.slice();
-    },
-
-    check: function(changeRecords) {
+    check_: function(changeRecords) {
       var splices;
       if (hasObserve) {
         if (!changeRecords)
           return false;
-        splices = projectArraySplices(this.object, changeRecords);
+        splices = projectArraySplices(this.value_, changeRecords);
       } else {
-        splices = calcSplices(this.object, 0, this.object.length,
-                              this.oldObject, 0, this.oldObject.length);
+        splices = calcSplices(this.value_, 0, this.value_.length,
+                              this.oldObject_, 0, this.oldObject_.length);
       }
 
       if (!splices || !splices.length)
         return false;
 
-      this.reportArgs = [splices];
+      if (!hasObserve)
+        this.oldObject_ = this.copyObject(this.value_);
+
+      this.report_([splices]);
       return true;
     }
   });
@@ -628,255 +853,247 @@
     });
   };
 
-  function ObservedSet(callback) {
-    this.arr = [];
-    this.callback = callback;
-    this.isObserved = true;
-  }
+  function PathObserver(object, path) {
+    Observer.call(this);
 
-  // TODO(rafaelw): Consider surfacing a way to avoid observing prototype
-  // ancestors which are expected not to change (e.g. Element, Node...).
-  var objProto = Object.getPrototypeOf({});
-  var arrayProto = Object.getPrototypeOf([]);
-  ObservedSet.prototype = {
-    reset: function() {
-      this.isObserved = !this.isObserved;
-    },
-
-    observe: function(obj) {
-      if (!isObject(obj) || obj === objProto || obj === arrayProto)
-        return;
-      var i = this.arr.indexOf(obj);
-      if (i >= 0 && this.arr[i+1] === this.isObserved)
-        return;
-
-      if (i < 0) {
-        i = this.arr.length;
-        this.arr[i] = obj;
-        Object.observe(obj, this.callback);
-      }
-
-      this.arr[i+1] = this.isObserved;
-      this.observe(Object.getPrototypeOf(obj));
-    },
-
-    cleanup: function() {
-      var i = 0, j = 0;
-      var isObserved = this.isObserved;
-      while(j < this.arr.length) {
-        var obj = this.arr[j];
-        if (this.arr[j + 1] == isObserved) {
-          if (i < j) {
-            this.arr[i] = obj;
-            this.arr[i + 1] = isObserved;
-          }
-          i += 2;
-        } else {
-          Object.unobserve(obj, this.callback);
-        }
-        j += 2;
-      }
-
-      this.arr.length = i;
-    }
-  };
-
-  function PathObserver(object, path, callback, target, token, valueFn,
-                        setValueFn) {
-    var path = path instanceof Path ? path : getPath(path);
-    if (!path || !path.length || !isObject(object)) {
-      this.value_ = path ? path.getValueFrom(object) : undefined;
-      this.value = valueFn ? valueFn(this.value_) : this.value_;
-      this.closed = true;
-      return;
-    }
-
-    Observer.call(this, object, callback, target, token);
-    this.valueFn = valueFn;
-    this.setValueFn = setValueFn;
-    this.path = path;
-
-    this.connect();
-    this.sync(true);
+    this.object_ = object;
+    this.path_ = path instanceof Path ? path : getPath(path);
+    this.directObserver_ = undefined;
   }
 
   PathObserver.prototype = createObject({
     __proto__: Observer.prototype,
 
-    connect: function() {
+    connect_: function() {
       if (hasObserve)
-        this.observedSet = new ObservedSet(this.boundInternalCallback);
+        this.directObserver_ = getObservedSet(this, this.object_);
+
+      this.check_(undefined, true);
     },
 
-    disconnect: function() {
-      this.value = undefined;
+    disconnect_: function() {
       this.value_ = undefined;
-      if (this.observedSet) {
-        this.observedSet.reset();
-        this.observedSet.cleanup();
-        this.observedSet = undefined;
+
+      if (this.directObserver_) {
+        this.directObserver_.close(this);
+        this.directObserver_ = undefined;
       }
     },
 
-    check: function() {
-      // Note: Extracting this to a member function for use here and below
-      // regresses dirty-checking path perf by about 25% =-(.
-      if (this.observedSet)
-        this.observedSet.reset();
+    iterateObjects_: function(observe) {
+      this.path_.iterateObjects(this.object_, observe);
+    },
 
-      this.value_ = this.path.getValueFrom(this.object, this.observedSet);
-
-      if (this.observedSet)
-        this.observedSet.cleanup();
-
-      if (areSameValue(this.value_, this.oldValue_))
+    check_: function(changeRecords, skipChanges) {
+      var oldValue = this.value_;
+      this.value_ = this.path_.getValueFrom(this.object_);
+      if (skipChanges || areSameValue(this.value_, oldValue))
         return false;
 
-      this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
-      this.reportArgs = [this.value, this.oldValue];
+      this.report_([this.value_, oldValue]);
       return true;
     },
 
-    sync: function(hard) {
-      if (hard) {
-        if (this.observedSet)
-          this.observedSet.reset();
-
-        this.value_ = this.path.getValueFrom(this.object, this.observedSet);
-        this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
-
-        if (this.observedSet)
-          this.observedSet.cleanup();
-      }
-
-      this.oldValue_ = this.value_;
-      this.oldValue = this.value;
-    },
-
     setValue: function(newValue) {
-      if (!this.path)
-        return;
-      if (typeof this.setValueFn === 'function')
-        newValue = this.setValueFn(newValue);
-      this.path.setValueFrom(this.object, newValue);
+      if (this.path_)
+        this.path_.setValueFrom(this.object_, newValue);
     }
   });
 
-  function CompoundPathObserver(callback, target, token, valueFn) {
-    Observer.call(this, undefined, callback, target, token);
-    this.valueFn = valueFn;
+  function CompoundObserver() {
+    Observer.call(this);
 
-    this.observed = [];
-    this.values = [];
-    this.value = undefined;
-    this.oldValue = undefined;
-    this.oldValues = undefined;
-    this.changeFlags = undefined;
-    this.started = false;
+    this.value_ = [];
+    this.directObserver_ = undefined;
+    this.observed_ = [];
   }
 
-  CompoundPathObserver.prototype = createObject({
-    __proto__: PathObserver.prototype,
+  var observerSentinel = {};
 
-    // TODO(rafaelw): Consider special-casing when |object| is a PathObserver
-    // and path 'value' to avoid explicit observation.
-    addPath: function(object, path) {
-      if (this.started)
-        throw Error('Cannot add more paths once started.');
+  CompoundObserver.prototype = createObject({
+    __proto__: Observer.prototype,
 
-      var path = path instanceof Path ? path : getPath(path);
-      var value = path ? path.getValueFrom(object) : undefined;
+    connect_: function() {
+      this.check_(undefined, true);
 
-      this.observed.push(object, path);
-      this.values.push(value);
-    },
+      if (!hasObserve)
+        return;
 
-    start: function() {
-      this.started = true;
-      this.connect();
-      this.sync(true);
-    },
-
-    getValues: function() {
-      if (this.observedSet)
-        this.observedSet.reset();
-
-      var anyChanged = false;
-      for (var i = 0; i < this.observed.length; i = i+2) {
-        var path = this.observed[i+1];
-        if (!path)
-          continue;
-        var object = this.observed[i];
-        var value = path.getValueFrom(object, this.observedSet);
-        var oldValue = this.values[i/2];
-        if (!areSameValue(value, oldValue)) {
-          if (!anyChanged && !this.valueFn) {
-            this.oldValues = this.oldValues || [];
-            this.changeFlags = this.changeFlags || [];
-            for (var j = 0; j < this.values.length; j++) {
-              this.oldValues[j] = this.values[j];
-              this.changeFlags[j] = false;
-            }
-          }
-
-          if (!this.valueFn)
-            this.changeFlags[i/2] = true;
-
-          this.values[i/2] = value;
-          anyChanged = true;
+      var object;
+      var needsDirectObserver = false;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        object = this.observed_[i]
+        if (object !== observerSentinel) {
+          needsDirectObserver = true;
+          break;
         }
       }
 
-      if (this.observedSet)
-        this.observedSet.cleanup();
-
-      return anyChanged;
-    },
-
-    check: function() {
-      if (!this.getValues())
+      if (this.directObserver_) {
+        if (needsDirectObserver) {
+          this.directObserver_.reset();
+          return;
+        }
+        this.directObserver_.close();
+        this.directObserver_ = undefined;
         return;
-
-      if (this.valueFn) {
-        this.value = this.valueFn(this.values);
-
-        if (areSameValue(this.value, this.oldValue))
-          return false;
-
-        this.reportArgs = [this.value, this.oldValue];
-      } else {
-        this.reportArgs = [this.values, this.oldValues, this.changeFlags,
-                           this.observed];
       }
 
-      return true;
+      if (needsDirectObserver)
+        this.directObserver_ = getObservedSet(this, object);
     },
 
-    sync: function(hard) {
-      if (hard) {
-        this.getValues();
-        if (this.valueFn)
-          this.value = this.valueFn(this.values);
+    closeObservers_: function() {
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        if (this.observed_[i] === observerSentinel)
+          this.observed_[i + 1].close();
+      }
+      this.observed_.length = 0;
+    },
+
+    disconnect_: function() {
+      this.value_ = undefined;
+
+      if (this.directObserver_) {
+        this.directObserver_.close(this);
+        this.directObserver_ = undefined;
       }
 
-      if (this.valueFn)
-        this.oldValue = this.value;
+      this.closeObservers_();
+    },
+
+    addPath: function(object, path) {
+      if (this.state_ != UNOPENED && this.state_ != RESETTING)
+        throw Error('Cannot add paths once started.');
+
+      this.observed_.push(object, path instanceof Path ? path : getPath(path));
+    },
+
+    addObserver: function(observer) {
+      if (this.state_ != UNOPENED && this.state_ != RESETTING)
+        throw Error('Cannot add observers once started.');
+
+      observer.open(this.deliver, this);
+      this.observed_.push(observerSentinel, observer);
+    },
+
+    startReset: function() {
+      if (this.state_ != OPENED)
+        throw Error('Can only reset while open');
+
+      this.state_ = RESETTING;
+      this.closeObservers_();
+    },
+
+    finishReset: function() {
+      if (this.state_ != RESETTING)
+        throw Error('Can only finishReset after startReset');
+      this.state_ = OPENED;
+      this.connect_();
+
+      return this.value_;
+    },
+
+    iterateObjects_: function(observe) {
+      var object;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        object = this.observed_[i]
+        if (object !== observerSentinel)
+          this.observed_[i + 1].iterateObjects(object, observe)
+      }
+    },
+
+    check_: function(changeRecords, skipChanges) {
+      var oldValues;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        var pathOrObserver = this.observed_[i+1];
+        var object = this.observed_[i];
+        var value = object === observerSentinel ?
+            pathOrObserver.discardChanges() :
+            pathOrObserver.getValueFrom(object)
+
+        if (skipChanges) {
+          this.value_[i / 2] = value;
+          continue;
+        }
+
+        if (areSameValue(value, this.value_[i / 2]))
+          continue;
+
+        oldValues = oldValues || [];
+        oldValues[i / 2] = this.value_[i / 2];
+        this.value_[i / 2] = value;
+      }
+
+      if (!oldValues)
+        return false;
+
+      // TODO(rafaelw): Having observed_ as the third callback arg here is
+      // pretty lame API. Fix.
+      this.report_([this.value_, oldValues, this.observed_]);
+      return true;
+    }
+  });
+
+  function identFn(value) { return value; }
+
+  function ObserverTransform(observable, getValueFn, setValueFn,
+                             dontPassThroughSet) {
+    this.callback_ = undefined;
+    this.target_ = undefined;
+    this.value_ = undefined;
+    this.observable_ = observable;
+    this.getValueFn_ = getValueFn || identFn;
+    this.setValueFn_ = setValueFn || identFn;
+    // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this
+    // at the moment because of a bug in it's dependency tracking.
+    this.dontPassThroughSet_ = dontPassThroughSet;
+  }
+
+  ObserverTransform.prototype = {
+    open: function(callback, target) {
+      this.callback_ = callback;
+      this.target_ = target;
+      this.value_ =
+          this.getValueFn_(this.observable_.open(this.observedCallback_, this));
+      return this.value_;
+    },
+
+    observedCallback_: function(value) {
+      value = this.getValueFn_(value);
+      if (areSameValue(value, this.value_))
+        return;
+      var oldValue = this.value_;
+      this.value_ = value;
+      this.callback_.call(this.target_, this.value_, oldValue);
+    },
+
+    discardChanges: function() {
+      this.value_ = this.getValueFn_(this.observable_.discardChanges());
+      return this.value_;
+    },
+
+    deliver: function() {
+      return this.observable_.deliver();
+    },
+
+    setValue: function(value) {
+      value = this.setValueFn_(value);
+      if (!this.dontPassThroughSet_ && this.observable_.setValue)
+        return this.observable_.setValue(value);
     },
 
     close: function() {
-      if (this.observed) {
-        for (var i = 0; i < this.observed.length; i = i + 2) {
-          var object = this.observed[i];
-          if (object && typeof object.close === 'function')
-            object.close();
-        }
-        this.observed = undefined;
-        this.values = undefined;
-      }
-
-      Observer.prototype.close.call(this);
+      if (this.observable_)
+        this.observable_.close();
+      this.callback_ = undefined;
+      this.target_ = undefined;
+      this.observable_ = undefined;
+      this.value_ = undefined;
+      this.getValueFn_ = undefined;
+      this.setValueFn_ = undefined;
     }
-  });
+  }
 
   var expectedRecordTypes = {};
   expectedRecordTypes[PROP_ADD_TYPE] = true;
@@ -900,40 +1117,31 @@
     }
   }
 
-  // TODO(rafaelw): It should be possible for the Object.observe case to have
-  // every PathObserver used by defineProperty share a single Object.observe
-  // callback, and thus get() can simply call observer.deliver() and any changes
-  // to any dependent value will be observed.
-  PathObserver.defineProperty = function(target, name, object, path) {
-    // TODO(rafaelw): Validate errors
-    path = getPath(path);
+  Observer.defineComputedProperty = function(target, name, observable) {
     var notify = notifyFunction(target, name);
-
-    var observer = new PathObserver(object, path,
-        function(newValue, oldValue) {
-          if (notify)
-            notify(PROP_UPDATE_TYPE, oldValue);
-        }
-    );
+    var value = observable.open(function(newValue, oldValue) {
+      value = newValue;
+      if (notify)
+        notify(PROP_UPDATE_TYPE, oldValue);
+    });
 
     Object.defineProperty(target, name, {
       get: function() {
-        return path.getValueFrom(object);
+        observable.deliver();
+        return value;
       },
       set: function(newValue) {
-        path.setValueFrom(object, newValue);
+        observable.setValue(newValue);
+        return newValue;
       },
       configurable: true
     });
 
     return {
       close: function() {
-        var oldValue = path.getValueFrom(object);
-        if (notify)
-          observer.deliver();
-        observer.close();
+        observable.close();
         Object.defineProperty(target, name, {
-          value: oldValue,
+          value: value,
           writable: true,
           configurable: true
         });
@@ -1397,6 +1605,7 @@
   }
 
   global.Observer = Observer;
+  global.Observer.runEOM_ = runEOM;
   global.Observer.hasObjectObserve = hasObserve;
   global.ArrayObserver = ArrayObserver;
   global.ArrayObserver.calculateSplices = function(current, previous) {
@@ -1406,8 +1615,9 @@
   global.ArraySplice = ArraySplice;
   global.ObjectObserver = ObjectObserver;
   global.PathObserver = PathObserver;
-  global.CompoundPathObserver = CompoundPathObserver;
+  global.CompoundObserver = CompoundObserver;
   global.Path = Path;
+  global.ObserverTransform = ObserverTransform;
 
   // TODO(rafaelw): Only needed for testing until new change record names
   // make it to release.
@@ -1418,7 +1628,7 @@
     'delete': PROP_DELETE_TYPE,
     splice: ARRAY_SPLICE_TYPE
   };
-})(typeof global !== 'undefined' && global ? global : this || window);
+})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
 
 /*
  * Copyright 2012 The Polymer Authors. All rights reserved.
@@ -1708,12 +1918,14 @@
   }
 
   var OriginalDOMImplementation = window.DOMImplementation;
+  var OriginalEventTarget = window.EventTarget;
   var OriginalEvent = window.Event;
   var OriginalNode = window.Node;
   var OriginalWindow = window.Window;
   var OriginalRange = window.Range;
   var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
   var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+  var OriginalSVGElementInstance = window.SVGElementInstance;
 
   function isWrapper(object) {
     return object instanceof wrappers.EventTarget ||
@@ -1726,14 +1938,17 @@
   }
 
   function isNative(object) {
-    return object instanceof OriginalNode ||
+    return OriginalEventTarget && object instanceof OriginalEventTarget ||
+           object instanceof OriginalNode ||
            object instanceof OriginalEvent ||
            object instanceof OriginalWindow ||
            object instanceof OriginalRange ||
            object instanceof OriginalDOMImplementation ||
            object instanceof OriginalCanvasRenderingContext2D ||
            OriginalWebGLRenderingContext &&
-               object instanceof OriginalWebGLRenderingContext;
+               object instanceof OriginalWebGLRenderingContext ||
+           OriginalSVGElementInstance &&
+               object instanceof OriginalSVGElementInstance;
   }
 
   /**
@@ -1832,6 +2047,7 @@
   scope.defineGetter = defineGetter;
   scope.defineWrapGetter = defineWrapGetter;
   scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+  scope.isWrapper = isWrapper;
   scope.isWrapperFor = isWrapperFor;
   scope.mixin = mixin;
   scope.nativePrototypeTable = nativePrototypeTable;
@@ -2287,6 +2503,7 @@
   var wrappedFuns = new WeakMap();
   var listenersTable = new WeakMap();
   var handledEventsTable = new WeakMap();
+  var currentlyDispatchingEvents = new WeakMap();
   var targetTable = new WeakMap();
   var currentTargetTable = new WeakMap();
   var relatedTargetTable = new WeakMap();
@@ -2458,16 +2675,16 @@
       return;
     handledEventsTable.set(originalEvent, true);
 
-    // Render before dispatching the event to ensure that the event path is
-    // correct.
-    scope.renderAllPending();
-
-    var target = wrap(originalEvent.target);
-    var event = wrap(originalEvent);
-    return dispatchEvent(event, target);
+    return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
   }
 
   function dispatchEvent(event, originalWrapperTarget) {
+    if (currentlyDispatchingEvents.get(event))
+      throw new Error('InvalidStateError')
+    currentlyDispatchingEvents.set(event, true);
+
+    // Render to ensure that the event path is correct.
+    scope.renderAllPending();
     var eventPath = retarget(originalWrapperTarget);
 
     // For window load events the load event is dispatched at the window but
@@ -2491,7 +2708,8 @@
     }
 
     eventPhaseTable.set(event, Event.NONE);
-    currentTargetTable.set(event, null);
+    currentTargetTable.delete(event, null);
+    currentlyDispatchingEvents.delete(event);
 
     return event.defaultPrevented;
   }
@@ -2630,7 +2848,12 @@
   };
 
   var OriginalEvent = window.Event;
-  OriginalEvent.prototype.polymerBlackList_ = {returnValue: true};
+  OriginalEvent.prototype.polymerBlackList_ = {
+    returnValue: true,
+    // TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not
+    // support constructable KeyboardEvent so we keep it here for now.
+    keyLocation: true
+  };
 
   /**
    * Creates a new Event wrapper or wraps an existin native Event object.
@@ -2705,14 +2928,16 @@
     if (prototype)
       mixin(GenericEvent.prototype, prototype);
     if (OriginalEvent) {
-      // IE does not support event constructors but FocusEvent can only be
-      // created using new FocusEvent in Firefox.
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=882165
-      if (OriginalEvent.prototype['init' + name]) {
+      // - Old versions of Safari fails on new FocusEvent (and others?).
+      // - IE does not support event constructors.
+      // - createEvent('FocusEvent') throws in Firefox.
+      // => Try the best practice solution first and fallback to the old way
+      // if needed.
+      try {
+        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
+      } catch (ex) {
         registerWrapper(OriginalEvent, GenericEvent,
                         document.createEvent(name));
-      } else {
-        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
       }
     }
     return GenericEvent;
@@ -2753,7 +2978,7 @@
 
   var supportsEventConstructors = (function() {
     try {
-      new window.MouseEvent('click');
+      new window.FocusEvent('focus');
     } catch (ex) {
       return false;
     }
@@ -2924,16 +3149,62 @@
       }
     },
     dispatchEvent: function(event) {
-      var target = getTargetToListenAt(this);
+      // We want to use the native dispatchEvent because it triggers the default
+      // actions (like checking a checkbox). However, if there are no listeners
+      // in the composed tree then there are no events that will trigger and
+      // listeners in the non composed tree that are part of the event path are
+      // not notified.
+      //
+      // If we find out that there are no listeners in the composed tree we add
+      // a temporary listener to the target which makes us get called back even
+      // in that case.
+
       var nativeEvent = unwrap(event);
+      var eventType = nativeEvent.type;
+
       // Allow dispatching the same event again. This is safe because if user
       // code calls this during an existing dispatch of the same event the
       // native dispatchEvent throws (that is required by the spec).
       handledEventsTable.set(nativeEvent, false);
-      return target.dispatchEvent_(nativeEvent);
+
+      // Force rendering since we prefer native dispatch and that works on the
+      // composed tree.
+      scope.renderAllPending();
+
+      var tempListener;
+      if (!hasListenerInAncestors(this, eventType)) {
+        tempListener = function() {};
+        this.addEventListener(eventType, tempListener, true);
+      }
+
+      try {
+        return unwrap(this).dispatchEvent_(nativeEvent);
+      } finally {
+        if (tempListener)
+          this.removeEventListener(eventType, tempListener, true);
+      }
     }
   };
 
+  function hasListener(node, type) {
+    var listeners = listenersTable.get(node);
+    if (listeners) {
+      for (var i = 0; i < listeners.length; i++) {
+        if (!listeners[i].removed && listeners[i].type === type)
+          return true;
+      }
+    }
+    return false;
+  }
+
+  function hasListenerInAncestors(target, type) {
+    for (var node = unwrap(target); node; node = node.parentNode) {
+      if (hasListener(wrap(node), type))
+        return true;
+    }
+    return false;
+  }
+
   if (OriginalEventTarget)
     registerWrapper(OriginalEventTarget, EventTarget);
 
@@ -3081,6 +3352,7 @@
   var assert = scope.assert;
   var defineWrapGetter = scope.defineWrapGetter;
   var enqueueMutation = scope.enqueueMutation;
+  var isWrapper = scope.isWrapper;
   var mixin = scope.mixin;
   var registerTransientObservers = scope.registerTransientObservers;
   var registerWrapper = scope.registerWrapper;
@@ -3254,6 +3526,18 @@
     return df;
   }
 
+  function clearChildNodes(wrapper) {
+    if (wrapper.firstChild_ !== undefined) {
+      var child = wrapper.firstChild_;
+      while (child) {
+        var tmp = child;
+        child = child.nextSibling_;
+        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+      }
+    }
+    wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+  }
+
   function removeAllChildNodes(wrapper) {
     if (wrapper.invalidateShadowRenderer()) {
       var childWrapper = wrapper.firstChild;
@@ -3286,6 +3570,13 @@
     return p && p.invalidateShadowRenderer();
   }
 
+  function cleanupNodes(nodes) {
+    for (var i = 0, n; i < nodes.length; i++) {
+      n = nodes[i];
+      n.parentNode.removeChild(n);
+    }
+  }
+
   var OriginalNode = window.Node;
 
   /**
@@ -3332,7 +3623,7 @@
      * @private
      */
     this.previousSibling_ = undefined;
-  };
+  }
 
   var OriginalDocumentFragment = window.DocumentFragment;
   var originalAppendChild = OriginalNode.prototype.appendChild;
@@ -3366,8 +3657,19 @@
     insertBefore: function(childWrapper, refWrapper) {
       assertIsNodeWrapper(childWrapper);
 
-      refWrapper = refWrapper || null;
-      refWrapper && assertIsNodeWrapper(refWrapper);
+      var refNode;
+      if (refWrapper) {
+        if (isWrapper(refWrapper)) {
+          refNode = unwrap(refWrapper);
+        } else {
+          refNode = refWrapper;
+          refWrapper = wrap(refNode);
+        }
+      } else {
+        refWrapper = null;
+        refNode = null;
+      }
+
       refWrapper && assert(refWrapper.parentNode === this);
 
       var nodes;
@@ -3384,15 +3686,14 @@
 
       if (useNative) {
         ensureSameOwnerDocument(this, childWrapper);
-        originalInsertBefore.call(this.impl, unwrap(childWrapper),
-                                  unwrap(refWrapper));
+        clearChildNodes(this);
+        originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);
       } else {
         if (!previousNode)
           this.firstChild_ = nodes[0];
         if (!refWrapper)
           this.lastChild_ = nodes[nodes.length - 1];
 
-        var refNode = unwrap(refWrapper);
         var parentNode = refNode ? refNode.parentNode : this.impl;
 
         // insertBefore refWrapper no matter what the parent is?
@@ -3463,6 +3764,7 @@
         childWrapper.previousSibling_ = childWrapper.nextSibling_ =
             childWrapper.parentNode_ = undefined;
       } else {
+        clearChildNodes(this);
         removeChildOriginalHelper(this.impl, childNode);
       }
 
@@ -3481,14 +3783,20 @@
 
     replaceChild: function(newChildWrapper, oldChildWrapper) {
       assertIsNodeWrapper(newChildWrapper);
-      assertIsNodeWrapper(oldChildWrapper);
+
+      var oldChildNode;
+      if (isWrapper(oldChildWrapper)) {
+        oldChildNode = unwrap(oldChildWrapper);
+      } else {
+        oldChildNode = oldChildWrapper;
+        oldChildWrapper = wrap(oldChildNode);
+      }
 
       if (oldChildWrapper.parentNode !== this) {
         // TODO(arv): DOMException
         throw new Error('NotFoundError');
       }
 
-      var oldChildNode = unwrap(oldChildWrapper);
       var nextNode = oldChildWrapper.nextSibling;
       var previousNode = oldChildWrapper.previousSibling;
       var nodes;
@@ -3522,6 +3830,7 @@
         }
       } else {
         ensureSameOwnerDocument(this, newChildWrapper);
+        clearChildNodes(this);
         originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
                                   oldChildNode);
       }
@@ -3598,7 +3907,9 @@
       // are no shadow trees below or above the context node.
       var s = '';
       for (var child = this.firstChild; child; child = child.nextSibling) {
-        s += child.textContent;
+        if (child.nodeType != Node.COMMENT_NODE) {
+          s += child.textContent;
+        }
       }
       return s;
     },
@@ -3612,6 +3923,7 @@
           this.appendChild(textNode);
         }
       } else {
+        clearChildNodes(this);
         this.impl.textContent = textContent;
       }
 
@@ -3666,6 +3978,43 @@
       // This only wraps, it therefore only operates on the composed DOM and not
       // the logical DOM.
       return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));
+    },
+
+    normalize: function() {
+      var nodes = snapshotNodeList(this.childNodes);
+      var remNodes = [];
+      var s = '';
+      var modNode;
+
+      for (var i = 0, n; i < nodes.length; i++) {
+        n = nodes[i];
+        if (n.nodeType === Node.TEXT_NODE) {
+          if (!modNode && !n.data.length)
+            this.removeNode(n);
+          else if (!modNode)
+            modNode = n;
+          else {
+            s += n.data;
+            remNodes.push(n);
+          }
+        } else {
+          if (modNode && remNodes.length) {
+            modNode.data += s;
+            cleanUpNodes(remNodes);
+          }
+          remNodes = [];
+          s = '';
+          modNode = null;
+          if (n.childNodes.length)
+            n.normalize();
+        }
+      }
+
+      // handle case where >1 text nodes are the last children
+      if (modNode && remNodes.length) {
+        modNode.data += s;
+        cleanupNodes(remNodes);
+      }
     }
   });
 
@@ -3878,6 +4227,49 @@
   scope.wrappers.CharacterData = CharacterData;
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var CharacterData = scope.wrappers.CharacterData;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+
+  function toUInt32(x) {
+    return x >>> 0;
+  }
+
+  var OriginalText = window.Text;
+
+  function Text(node) {
+    CharacterData.call(this, node);
+  }
+  Text.prototype = Object.create(CharacterData.prototype);
+  mixin(Text.prototype, {
+    splitText: function(offset) {
+      offset = toUInt32(offset);
+      var s = this.data;
+      if (offset > s.length)
+        throw new Error('IndexSizeError');
+      var head = s.slice(0, offset);
+      var tail = s.slice(offset);
+      this.data = head;
+      var newTextNode = this.ownerDocument.createTextNode(tail);
+      if (this.parentNode)
+        this.parentNode.insertBefore(newTextNode, this.nextSibling);
+      return newTextNode;
+    }
+  });
+
+  registerWrapper(OriginalText, Text, document.createTextNode(''));
+
+  scope.wrappers.Text = Text;
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -3899,12 +4291,16 @@
 
   var OriginalElement = window.Element;
 
-  var matchesName = oneOf(OriginalElement.prototype, [
-    'matches',
+  var matchesNames = [
+    'matches',  // needs to come first.
     'mozMatchesSelector',
     'msMatchesSelector',
     'webkitMatchesSelector',
-  ]);
+  ].filter(function(name) {
+    return OriginalElement.prototype[name];
+  });
+
+  var matchesName = matchesNames[0];
 
   var originalMatches = OriginalElement.prototype[matchesName];
 
@@ -3968,9 +4364,13 @@
     }
   });
 
-  Element.prototype[matchesName] = function(selector) {
-    return this.matches(selector);
-  };
+  matchesNames.forEach(function(name) {
+    if (name !== 'matches') {
+      Element.prototype[name] = function(selector) {
+        return this.matches(selector);
+      };
+    }
+  });
 
   if (OriginalElement.prototype.webkitCreateShadowRoot) {
     Element.prototype.webkitCreateShadowRoot =
@@ -4004,11 +4404,12 @@
   mixin(Element.prototype, ParentNodeInterface);
   mixin(Element.prototype, SelectorsInterface);
 
-  registerWrapper(OriginalElement, Element);
+  registerWrapper(OriginalElement, Element,
+                  document.createElementNS(null, 'x'));
 
   // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
   // that reflect attributes.
-  scope.matchesName = matchesName;
+  scope.matchesNames = matchesNames;
   scope.wrappers.Element = Element;
 })(window.ShadowDOMPolyfill);
 
@@ -4033,7 +4434,9 @@
   /////////////////////////////////////////////////////////////////////////////
   // innerHTML and outerHTML
 
-  var escapeRegExp = /&|<|"/g;
+  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
+  var escapeAttrRegExp = /[&\u00A0"]/g;
+  var escapeDataRegExp = /[&\u00A0<>]/g;
 
   function escapeReplace(c) {
     switch (c) {
@@ -4041,43 +4444,70 @@
         return '&amp;';
       case '<':
         return '&lt;';
+      case '>':
+        return '&gt;';
       case '"':
         return '&quot;'
+      case '\u00A0':
+        return '&nbsp;';
     }
   }
 
-  function escape(s) {
-    return s.replace(escapeRegExp, escapeReplace);
+  function escapeAttr(s) {
+    return s.replace(escapeAttrRegExp, escapeReplace);
+  }
+
+  function escapeData(s) {
+    return s.replace(escapeDataRegExp, escapeReplace);
+  }
+
+  function makeSet(arr) {
+    var set = {};
+    for (var i = 0; i < arr.length; i++) {
+      set[arr[i]] = true;
+    }
+    return set;
   }
 
   // http://www.whatwg.org/specs/web-apps/current-work/#void-elements
-  var voidElements = {
-    'area': true,
-    'base': true,
-    'br': true,
-    'col': true,
-    'command': true,
-    'embed': true,
-    'hr': true,
-    'img': true,
-    'input': true,
-    'keygen': true,
-    'link': true,
-    'meta': true,
-    'param': true,
-    'source': true,
-    'track': true,
-    'wbr': true
-  };
+  var voidElements = makeSet([
+    'area',
+    'base',
+    'br',
+    'col',
+    'command',
+    'embed',
+    'hr',
+    'img',
+    'input',
+    'keygen',
+    'link',
+    'meta',
+    'param',
+    'source',
+    'track',
+    'wbr'
+  ]);
 
-  function getOuterHTML(node) {
+  var plaintextParents = makeSet([
+    'style',
+    'script',
+    'xmp',
+    'iframe',
+    'noembed',
+    'noframes',
+    'plaintext',
+    'noscript'
+  ]);
+
+  function getOuterHTML(node, parentNode) {
     switch (node.nodeType) {
       case Node.ELEMENT_NODE:
         var tagName = node.tagName.toLowerCase();
         var s = '<' + tagName;
         var attrs = node.attributes;
         for (var i = 0, attr; attr = attrs[i]; i++) {
-          s += ' ' + attr.name + '="' + escape(attr.value) + '"';
+          s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
         }
         s += '>';
         if (voidElements[tagName])
@@ -4086,10 +4516,14 @@
         return s + getInnerHTML(node) + '</' + tagName + '>';
 
       case Node.TEXT_NODE:
-        return escape(node.nodeValue);
+        var data = node.data;
+        if (parentNode && plaintextParents[parentNode.localName])
+          return data;
+        return escapeData(data);
 
       case Node.COMMENT_NODE:
-        return '<!--' + escape(node.nodeValue) + '-->';
+        return '<!--' + node.data + '-->';
+
       default:
         console.error(node);
         throw new Error('not implemented');
@@ -4099,7 +4533,7 @@
   function getInnerHTML(node) {
     var s = '';
     for (var child = node.firstChild; child; child = child.nextSibling) {
-      s += getOuterHTML(child);
+      s += getOuterHTML(child, node);
     }
     return s;
   }
@@ -4115,6 +4549,9 @@
     }
   }
 
+  // IE11 does not have MSIE in the user agent string.
+  var oldIe = /MSIE/.test(navigator.userAgent);
+
   var OriginalHTMLElement = window.HTMLElement;
 
   function HTMLElement(node) {
@@ -4128,6 +4565,17 @@
       return getInnerHTML(this);
     },
     set innerHTML(value) {
+      // IE9 does not handle set innerHTML correctly on plaintextParents. It
+      // creates element children. For example
+      //
+      //   scriptElement.innerHTML = '<a>test</a>'
+      //
+      // Creates a single HTMLAnchorElement child.
+      if (oldIe && plaintextParents[this.localName]) {
+        this.textContent = value;
+        return;
+      }
+
       var removedNodes = snapshotNodeList(this.childNodes);
 
       if (this.invalidateShadowRenderer())
@@ -4146,19 +4594,57 @@
     },
 
     get outerHTML() {
-      // TODO(arv): This should fallback to HTMLElement_prototype.outerHTML if there
-      // are no shadow trees below or above the context node.
-      return getOuterHTML(this);
+      return getOuterHTML(this, this.parentNode);
     },
     set outerHTML(value) {
       var p = this.parentNode;
       if (p) {
         p.invalidateShadowRenderer();
-        this.impl.outerHTML = value;
+        var df = frag(p, value);
+        p.replaceChild(df, this);
       }
+    },
+
+    insertAdjacentHTML: function(position, text) {
+      var contextElement, refNode;
+      switch (String(position).toLowerCase()) {
+        case 'beforebegin':
+          contextElement = this.parentNode;
+          refNode = this;
+          break;
+        case 'afterend':
+          contextElement = this.parentNode;
+          refNode = this.nextSibling;
+          break;
+        case 'afterbegin':
+          contextElement = this;
+          refNode = this.firstChild;
+          break;
+        case 'beforeend':
+          contextElement = this;
+          refNode = null;
+          break;
+        default:
+          return;
+      }
+
+      var df = frag(contextElement, text);
+      contextElement.insertBefore(df, refNode);
     }
   });
 
+  function frag(contextElement, html) {
+    // TODO(arv): This does not work with SVG and other non HTML elements.
+    var p = unwrap(contextElement.cloneNode(false));
+    p.innerHTML = html;
+    var df = unwrap(document.createDocumentFragment());
+    var c;
+    while (c = p.firstChild) {
+      df.appendChild(c);
+    }
+    return wrap(df);
+  }
+
   function getter(name) {
     return function() {
       scope.renderAllPending();
@@ -4616,6 +5102,138 @@
   scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var registerObject = scope.registerObject;
+
+  var SVG_NS = 'http://www.w3.org/2000/svg';
+  var svgTitleElement = document.createElementNS(SVG_NS, 'title');
+  var SVGTitleElement = registerObject(svgTitleElement);
+  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+
+  scope.wrappers.SVGElement = SVGElement;
+})(window.ShadowDOMPolyfill);
+
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+
+  var OriginalSVGUseElement = window.SVGUseElement;
+
+  // IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses
+  // SVGGraphicsElement. Use the <g> element to get the right prototype.
+
+  var SVG_NS = 'http://www.w3.org/2000/svg';
+  var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));
+  var useElement = document.createElementNS(SVG_NS, 'use');
+  var SVGGElement = gWrapper.constructor;
+  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+  var parentInterface = parentInterfacePrototype.constructor;
+
+  function SVGUseElement(impl) {
+    parentInterface.call(this, impl);
+  }
+
+  SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+
+  // Firefox does not expose instanceRoot.
+  if ('instanceRoot' in useElement) {
+    mixin(SVGUseElement.prototype, {
+      get instanceRoot() {
+        return wrap(unwrap(this).instanceRoot);
+      },
+      get animatedInstanceRoot() {
+        return wrap(unwrap(this).animatedInstanceRoot);
+      },
+    });
+  }
+
+  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+
+  scope.wrappers.SVGUseElement = SVGUseElement;
+})(window.ShadowDOMPolyfill);
+
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var EventTarget = scope.wrappers.EventTarget;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var wrap = scope.wrap;
+
+  var OriginalSVGElementInstance = window.SVGElementInstance;
+  if (!OriginalSVGElementInstance)
+    return;
+
+  function SVGElementInstance(impl) {
+    EventTarget.call(this, impl);
+  }
+
+  SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+  mixin(SVGElementInstance.prototype, {
+    /** @type {SVGElement} */
+    get correspondingElement() {
+      return wrap(this.impl.correspondingElement);
+    },
+
+    /** @type {SVGUseElement} */
+    get correspondingUseElement() {
+      return wrap(this.impl.correspondingUseElement);
+    },
+
+    /** @type {SVGElementInstance} */
+    get parentNode() {
+      return wrap(this.impl.parentNode);
+    },
+
+    /** @type {SVGElementInstanceList} */
+    get childNodes() {
+      throw new Error('Not implemented');
+    },
+
+    /** @type {SVGElementInstance} */
+    get firstChild() {
+      return wrap(this.impl.firstChild);
+    },
+
+    /** @type {SVGElementInstance} */
+    get lastChild() {
+      return wrap(this.impl.lastChild);
+    },
+
+    /** @type {SVGElementInstance} */
+    get previousSibling() {
+      return wrap(this.impl.previousSibling);
+    },
+
+    /** @type {SVGElementInstance} */
+    get nextSibling() {
+      return wrap(this.impl.nextSibling);
+    }
+  });
+
+  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+
+  scope.wrappers.SVGElementInstance = SVGElementInstance;
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -4785,6 +5403,9 @@
     },
     intersectsNode: function(node) {
       return this.impl.intersectsNode(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return this.impl.toString();
     }
   };
 
@@ -4819,12 +5440,10 @@
   mixin(DocumentFragment.prototype, SelectorsInterface);
   mixin(DocumentFragment.prototype, GetElementsByInterface);
 
-  var Text = registerObject(document.createTextNode(''));
   var Comment = registerObject(document.createComment(''));
 
   scope.wrappers.Comment = Comment;
   scope.wrappers.DocumentFragment = DocumentFragment;
-  scope.wrappers.Text = Text;
 
 })(window.ShadowDOMPolyfill);
 
@@ -4846,6 +5465,8 @@
   var shadowHostTable = new WeakMap();
   var nextOlderShadowTreeTable = new WeakMap();
 
+  var spaceCharRe = /[ \t\n\r\f]/;
+
   function ShadowRoot(hostWrapper) {
     var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
     DocumentFragment.call(this, node);
@@ -4886,7 +5507,9 @@
     },
 
     getElementById: function(id) {
-      return this.querySelector('#' + id);
+      if (spaceCharRe.test(id))
+        return null;
+      return this.querySelector('[id="' + id + '"]');
     }
   });
 
@@ -5086,10 +5709,18 @@
     if (!(node instanceof Element))
       return false;
 
+    // The native matches function in IE9 does not correctly work with elements
+    // that are not in the document.
+    // TODO(arv): Implement matching in JS.
+    // https://github.com/Polymer/ShadowDOM/issues/361
+    if (select === '*' || select === node.localName)
+      return true;
+
     // TODO(arv): This does not seem right. Need to check for a simple selector.
     if (!selectorMatchRegExp.test(select))
       return false;
 
+    // TODO(arv): This no longer matches the spec.
     if (select[0] === ':' && !allowedPseudoRegExp.test(select))
       return false;
 
@@ -5606,6 +6237,74 @@
 
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+
+  var OriginalSelection = window.Selection;
+
+  function Selection(impl) {
+    this.impl = impl;
+  }
+  Selection.prototype = {
+    get anchorNode() {
+      return wrap(this.impl.anchorNode);
+    },
+    get focusNode() {
+      return wrap(this.impl.focusNode);
+    },
+    addRange: function(range) {
+      this.impl.addRange(unwrap(range));
+    },
+    collapse: function(node, index) {
+      this.impl.collapse(unwrapIfNeeded(node), index);
+    },
+    containsNode: function(node, allowPartial) {
+      return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);
+    },
+    extend: function(node, offset) {
+      this.impl.extend(unwrapIfNeeded(node), offset);
+    },
+    getRangeAt: function(index) {
+      return wrap(this.impl.getRangeAt(index));
+    },
+    removeRange: function(range) {
+      this.impl.removeRange(unwrap(range));
+    },
+    selectAllChildren: function(node) {
+      this.impl.selectAllChildren(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return this.impl.toString();
+    }
+  };
+
+  // WebKit extensions. Not implemented.
+  // readonly attribute Node baseNode;
+  // readonly attribute long baseOffset;
+  // readonly attribute Node extentNode;
+  // readonly attribute long extentOffset;
+  // [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
+  //                       [Default=Undefined] optional long baseOffset,
+  //                       [Default=Undefined] optional Node extentNode,
+  //                       [Default=Undefined] optional long extentOffset);
+  // [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,
+  //                  [Default=Undefined] optional long offset);
+
+  registerWrapper(window.Selection, Selection, window.getSelection());
+
+  scope.wrappers.Selection = Selection;
+
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -5616,14 +6315,17 @@
   var GetElementsByInterface = scope.GetElementsByInterface;
   var Node = scope.wrappers.Node;
   var ParentNodeInterface = scope.ParentNodeInterface;
+  var Selection = scope.wrappers.Selection;
   var SelectorsInterface = scope.SelectorsInterface;
   var ShadowRoot = scope.wrappers.ShadowRoot;
   var defineWrapGetter = scope.defineWrapGetter;
   var elementFromPoint = scope.elementFromPoint;
   var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-  var matchesName = scope.matchesName;
+  var matchesNames = scope.matchesNames;
   var mixin = scope.mixin;
   var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
+  var rewrap = scope.rewrap;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
   var wrapEventTargetMethods = scope.wrapEventTargetMethods;
@@ -5662,7 +6364,7 @@
     'createEventNS',
     'createRange',
     'createTextNode',
-    'getElementById',
+    'getElementById'
   ].forEach(wrapMethod);
 
   var originalAdoptNode = document.adoptNode;
@@ -5689,6 +6391,7 @@
   }
 
   var originalImportNode = document.importNode;
+  var originalGetSelection = document.getSelection;
 
   mixin(Document.prototype, {
     adoptNode: function(node) {
@@ -5710,12 +6413,16 @@
         }
       }
       return clone;
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
     }
   });
 
-  if (document.register) {
-    var originalRegister = document.register;
-    Document.prototype.register = function(tagName, object) {
+  if (document.registerElement) {
+    var originalRegisterElement = document.registerElement;
+    Document.prototype.registerElement = function(tagName, object) {
       var prototype = object.prototype;
 
       // If we already used the object as a prototype for another custom
@@ -5759,14 +6466,19 @@
       // and not from the spec since the spec is out of date.
       [
         'createdCallback',
-        'enteredViewCallback',
-        'leftViewCallback',
+        'attachedCallback',
+        'detachedCallback',
         'attributeChangedCallback',
       ].forEach(function(name) {
         var f = prototype[name];
         if (!f)
           return;
         newPrototype[name] = function() {
+          // if this element has been wrapped prior to registration,
+          // the wrapper is stale; in this case rewrap
+          if (!(wrap(this) instanceof CustomElementConstructor)) {
+            rewrap(this);
+          }
           f.apply(wrap(this), arguments);
         };
       });
@@ -5774,9 +6486,8 @@
       var p = {prototype: newPrototype};
       if (object.extends)
         p.extends = object.extends;
-      var nativeConstructor = originalRegister.call(unwrap(this), tagName, p);
 
-      function GeneratedWrapper(node) {
+      function CustomElementConstructor(node) {
         if (!node) {
           if (object.extends) {
             return document.createElement(object.extends, tagName);
@@ -5786,19 +6497,22 @@
         }
         this.impl = node;
       }
-      GeneratedWrapper.prototype = prototype;
-      GeneratedWrapper.prototype.constructor = GeneratedWrapper;
+      CustomElementConstructor.prototype = prototype;
+      CustomElementConstructor.prototype.constructor = CustomElementConstructor;
 
-      scope.constructorTable.set(newPrototype, GeneratedWrapper);
+      scope.constructorTable.set(newPrototype, CustomElementConstructor);
       scope.nativePrototypeTable.set(prototype, newPrototype);
 
-      return GeneratedWrapper;
+      // registration is synchronous so do it last
+      var nativeConstructor = originalRegisterElement.call(unwrap(this),
+          tagName, p);
+      return CustomElementConstructor;
     };
 
     forwardMethodsToWrapper([
       window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
     ], [
-      'register',
+      'registerElement',
     ]);
   }
 
@@ -5821,8 +6535,7 @@
     'querySelectorAll',
     'removeChild',
     'replaceChild',
-    matchesName,
-  ]);
+  ].concat(matchesNames));
 
   forwardMethodsToWrapper([
     window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
@@ -5840,6 +6553,7 @@
     'createTextNode',
     'elementFromPoint',
     'getElementById',
+    'getSelection',
   ]);
 
   mixin(Document.prototype, GetElementsByInterface);
@@ -5920,40 +6634,56 @@
   'use strict';
 
   var EventTarget = scope.wrappers.EventTarget;
+  var Selection = scope.wrappers.Selection;
   var mixin = scope.mixin;
   var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
   var unwrap = scope.unwrap;
   var unwrapIfNeeded = scope.unwrapIfNeeded;
   var wrap = scope.wrap;
-  var renderAllPending = scope.renderAllPending;
 
   var OriginalWindow = window.Window;
+  var originalGetComputedStyle = window.getComputedStyle;
+  var originalGetSelection = window.getSelection;
 
   function Window(impl) {
     EventTarget.call(this, impl);
   }
   Window.prototype = Object.create(EventTarget.prototype);
 
-  var originalGetComputedStyle = window.getComputedStyle;
   OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
-    renderAllPending();
-    return originalGetComputedStyle.call(this || window, unwrapIfNeeded(el),
-                                         pseudo);
+    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
   };
 
+  OriginalWindow.prototype.getSelection = function() {
+    return wrap(this || window).getSelection();
+  };
+
+  // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
+  delete window.getComputedStyle;
+  delete window.getSelection;
+
   ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
       function(name) {
         OriginalWindow.prototype[name] = function() {
           var w = wrap(this || window);
           return w[name].apply(w, arguments);
         };
+
+        // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
+        delete window[name];
       });
 
   mixin(Window.prototype, {
     getComputedStyle: function(el, pseudo) {
+      renderAllPending();
       return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),
                                            pseudo);
-    }
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
+    },
   });
 
   registerWrapper(OriginalWindow, Window);
@@ -5975,7 +6705,12 @@
   // for.
   var elements = {
     'a': 'HTMLAnchorElement',
-    'applet': 'HTMLAppletElement',
+
+    // Do not create an applet element by default since it shows a warning in
+    // IE.
+    // https://github.com/Polymer/polymer/issues/217
+    // 'applet': 'HTMLAppletElement',
+
     'area': 'HTMLAreaElement',
     'br': 'HTMLBRElement',
     'base': 'HTMLBaseElement',
@@ -6083,6 +6818,10 @@
     }
   });
 
+  // ShadowCSS needs this:
+  window.wrap = window.ShadowDOMPolyfill.wrap;
+  window.unwrap = window.ShadowDOMPolyfill.unwrap;
+
   //TODO(sjmiles): review method alias with Arv
   HTMLElement.prototype.webkitCreateShadowRoot =
       HTMLElement.prototype.createShadowRoot;
@@ -6290,6 +7029,8 @@
 */
 (function(scope) {
 
+var loader = scope.loader;
+
 var ShadowCSS = {
   strictStyling: false,
   registry: {},
@@ -6307,14 +7048,8 @@
     if (this.strictStyling) {
       this.applyScopeToContent(root, name);
     }
-    // insert @polyfill and @polyfill-rule rules into style elements
-    // scoping process takes care of shimming these
-    this.insertPolyfillDirectives(def.rootStyles);
-    this.insertPolyfillRules(def.rootStyles);
-    var cssText = this.stylesToShimmedCssText(def.scopeStyles, name,
-        typeExtension);
-    // note: we only need to do rootStyles since these are unscoped.
-    cssText += this.extractPolyfillUnscopedRules(def.rootStyles);
+    var cssText = this.stylesToShimmedCssText(def.rootStyles, def.scopeStyles,
+        name, typeExtension);
     // provide shimmedStyle for user extensibility
     def.shimmedStyle = cssTextToStyle(cssText);
     if (root) {
@@ -6328,6 +7063,20 @@
     // add style to document
     addCssToDocument(cssText);
   },
+  // apply @polyfill rules + @host and scope shimming
+  stylesToShimmedCssText: function(rootStyles, scopeStyles, name,
+      typeExtension) {
+    name = name || '';
+    // insert @polyfill and @polyfill-rule rules into style elements
+    // scoping process takes care of shimming these
+    this.insertPolyfillDirectives(rootStyles);
+    this.insertPolyfillRules(rootStyles);
+    var cssText = this.shimAtHost(scopeStyles, name, typeExtension) +
+        this.shimScoping(scopeStyles, name, typeExtension);
+    // note: we only need to do rootStyles since these are unscoped.
+    cssText += this.extractPolyfillUnscopedRules(rootStyles);
+    return cssText;
+  },
   registerDefinition: function(root, name, extendsName) {
     var def = this.registry[name] = {
       root: root,
@@ -6446,11 +7195,6 @@
     }
     return r;
   },
-  // apply @host and scope shimming
-  stylesToShimmedCssText: function(styles, name, typeExtension) {
-    return this.shimAtHost(styles, name, typeExtension) +
-        this.shimScoping(styles, name, typeExtension);
-  },
   // form: @host { .foo { declarations } }
   // becomes: scopeName.foo { declarations }
   shimAtHost: function(styles, name, typeExtension) {
@@ -6519,11 +7263,16 @@
     var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
     cssText = this.insertPolyfillHostInCssText(cssText);
     cssText = this.convertColonHost(cssText);
+    cssText = this.convertColonAncestor(cssText);
+    // TODO(sorvell): deprecated, remove
     cssText = this.convertPseudos(cssText);
+    // TODO(sorvell): deprecated, remove
     cssText = this.convertParts(cssText);
     cssText = this.convertCombinators(cssText);
     var rules = cssToRules(cssText);
-    cssText = this.scopeRules(rules, name, typeExtension);
+    if (name) {
+      cssText = this.scopeRules(rules, name, typeExtension);
+    }
     return cssText;
   },
   convertPseudos: function(cssText) {
@@ -6537,29 +7286,40 @@
    *
    * to
    *
+   * scopeName.foo > .bar
+  */
+  convertColonHost: function(cssText) {
+    return this.convertColonRule(cssText, cssColonHostRe,
+        this.colonHostPartReplacer);
+  },
+  /*
+   * convert a rule like :ancestor(.foo) > .bar { }
+   *
+   * to
+   *
    * scopeName.foo > .bar, .foo scopeName > .bar { }
    * 
    * and
    *
-   * :host(.foo:host) .bar { ... }
+   * :ancestor(.foo:host) .bar { ... }
    * 
    * to
    * 
    * scopeName.foo .bar { ... }
   */
-  convertColonHost: function(cssText) {
+  convertColonAncestor: function(cssText) {
+    return this.convertColonRule(cssText, cssColonAncestorRe,
+        this.colonAncestorPartReplacer);
+  },
+  convertColonRule: function(cssText, regExp, partReplacer) {
     // p1 = :host, p2 = contents of (), p3 rest of rule
-    return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
+    return cssText.replace(regExp, function(m, p1, p2, p3) {
       p1 = polyfillHostNoCombinator;
       if (p2) {
         var parts = p2.split(','), r = [];
         for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
           p = p.trim();
-          if (p.match(polyfillHost)) {
-            r.push(p1 + p.replace(polyfillHost, '') + p3);
-          } else {
-            r.push(p1 + p + p3 + ', ' + p + ' ' + p1 + p3);
-          }
+          r.push(partReplacer(p1, p, p3));
         }
         return r.join(',');
       } else {
@@ -6567,6 +7327,16 @@
       }
     });
   },
+  colonAncestorPartReplacer: function(host, part, suffix) {
+    if (part.match(polyfillHost)) {
+      return this.colonHostPartReplacer(host, part, suffix);
+    } else {
+      return host + part + suffix + ', ' + part + ' ' + host + suffix;
+    }
+  },
+  colonHostPartReplacer: function(host, part, suffix) {
+    return host + part.replace(polyfillHost, '') + suffix;
+  },
   /*
    * Convert ^ and ^^ combinators by replacing with space.
   */
@@ -6643,9 +7413,15 @@
   },
   insertPolyfillHostInCssText: function(selector) {
     return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
-        polyfillHost);
+        polyfillHost).replace(colonAncestorRe, polyfillAncestor);
   },
   propertiesFromRule: function(rule) {
+    // TODO(sorvell): Safari cssom incorrectly removes quotes from the content
+    // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
+    if (rule.style.content && !rule.style.content.match(/['"]+/)) {
+      return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' + 
+          rule.style.content + '\';');
+    }
     return rule.style.cssText;
   }
 };
@@ -6662,16 +7438,21 @@
     cssPartRe = /::part\(([^)]*)\)/gim,
     // note: :host pre-processed to -shadowcsshost.
     polyfillHost = '-shadowcsshost',
-    cssColonHostRe = new RegExp('(' + polyfillHost +
-        ')(?:\\((' +
+    // note: :ancestor pre-processed to -shadowcssancestor.
+    polyfillAncestor = '-shadowcssancestor',
+    parenSuffix = ')(?:\\((' +
         '(?:\\([^)(]*\\)|[^)(]*)+?' +
-        ')\\))?([^,{]*)', 'gim'),
+        ')\\))?([^,{]*)';
+    cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),
+    cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim'),
     selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
     hostRe = /@host/gim,
     colonHostRe = /\:host/gim,
+    colonAncestorRe = /\:ancestor/gim,
     /* host name without combinator */
     polyfillHostNoCombinator = polyfillHost + '-no-combinator',
     polyfillHostRe = new RegExp(polyfillHost, 'gim');
+    polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim');
 
 function stylesToCssText(styles, preserveComments) {
   var cssText = '';
@@ -6717,6 +7498,7 @@
   if (!sheet) {
     sheet = document.createElement("style");
     sheet.setAttribute('ShadowCSSShim', '');
+    sheet.shadowCssShim = true;
   }
   return sheet;
 }
@@ -6724,8 +7506,42 @@
 // add polyfill stylesheet to document
 if (window.ShadowDOMPolyfill) {
   addCssToDocument('style { display: none !important; }\n');
-  var head = document.querySelector('head');
+  var doc = wrap(document);
+  var head = doc.querySelector('head');
   head.insertBefore(getSheet(), head.childNodes[0]);
+
+  document.addEventListener('DOMContentLoaded', function() {
+    if (window.HTMLImports && !HTMLImports.useNative) {
+      HTMLImports.importer.preloadSelectors += 
+          ', link[rel=stylesheet]:not([nopolyfill])';
+      HTMLImports.parser.parseGeneric = function(elt) {
+        if (elt.shadowCssShim) {
+          return;
+        }
+        var style = elt;
+        if (!elt.hasAttribute('nopolyfill')) {
+          if (elt.__resource) {
+            style = elt.ownerDocument.createElement('style');
+            style.textContent = Platform.loader.resolveUrlsInCssText(
+                elt.__resource, elt.href);
+            // remove links from main document
+            if (elt.ownerDocument === doc) {
+              elt.parentNode.removeChild(elt);
+            }
+          } else {
+            Platform.loader.resolveUrlsInStyle(style);  
+          }
+          var styles = [style];
+          style.textContent = ShadowCSS.stylesToShimmedCssText(styles, styles);
+          style.shadowCssShim = true;
+        }
+        // place in document
+        if (style.parentNode !== head) {
+          head.appendChild(style);
+        }
+      }
+    }
+  });
 }
 
 // exports
@@ -6790,555 +7606,11 @@
   })();
 }
 
-(function(global) {
-
-  var registrationsTable = new WeakMap();
-
-  // We use setImmediate or postMessage for our future callback.
-  var setImmediate = window.msSetImmediate;
-
-  // Use post message to emulate setImmediate.
-  if (!setImmediate) {
-    var setImmediateQueue = [];
-    var sentinel = String(Math.random());
-    window.addEventListener('message', function(e) {
-      if (e.data === sentinel) {
-        var queue = setImmediateQueue;
-        setImmediateQueue = [];
-        queue.forEach(function(func) {
-          func();
-        });
-      }
-    });
-    setImmediate = function(func) {
-      setImmediateQueue.push(func);
-      window.postMessage(sentinel, '*');
-    };
-  }
-
-  // This is used to ensure that we never schedule 2 callas to setImmediate
-  var isScheduled = false;
-
-  // Keep track of observers that needs to be notified next time.
-  var scheduledObservers = [];
-
-  /**
-   * Schedules |dispatchCallback| to be called in the future.
-   * @param {MutationObserver} observer
-   */
-  function scheduleCallback(observer) {
-    scheduledObservers.push(observer);
-    if (!isScheduled) {
-      isScheduled = true;
-      setImmediate(dispatchCallbacks);
-    }
-  }
-
-  function wrapIfNeeded(node) {
-    return window.ShadowDOMPolyfill &&
-        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
-        node;
-  }
-
-  function dispatchCallbacks() {
-    // http://dom.spec.whatwg.org/#mutation-observers
-
-    isScheduled = false; // Used to allow a new setImmediate call above.
-
-    var observers = scheduledObservers;
-    scheduledObservers = [];
-    // Sort observers based on their creation UID (incremental).
-    observers.sort(function(o1, o2) {
-      return o1.uid_ - o2.uid_;
-    });
-
-    var anyNonEmpty = false;
-    observers.forEach(function(observer) {
-
-      // 2.1, 2.2
-      var queue = observer.takeRecords();
-      // 2.3. Remove all transient registered observers whose observer is mo.
-      removeTransientObserversFor(observer);
-
-      // 2.4
-      if (queue.length) {
-        observer.callback_(queue, observer);
-        anyNonEmpty = true;
-      }
-    });
-
-    // 3.
-    if (anyNonEmpty)
-      dispatchCallbacks();
-  }
-
-  function removeTransientObserversFor(observer) {
-    observer.nodes_.forEach(function(node) {
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        return;
-      registrations.forEach(function(registration) {
-        if (registration.observer === observer)
-          registration.removeTransientObservers();
-      });
-    });
-  }
-
-  /**
-   * This function is used for the "For each registered observer observer (with
-   * observer's options as options) in target's list of registered observers,
-   * run these substeps:" and the "For each ancestor ancestor of target, and for
-   * each registered observer observer (with options options) in ancestor's list
-   * of registered observers, run these substeps:" part of the algorithms. The
-   * |options.subtree| is checked to ensure that the callback is called
-   * correctly.
-   *
-   * @param {Node} target
-   * @param {function(MutationObserverInit):MutationRecord} callback
-   */
-  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
-    for (var node = target; node; node = node.parentNode) {
-      var registrations = registrationsTable.get(node);
-
-      if (registrations) {
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          var options = registration.options;
-
-          // Only target ignores subtree.
-          if (node !== target && !options.subtree)
-            continue;
-
-          var record = callback(options);
-          if (record)
-            registration.enqueue(record);
-        }
-      }
-    }
-  }
-
-  var uidCounter = 0;
-
-  /**
-   * The class that maps to the DOM MutationObserver interface.
-   * @param {Function} callback.
-   * @constructor
-   */
-  function JsMutationObserver(callback) {
-    this.callback_ = callback;
-    this.nodes_ = [];
-    this.records_ = [];
-    this.uid_ = ++uidCounter;
-  }
-
-  JsMutationObserver.prototype = {
-    observe: function(target, options) {
-      target = wrapIfNeeded(target);
-
-      // 1.1
-      if (!options.childList && !options.attributes && !options.characterData ||
-
-          // 1.2
-          options.attributeOldValue && !options.attributes ||
-
-          // 1.3
-          options.attributeFilter && options.attributeFilter.length &&
-              !options.attributes ||
-
-          // 1.4
-          options.characterDataOldValue && !options.characterData) {
-
-        throw new SyntaxError();
-      }
-
-      var registrations = registrationsTable.get(target);
-      if (!registrations)
-        registrationsTable.set(target, registrations = []);
-
-      // 2
-      // If target's list of registered observers already includes a registered
-      // observer associated with the context object, replace that registered
-      // observer's options with options.
-      var registration;
-      for (var i = 0; i < registrations.length; i++) {
-        if (registrations[i].observer === this) {
-          registration = registrations[i];
-          registration.removeListeners();
-          registration.options = options;
-          break;
-        }
-      }
-
-      // 3.
-      // Otherwise, add a new registered observer to target's list of registered
-      // observers with the context object as the observer and options as the
-      // options, and add target to context object's list of nodes on which it
-      // is registered.
-      if (!registration) {
-        registration = new Registration(this, target, options);
-        registrations.push(registration);
-        this.nodes_.push(target);
-      }
-
-      registration.addListeners();
-    },
-
-    disconnect: function() {
-      this.nodes_.forEach(function(node) {
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.observer === this) {
-            registration.removeListeners();
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-      this.records_ = [];
-    },
-
-    takeRecords: function() {
-      var copyOfRecords = this.records_;
-      this.records_ = [];
-      return copyOfRecords;
-    }
-  };
-
-  /**
-   * @param {string} type
-   * @param {Node} target
-   * @constructor
-   */
-  function MutationRecord(type, target) {
-    this.type = type;
-    this.target = target;
-    this.addedNodes = [];
-    this.removedNodes = [];
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this.attributeName = null;
-    this.attributeNamespace = null;
-    this.oldValue = null;
-  }
-
-  function copyMutationRecord(original) {
-    var record = new MutationRecord(original.type, original.target);
-    record.addedNodes = original.addedNodes.slice();
-    record.removedNodes = original.removedNodes.slice();
-    record.previousSibling = original.previousSibling;
-    record.nextSibling = original.nextSibling;
-    record.attributeName = original.attributeName;
-    record.attributeNamespace = original.attributeNamespace;
-    record.oldValue = original.oldValue;
-    return record;
-  };
-
-  // We keep track of the two (possibly one) records used in a single mutation.
-  var currentRecord, recordWithOldValue;
-
-  /**
-   * Creates a record without |oldValue| and caches it as |currentRecord| for
-   * later use.
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecord(type, target) {
-    return currentRecord = new MutationRecord(type, target);
-  }
-
-  /**
-   * Gets or creates a record with |oldValue| based in the |currentRecord|
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecordWithOldValue(oldValue) {
-    if (recordWithOldValue)
-      return recordWithOldValue;
-    recordWithOldValue = copyMutationRecord(currentRecord);
-    recordWithOldValue.oldValue = oldValue;
-    return recordWithOldValue;
-  }
-
-  function clearRecords() {
-    currentRecord = recordWithOldValue = undefined;
-  }
-
-  /**
-   * @param {MutationRecord} record
-   * @return {boolean} Whether the record represents a record from the current
-   * mutation event.
-   */
-  function recordRepresentsCurrentMutation(record) {
-    return record === recordWithOldValue || record === currentRecord;
-  }
-
-  /**
-   * Selects which record, if any, to replace the last record in the queue.
-   * This returns |null| if no record should be replaced.
-   *
-   * @param {MutationRecord} lastRecord
-   * @param {MutationRecord} newRecord
-   * @param {MutationRecord}
-   */
-  function selectRecord(lastRecord, newRecord) {
-    if (lastRecord === newRecord)
-      return lastRecord;
-
-    // Check if the the record we are adding represents the same record. If
-    // so, we keep the one with the oldValue in it.
-    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
-      return recordWithOldValue;
-
-    return null;
-  }
-
-  /**
-   * Class used to represent a registered observer.
-   * @param {MutationObserver} observer
-   * @param {Node} target
-   * @param {MutationObserverInit} options
-   * @constructor
-   */
-  function Registration(observer, target, options) {
-    this.observer = observer;
-    this.target = target;
-    this.options = options;
-    this.transientObservedNodes = [];
-  }
-
-  Registration.prototype = {
-    enqueue: function(record) {
-      var records = this.observer.records_;
-      var length = records.length;
-
-      // There are cases where we replace the last record with the new record.
-      // For example if the record represents the same mutation we need to use
-      // the one with the oldValue. If we get same record (this can happen as we
-      // walk up the tree) we ignore the new record.
-      if (records.length > 0) {
-        var lastRecord = records[length - 1];
-        var recordToReplaceLast = selectRecord(lastRecord, record);
-        if (recordToReplaceLast) {
-          records[length - 1] = recordToReplaceLast;
-          return;
-        }
-      } else {
-        scheduleCallback(this.observer);
-      }
-
-      records[length] = record;
-    },
-
-    addListeners: function() {
-      this.addListeners_(this.target);
-    },
-
-    addListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.addEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.addEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.addEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.addEventListener('DOMNodeRemoved', this, true);
-    },
-
-    removeListeners: function() {
-      this.removeListeners_(this.target);
-    },
-
-    removeListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.removeEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.removeEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.removeEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.removeEventListener('DOMNodeRemoved', this, true);
-    },
-
-    /**
-     * Adds a transient observer on node. The transient observer gets removed
-     * next time we deliver the change records.
-     * @param {Node} node
-     */
-    addTransientObserver: function(node) {
-      // Don't add transient observers on the target itself. We already have all
-      // the required listeners set up on the target.
-      if (node === this.target)
-        return;
-
-      this.addListeners_(node);
-      this.transientObservedNodes.push(node);
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        registrationsTable.set(node, registrations = []);
-
-      // We know that registrations does not contain this because we already
-      // checked if node === this.target.
-      registrations.push(this);
-    },
-
-    removeTransientObservers: function() {
-      var transientObservedNodes = this.transientObservedNodes;
-      this.transientObservedNodes = [];
-
-      transientObservedNodes.forEach(function(node) {
-        // Transient observers are never added to the target.
-        this.removeListeners_(node);
-
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          if (registrations[i] === this) {
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-    },
-
-    handleEvent: function(e) {
-      // Stop propagation since we are managing the propagation manually.
-      // This means that other mutation events on the page will not work
-      // correctly but that is by design.
-      e.stopImmediatePropagation();
-
-      switch (e.type) {
-        case 'DOMAttrModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes
-
-          var name = e.attrName;
-          var namespace = e.relatedNode.namespaceURI;
-          var target = e.target;
-
-          // 1.
-          var record = new getRecord('attributes', target);
-          record.attributeName = name;
-          record.attributeNamespace = namespace;
-
-          // 2.
-          var oldValue =
-              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.attributes)
-              return;
-
-            // 3.2, 4.3
-            if (options.attributeFilter && options.attributeFilter.length &&
-                options.attributeFilter.indexOf(name) === -1 &&
-                options.attributeFilter.indexOf(namespace) === -1) {
-              return;
-            }
-            // 3.3, 4.4
-            if (options.attributeOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.4, 4.5
-            return record;
-          });
-
-          break;
-
-        case 'DOMCharacterDataModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
-          var target = e.target;
-
-          // 1.
-          var record = getRecord('characterData', target);
-
-          // 2.
-          var oldValue = e.prevValue;
-
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.characterData)
-              return;
-
-            // 3.2, 4.3
-            if (options.characterDataOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.3, 4.4
-            return record;
-          });
-
-          break;
-
-        case 'DOMNodeRemoved':
-          this.addTransientObserver(e.target);
-          // Fall through.
-        case 'DOMNodeInserted':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist
-          var target = e.relatedNode;
-          var changedNode = e.target;
-          var addedNodes, removedNodes;
-          if (e.type === 'DOMNodeInserted') {
-            addedNodes = [changedNode];
-            removedNodes = [];
-          } else {
-
-            addedNodes = [];
-            removedNodes = [changedNode];
-          }
-          var previousSibling = changedNode.previousSibling;
-          var nextSibling = changedNode.nextSibling;
-
-          // 1.
-          var record = getRecord('childList', target);
-          record.addedNodes = addedNodes;
-          record.removedNodes = removedNodes;
-          record.previousSibling = previousSibling;
-          record.nextSibling = nextSibling;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 2.1, 3.2
-            if (!options.childList)
-              return;
-
-            // 2.2, 3.3
-            return record;
-          });
-
-      }
-
-      clearRecords();
-    }
-  };
-
-  global.JsMutationObserver = JsMutationObserver;
-
-  // Provide unprefixed MutationObserver with native or JS implementation
-  if (!global.MutationObserver && global.WebKitMutationObserver)
-    global.MutationObserver = global.WebKitMutationObserver;
-
-  if (!global.MutationObserver)
-    global.MutationObserver = JsMutationObserver;
-
-
-})(this);
-
 window.CustomElements = window.CustomElements || {flags:{}};
 (function(scope){

 

 var logFlags = window.logFlags || {};

+var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';

 

 // walk the subtree rooted at node, applying 'find(element, data)' function

 // to each element

@@ -7430,11 +7702,11 @@
 }

 

 

-// TODO(sorvell): on platforms without MutationObserver, mutations may not be

-// reliable and therefore entered/leftView are not reliable.

+// TODO(sorvell): on platforms without MutationObserver, mutations may not be 

+// reliable and therefore attached/detached are not reliable.

 // To make these callbacks less likely to fail, we defer all inserts and removes

-// to give a chance for elements to be inserted into dom.

-// This ensures enteredViewCallback fires for elements that are created and

+// to give a chance for elements to be inserted into dom. 

+// This ensures attachedCallback fires for elements that are created and 

 // immediately added to dom.

 var hasPolyfillMutations = (!window.MutationObserver ||

     (window.MutationObserver === window.JsMutationObserver));

@@ -7483,7 +7755,7 @@
   // TODO(sjmiles): when logging, do work on all custom elements so we can

   // track behavior even when callbacks not defined

   //console.log('inserted: ', element.localName);

-  if (element.enteredViewCallback || (element.__upgraded__ && logFlags.dom)) {

+  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {

     logFlags.dom && console.group('inserted:', element.localName);

     if (inDocument(element)) {

       element.__inserted = (element.__inserted || 0) + 1;

@@ -7495,9 +7767,9 @@
       if (element.__inserted > 1) {

         logFlags.dom && console.warn('inserted:', element.localName,

           'insert/remove count:', element.__inserted)

-      } else if (element.enteredViewCallback) {

+      } else if (element.attachedCallback) {

         logFlags.dom && console.log('inserted:', element.localName);

-        element.enteredViewCallback();

+        element.attachedCallback();

       }

     }

     logFlags.dom && console.groupEnd();

@@ -7524,8 +7796,8 @@
 function _removed(element) {

   // TODO(sjmiles): temporary: do work on all custom elements so we can track

   // behavior even when callbacks not defined

-  if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) {

-    logFlags.dom && console.log('removed:', element.localName);

+  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {

+    logFlags.dom && console.group('removed:', element.localName);

     if (!inDocument(element)) {

       element.__inserted = (element.__inserted || 0) - 1;

       // if we are in a 'inserted' state, bluntly adjust to an 'removed' state

@@ -7536,17 +7808,24 @@
       if (element.__inserted < 0) {

         logFlags.dom && console.warn('removed:', element.localName,

             'insert/remove count:', element.__inserted)

-      } else if (element.leftViewCallback) {

-        element.leftViewCallback();

+      } else if (element.detachedCallback) {

+        element.detachedCallback();

       }

     }

+    logFlags.dom && console.groupEnd();

   }

 }

 

+// SD polyfill intrustion due mainly to the fact that 'document'

+// is not entirely wrapped

+function wrapIfNeeded(node) {

+  return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)

+      : node;

+}

+

 function inDocument(element) {

   var p = element;

-  var doc = window.ShadowDOMPolyfill &&

-      window.ShadowDOMPolyfill.wrapIfNeeded(document) || document;

+  var doc = wrapIfNeeded(document);

   while (p) {

     if (p == doc) {

       return true;

@@ -7630,19 +7909,33 @@
   observer.observe(inRoot, {childList: true, subtree: true});

 }

 

-function observeDocument(document) {

-  observe(document);

+function observeDocument(doc) {

+  observe(doc);

 }

 

-function upgradeDocument(document) {

-  logFlags.dom && console.group('upgradeDocument: ', (document.URL || document._URL || '').split('/').pop());

-  addedNode(document);

+function upgradeDocument(doc) {

+  logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());

+  addedNode(doc);

   logFlags.dom && console.groupEnd();

 }

 

-// exports

+function upgradeDocumentTree(doc) {

+  doc = wrapIfNeeded(doc);

+  upgradeDocument(doc);

+  //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());

+  // upgrade contained imported documents

+  var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');

+  for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {

+    if (n.import && n.import.__parsed) {

+      upgradeDocumentTree(n.import);

+    }

+  }

+}

 

+// exports

+scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;

 scope.watchShadow = watchShadow;

+scope.upgradeDocumentTree = upgradeDocumentTree;

 scope.upgradeAll = addedNode;

 scope.upgradeSubtree = addedSubtree;

 

@@ -7672,10 +7965,15 @@
 }
 var flags = scope.flags;
 
-// native document.register?
+// native document.registerElement?
 
-var hasNative = Boolean(document.register);
-var useNative = !flags.register && hasNative;
+var hasNative = Boolean(document.registerElement);
+// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399
+// we'll address this by defaulting to CE polyfill in the presence of the SD
+// polyfill. This will avoid spamming excess attached/detached callbacks.
+// If there is a compelling need to run CE native with SD polyfill, 
+// we'll need to fix this issue.
+var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;
 
 if (useNative) {
 
@@ -7722,7 +8020,7 @@
    *      element.
    *
    * @example
-   *      FancyButton = document.register("fancy-button", {
+   *      FancyButton = document.registerElement("fancy-button", {
    *        extends: 'button',
    *        prototype: Object.create(HTMLButtonElement.prototype, {
    *          readyCallback: {
@@ -7735,19 +8033,19 @@
    * @return {Function} Constructor for the newly registered type.
    */
   function register(name, options) {
-    //console.warn('document.register("' + name + '", ', options, ')');
+    //console.warn('document.registerElement("' + name + '", ', options, ')');
     // construct a defintion out of options
     // TODO(sjmiles): probably should clone options instead of mutating it
     var definition = options || {};
     if (!name) {
       // TODO(sjmiles): replace with more appropriate error (EricB can probably
       // offer guidance)
-      throw new Error('document.register: first argument `name` must not be empty');
+      throw new Error('document.registerElement: first argument `name` must not be empty');
     }
     if (name.indexOf('-') < 0) {
       // TODO(sjmiles): replace with more appropriate error (EricB can probably
       // offer guidance)
-      throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
+      throw new Error('document.registerElement: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
     }
     // elements may only be registered once
     if (getRegisteredDefinition(name)) {
@@ -7761,7 +8059,7 @@
       throw new Error('Options missing required prototype property');
     }
     // record name
-    definition.name = name.toLowerCase();
+    definition.__name = name.toLowerCase();
     // ensure a lifecycle object so we don't have to null test it
     definition.lifecycle = definition.lifecycle || {};
     // build a list of ancestral custom elements (for native base detection)
@@ -7777,7 +8075,7 @@
     // overrides to implement attributeChanged callback
     overrideAttributeApi(definition.prototype);
     // 7.1.5: Register the DEFINITION with DOCUMENT
-    registerDefinition(definition.name, definition);
+    registerDefinition(definition.__name, definition);
     // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
     // 7.1.8. Return the output of the previous step.
     definition.ctor = generateConstructor(definition);
@@ -7787,7 +8085,7 @@
     // if initial parsing is complete
     if (scope.ready || scope.performedInitialDocumentUpgrade) {
       // upgrade any pre-existing nodes of this type
-      scope.upgradeAll(document);
+      scope.upgradeDocumentTree(document);
     }
     return definition.ctor;
   }
@@ -7810,10 +8108,10 @@
       baseTag = a.is && a.tag;
     }
     // our tag is our baseTag, if it exists, and otherwise just our name
-    definition.tag = baseTag || definition.name;
+    definition.tag = baseTag || definition.__name;
     if (baseTag) {
       // if there is a base tag, use secondary 'is' specifier
-      definition.is = definition.name;
+      definition.is = definition.__name;
     }
   }
 
@@ -8039,7 +8337,7 @@
 
   // exports
 
-  document.register = register;
+  document.registerElement = register;
   document.createElement = createElement; // override
   Node.prototype.cloneNode = cloneNode; // override
 
@@ -8059,16 +8357,19 @@
   scope.upgrade = upgradeElement;
 }
 
+// bc
+document.register = document.registerElement;
+
 scope.hasNative = hasNative;
 scope.useNative = useNative;
 
 })(window.CustomElements);
 
-(function() {
+(function(scope) {
 
 // import
 
-var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
+var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
 
 // highlander object for parsing a document tree
 
@@ -8103,8 +8404,8 @@
     }
   },
   parseImport: function(linkElt) {
-    if (linkElt.content) {
-      parser.parse(linkElt.content);
+    if (linkElt.import) {
+      parser.parse(linkElt.import);
     }
   }
 };
@@ -8118,9 +8419,10 @@
 
 // exports
 
-CustomElements.parser = parser;
+scope.parser = parser;
+scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
 
-})();
+})(window.CustomElements);
 (function(scope){
 
 // bootstrap parsing
@@ -8135,7 +8437,7 @@
     Platform.endOfMicrotask :
     setTimeout;
   async(function() {
-    // set internal 'ready' flag, now document.register will trigger
+    // set internal 'ready' flag, now document.registerElement will trigger 
     // synchronous upgrades
     CustomElements.ready = true;
     // capture blunt profiling data
@@ -8144,7 +8446,7 @@
       CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
     }
     // notify the system that we are bootstrapped
-    document.body.dispatchEvent(
+    document.dispatchEvent(
       new CustomEvent('WebComponentsReady', {bubbles: true})
     );
   });
@@ -8172,8 +8474,9 @@
 // When loading at other readyStates, wait for the appropriate DOM event to
 // bootstrap.
 } else {
-  var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' :
-      document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
+  var loadEvent = window.HTMLImports && !HTMLImports.ready
+      ? 'HTMLImportsLoaded'
+      : document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
   window.addEventListener(loadEvent, bootstrap);
 }
 
@@ -8239,7 +8542,7 @@
 function DartObject(o) {
   this.o = o;
 }
-// Generated by dart2js, the Dart to JavaScript compiler version: 1.2.0-dev.1.0.
+// Generated by dart2js, the Dart to JavaScript compiler version: 1.2.0-dev.5.15.
 (function($){function dart() {}var A=new dart
 delete A.x
 var B=new dart
@@ -8294,19 +8597,20 @@
 init()
 $=I.p
 var $$={}
-;init.mangledNames={gBA:"__$methodCountSelected",gCO:"_oldPieChart",gF0:"__$cls",gGQ:"_newPieDataTable",gGj:"_message",gHX:"__$displayValue",gJ0:"_newPieChart",gKM:"$",gL4:"human",gLE:"timers",gN7:"__$library",gOc:"_oldPieDataTable",gOl:"__$profile",gP:"value",gPe:"__$internal",gPw:"__$isolate",gPy:"__$error",gRd:"line",gSw:"lines",gUy:"_collapsed",gUz:"__$script",gV4:"__$trace",gVa:"__$frame",gX3:"_first",gXR:"scripts",gXh:"__$instance",gYu:"address",gZ0:"codes",gZ6:"locationManager",gZ8:"__$function",ga:"a",gan:"_tableChart",gb:"b",gc:"c",ge6:"_tableDataTable",geE:"__$msg",geJ:"__$code",geb:"__$json",gfb:"methodCounts",ghm:"__$app",gi2:"isolates",giZ:"__$topInclusiveCodes",gk5:"__$devtools",gkf:"_count",glw:"requestManager",gm0:"__$instruction",gm7:"machine",gnI:"isolateManager",gqY:"__$topExclusiveCodes",grK:"__$links",gtY:"__$ref",gvH:"index",gva:"instructions",gvt:"__$field",gzh:"__$iconClass"};init.mangledGlobalNames={BO:"ALLOCATED_BEFORE_GC",DI:"_closeIconClass",Hg:"ALLOCATED_BEFORE_GC_SIZE",V1g:"LIVE_AFTER_GC_SIZE",Vl:"_openIconClass",d6:"ALLOCATED_SINCE_GC_SIZE",jr:"ALLOCATED_SINCE_GC",xK:"LIVE_AFTER_GC"};(function (reflectionData) {
+;init.mangledNames={gBA:"__$methodCountSelected",gBW:"__$msg",gCO:"_oldPieChart",gDF:"requestManager",gF0:"__$cls",gF8:"__$instruction",gGQ:"_newPieDataTable",gGj:"_message",gHX:"__$displayValue",gHm:"tree",gJ0:"_newPieChart",gKM:"$",gL4:"human",gLE:"timers",gMt:"__$expanded",gN7:"__$library",gOc:"_oldPieDataTable",gOl:"__$profile",gP:"value",gPe:"__$internal",gPw:"__$isolate",gPy:"__$error",gRd:"line",gSw:"lines",gUy:"_collapsed",gUz:"__$script",gV4:"__$trace",gVa:"__$frame",gWT:"rows",gX3:"_first",gXR:"scripts",gXh:"__$instance",gYu:"address",gZ0:"codes",gZ6:"locationManager",gZ8:"__$function",ga:"a",gan:"_tableChart",gb:"b",gc:"c",ge6:"_tableDataTable",geJ:"__$code",geb:"__$json",gfb:"methodCounts",ghm:"__$app",gi2:"isolates",gk5:"__$devtools",gkf:"_count",gm0:"__$isolate",gm7:"machine",gnI:"isolateManager",goH:"columns",gqO:"_id",gqX:"__$expanded",gqY:"__$topExclusiveCodes",grK:"__$links",gtT:"code",gtY:"__$ref",gvH:"index",gva:"instructions",gvt:"__$field",gwd:"children",gyt:"depth",gzh:"__$iconClass",gzw:"__$line"};init.mangledGlobalNames={BO:"ALLOCATED_BEFORE_GC",DI:"_closeIconClass",V1g:"LIVE_AFTER_GC_SIZE",Vl:"_openIconClass",Xa:"ALLOCATED_BEFORE_GC_SIZE",d6:"ALLOCATED_SINCE_GC_SIZE",r1K:"ALLOCATED_SINCE_GC",xK:"LIVE_AFTER_GC"};(function (reflectionData) {
   "use strict";
   function map(x){x={x:x};delete x.x;return x}
     function processStatics(descriptor) {
       for (var property in descriptor) {
         if (!hasOwnProperty.call(descriptor, property)) continue;
-        if (property === "") continue;
+        if (property === "^") continue;
         var element = descriptor[property];
         var firstChar = property.substring(0, 1);
         var previousProperty;
         if (firstChar === "+") {
           mangledGlobalNames[previousProperty] = property.substring(1);
-          if (descriptor[property] == 1) descriptor[previousProperty].$reflectable = 1;
+          var flag = descriptor[property];
+          if (flag > 0) descriptor[previousProperty].$reflectable = flag;
           if (element && element.length) init.typeInformation[previousProperty] = element;
         } else if (firstChar === "@") {
           property = property.substring(1);
@@ -8335,7 +8639,8 @@
               processStatics(init.statics[property] = element[prop]);
             } else if (firstChar === "+") {
               mangledNames[previousProp] = prop.substring(1);
-              if (element[prop] == 1) element[previousProp].$reflectable = 1;
+              var flag = element[prop];
+              if (flag > 0) element[previousProp].$reflectable = flag;
             } else if (firstChar === "@" && prop !== "@") {
               newDesc[prop.substring(1)]["@"] = element[prop];
             } else if (firstChar === "*") {
@@ -8347,7 +8652,7 @@
               optionalMethods[prop] = previousProp;
             } else {
               var elem = element[prop];
-              if (prop && elem != null && elem.constructor === Array && prop !== "<>") {
+              if (prop !== "^" && elem != null && elem.constructor === Array && prop !== "<>") {
                 addStubs(newDesc, elem, prop, false, element, []);
               } else {
                 newDesc[previousProp = prop] = elem;
@@ -8360,29 +8665,13 @@
       }
     }
   function addStubs(descriptor, array, name, isStatic, originalDescriptor, functions) {
-    var f, funcs = [originalDescriptor[name] = descriptor[name] = f = (function() {
-  var result = array[0];
-  if (result != null && typeof result != "function") {
-    throw new Error(
-        name + ": expected value of type 'function' at index " + (0) +
-        " but got " + (typeof result));
-  }
-  return result;
-})()];
+    var f, funcs = [originalDescriptor[name] = descriptor[name] = f = array[0]];
     f.$stubName = name;
     functions.push(name);
     for (var index = 0; index < array.length; index += 2) {
       f = array[index + 1];
       if (typeof f != "function") break;
-      f.$stubName = (function() {
-  var result = array[index + 2];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (index + 2) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      f.$stubName = array[index + 2];
       funcs.push(f);
       if (f.$stubName) {
         originalDescriptor[f.$stubName] = descriptor[f.$stubName] = f;
@@ -8390,61 +8679,21 @@
       }
     }
     for (var i = 0; i < funcs.length; index++, i++) {
-      funcs[i].$callName = (function() {
-  var result = array[index + 1];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (index + 1) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      funcs[i].$callName = array[index + 1];
     }
-    var getterStubName = (function() {
-  var result = array[++index];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (++index) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var getterStubName = array[++index];
     array = array.slice(++index);
-    var requiredParameterInfo = (function() {
-  var result = array[0];
-  if (result != null && (typeof result != "number" || (result|0) !== result)) {
-    throw new Error(
-        name + ": expected value of type 'int' at index " + (0) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var requiredParameterInfo = array[0];
     var requiredParameterCount = requiredParameterInfo >> 1;
     var isAccessor = (requiredParameterInfo & 1) === 1;
     var isSetter = requiredParameterInfo === 3;
     var isGetter = requiredParameterInfo === 1;
-    var optionalParameterInfo = (function() {
-  var result = array[1];
-  if (result != null && (typeof result != "number" || (result|0) !== result)) {
-    throw new Error(
-        name + ": expected value of type 'int' at index " + (1) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var optionalParameterInfo = array[1];
     var optionalParameterCount = optionalParameterInfo >> 1;
     var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
     var isIntercepted = requiredParameterCount + optionalParameterCount != funcs[0].length;
-    var functionTypeIndex = (function() {
-  var result = array[2];
-  if (result != null && (typeof result != "number" || (result|0) !== result) && typeof result != "function") {
-    throw new Error(
-        name + ": expected value of type 'function or int' at index " + (2) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
-    var isReflectable = array.length > requiredParameterCount + optionalParameterCount + 3;
+    var functionTypeIndex = array[2];
+    var isReflectable = array.length > 3 * optionalParameterCount + 2 * requiredParameterCount + 3
     if (getterStubName) {
       f = tearOff(funcs, array, isStatic, name, isIntercepted);
       if (isStatic) init.globalFunctions[name] = f;
@@ -8461,16 +8710,8 @@
       }
     }
     if (isReflectable) {
-      var unmangledNameIndex = optionalParameterCount * 2 + requiredParameterCount + 3;
-      var unmangledName = (function() {
-  var result = array[unmangledNameIndex];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (unmangledNameIndex) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      var unmangledNameIndex = 3 * optionalParameterCount + 2 * requiredParameterCount + 3;
+      var unmangledName = array[unmangledNameIndex];
       var reflectionName = unmangledName + ":" + requiredParameterCount + ":" + optionalParameterCount;
       if (isGetter) {
         reflectionName = unmangledName;
@@ -8491,13 +8732,13 @@
     return isIntercepted
         ? new Function("funcs", "reflectionInfo", "name", "H", "c",
             "return function tearOff_" + name + (functionCounter++)+ "(x) {" +
-              "if (c === null) c = H.qm(" +
+              "if (c === null) c = H.Kq(" +
                   "this, funcs, reflectionInfo, false, [x], name);" +
               "return new c(this, funcs[0], x, name);" +
             "}")(funcs, reflectionInfo, name, H, null)
         : new Function("funcs", "reflectionInfo", "name", "H", "c",
             "return function tearOff_" + name + (functionCounter++)+ "() {" +
-              "if (c === null) c = H.qm(" +
+              "if (c === null) c = H.Kq(" +
                   "this, funcs, reflectionInfo, false, [], name);" +
               "return new c(this, funcs[0], null, name);" +
             "}")(funcs, reflectionInfo, name, H, null)
@@ -8506,11 +8747,11 @@
     var cache = null;
     return isIntercepted
         ? function(x) {
-            if (cache === null) cache = H.qm(this, funcs, reflectionInfo, false, [x], name);
+            if (cache === null) cache = H.Kq(this, funcs, reflectionInfo, false, [x], name);
             return new cache(this, funcs[0], x, name)
           }
         : function() {
-            if (cache === null) cache = H.qm(this, funcs, reflectionInfo, false, [], name);
+            if (cache === null) cache = H.Kq(this, funcs, reflectionInfo, false, [], name);
             return new cache(this, funcs[0], null, name)
           }
   }
@@ -8518,7 +8759,7 @@
     var cache;
     return isStatic
         ? function() {
-            if (cache === void 0) cache = H.qm(this, funcs, reflectionInfo, true, [], name).prototype;
+            if (cache === void 0) cache = H.Kq(this, funcs, reflectionInfo, true, [], name).prototype;
             return cache;
           }
         : tearOffGetter(funcs, reflectionInfo, name, isIntercepted);
@@ -8545,7 +8786,7 @@
     var globalObject = data[3];
     var descriptor = data[4];
     var isRoot = !!data[5];
-    var fields = descriptor && descriptor[""];
+    var fields = descriptor && descriptor["^"];
     var classes = [];
     var functions = [];
     processStatics(descriptor);
@@ -8554,12 +8795,12 @@
   }
 })
 ([["_foreign_helper","dart:_foreign_helper",,H,{
-"":"",
+"^":"",
 Lt:{
-"":"a;tT>"}}],["_interceptors","dart:_interceptors",,J,{
-"":"",
-x:[function(a){return void 0},"call$1","DK",2,0,null,6],
-Qu:[function(a,b,c,d){return{i: a, p: b, e: c, x: d}},"call$4","yC",8,0,null,7,8,9,10],
+"^":"a;tT>"}}],["_interceptors","dart:_interceptors",,J,{
+"^":"",
+x:[function(a){return void 0},"call$1","DK",2,0,null,6,[]],
+Qu:[function(a,b,c,d){return{i: a, p: b, e: c, x: d}},"call$4","yC",8,0,null,7,[],8,[],9,[],10,[]],
 ks:[function(a){var z,y,x,w
 z=a[init.dispatchPropertyName]
 if(z==null)if($.Bv==null){H.XD()
@@ -8570,96 +8811,96 @@
 if(y===x)return z.i
 if(z.e===x)throw H.b(P.SY("Return interceptor for "+H.d(y(a,z))))}w=H.w3(a)
 if(w==null)return C.vB
-return w},"call$1","Fd",2,0,null,6],
+return w},"call$1","mz",2,0,null,6,[]],
 e1:[function(a){var z,y,x,w
 z=$.Au
 if(z==null)return
 y=z
 for(z=y.length,x=J.x(a),w=0;w+1<z;w+=3){if(w>=z)return H.e(y,w)
-if(x.n(a,y[w]))return w}return},"call$1","kC",2,0,null,11],
-Fb:[function(a){var z,y,x
+if(x.n(a,y[w]))return w}return},"call$1","kC",2,0,null,11,[]],
+Xr:[function(a){var z,y,x
 z=J.e1(a)
 if(z==null)return
 y=$.Au
 if(typeof z!=="number")return z.g()
 x=z+1
 if(x>=y.length)return H.e(y,x)
-return y[x]},"call$1","d2",2,0,null,11],
-Dp:[function(a,b){var z,y,x
+return y[x]},"call$1","Tj",2,0,null,11,[]],
+Nq:[function(a,b){var z,y,x
 z=J.e1(a)
 if(z==null)return
 y=$.Au
 if(typeof z!=="number")return z.g()
 x=z+2
 if(x>=y.length)return H.e(y,x)
-return y[x][b]},"call$2","nc",4,0,null,11,12],
+return y[x][b]},"call$2","BJ",4,0,null,11,[],12,[]],
 Gv:{
-"":"a;",
-n:[function(a,b){return a===b},"call$1","gUJ",2,0,null,104],
+"^":"a;",
+n:[function(a,b){return a===b},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return H.eQ(a)},
 bu:[function(a){return H.a5(a)},"call$0","gXo",0,0,null],
-T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,332],
+T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,326,[]],
 gbx:function(a){return new H.cu(H.dJ(a),null)},
 $isGv:true,
 "%":"DOMImplementation|SVGAnimatedEnumeration|SVGAnimatedNumberList|SVGAnimatedString"},
 kn:{
-"":"bool/Gv;",
+"^":"bool/Gv;",
 bu:[function(a){return String(a)},"call$0","gXo",0,0,null],
 giO:function(a){return a?519018:218159},
 gbx:function(a){return C.HL},
 $isbool:true},
-PE:{
-"":"Gv;",
-n:[function(a,b){return null==b},"call$1","gUJ",2,0,null,104],
+ht:{
+"^":"Null/Gv;",
+n:[function(a,b){return null==b},"call$1","gUJ",2,0,null,104,[]],
 bu:[function(a){return"null"},"call$0","gXo",0,0,null],
 giO:function(a){return 0},
 gbx:function(a){return C.Qf}},
 QI:{
-"":"Gv;",
+"^":"Gv;",
 giO:function(a){return 0},
 gbx:function(a){return C.CS}},
 FP:{
-"":"QI;"},
+"^":"QI;"},
 is:{
-"":"QI;"},
+"^":"QI;"},
 Q:{
-"":"List/Gv;",
+"^":"List/Gv;",
 h:[function(a,b){if(!!a.fixed$length)H.vh(P.f("add"))
-a.push(b)},"call$1","ght",2,0,null,23],
+a.push(b)},"call$1","ght",2,0,null,23,[]],
+KI:[function(a,b){if(b<0||b>=a.length)throw H.b(new P.bJ("value "+b))
+if(!!a.fixed$length)H.vh(P.f("removeAt"))
+return a.splice(b,1)[0]},"call$1","gNM",2,0,null,47,[]],
 xe:[function(a,b,c){if(b<0||b>a.length)throw H.b(new P.bJ("value "+b))
 if(!!a.fixed$length)H.vh(P.f("insert"))
-a.splice(b,0,c)},"call$2","gQG",4,0,null,47,23],
-mv:[function(a){if(!!a.fixed$length)H.vh(P.f("removeLast"))
-if(a.length===0)throw H.b(new P.bJ("value -1"))
-return a.pop()},"call$0","gdc",0,0,null],
+a.splice(b,0,c)},"call$2","gQG",4,0,null,47,[],23,[]],
 Rz:[function(a,b){var z
 if(!!a.fixed$length)H.vh(P.f("remove"))
 for(z=0;z<a.length;++z)if(J.de(a[z],b)){a.splice(z,1)
-return!0}return!1},"call$1","gRI",2,0,null,124],
-ev:[function(a,b){return H.VM(new H.U5(a,b),[null])},"call$1","gIR",2,0,null,110],
+return!0}return!1},"call$1","gRI",2,0,null,124,[]],
+ev:[function(a,b){return H.VM(new H.U5(a,b),[null])},"call$1","gIR",2,0,null,110,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(a,z.gl())},"call$1","gDY",2,0,null,333],
+for(z=J.GP(b);z.G();)this.h(a,z.gl())},"call$1","gDY",2,0,null,327,[]],
 V1:[function(a){this.sB(a,0)},"call$0","gyP",0,0,null],
-aN:[function(a,b){return H.bQ(a,b)},"call$1","gjw",2,0,null,110],
-ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110],
+aN:[function(a,b){return H.bQ(a,b)},"call$1","gjw",2,0,null,110,[]],
+ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
 zV:[function(a,b){var z,y,x,w
 z=a.length
 y=Array(z)
 y.fixed$length=init
 for(x=0;x<a.length;++x){w=H.d(a[x])
 if(x>=z)return H.e(y,x)
-y[x]=w}return y.join(b)},"call$1","gnr",0,2,null,334,335],
-eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gVQ",2,0,null,292],
+y[x]=w}return y.join(b)},"call$1","gnr",0,2,null,328,329,[]],
+eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gZo",2,0,null,287,[]],
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 D6:[function(a,b,c){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b<0||b>a.length)throw H.b(P.TE(b,0,a.length))
 if(c==null)c=a.length
 else{if(typeof c!=="number"||Math.floor(c)!==c)throw H.b(new P.AT(c))
 if(c<b||c>a.length)throw H.b(P.TE(c,b,a.length))}if(b===c)return H.VM([],[H.Kp(a,0)])
-return H.VM(a.slice(b,c),[H.Kp(a,0)])},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
-Mu:[function(a,b,c){H.S6(a,b,c)
-return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,116],
+return H.VM(a.slice(b,c),[H.Kp(a,0)])},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+Mu:[function(a,b,c){H.K0(a,b,c)
+return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,[],116,[]],
 gtH:function(a){if(a.length>0)return a[0]
 throw H.b(new P.lj("No elements"))},
 grZ:function(a){var z=a.length
@@ -8673,17 +8914,17 @@
 y=J.Wx(c)
 if(y.C(c,b)||y.D(c,z))throw H.b(P.TE(c,b,z))
 if(typeof c!=="number")return H.s(c)
-H.Gj(a,c,a,b,z-c)
+H.tb(a,c,a,b,z-c)
 if(typeof b!=="number")return H.s(b)
-this.sB(a,z-(c-b))},"call$2","gYH",4,0,null,115,116],
-Vr:[function(a,b){return H.Ck(a,b)},"call$1","gG2",2,0,null,110],
-So:[function(a,b){if(!!a.immutable$list)H.vh(P.f("sort"))
-H.ZE(a,0,a.length-1,b)},"call$1","gH7",0,2,null,77,128],
-XU:[function(a,b,c){return H.Ri(a,b,c,a.length)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,124,115],
-Pk:[function(a,b,c){return H.lO(a,b,a.length-1)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,124,115],
+this.sB(a,z-(c-b))},"call$2","gYH",4,0,null,115,[],116,[]],
+Vr:[function(a,b){return H.Ck(a,b)},"call$1","gG2",2,0,null,110,[]],
+GT:[function(a,b){if(!!a.immutable$list)H.vh(P.f("sort"))
+H.ZE(a,0,a.length-1,b)},"call$1","gH7",0,2,null,77,128,[]],
+XU:[function(a,b,c){return H.TK(a,b,c,a.length)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],115,[]],
+Pk:[function(a,b,c){return H.eX(a,b,a.length-1)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],115,[]],
 tg:[function(a,b){var z
 for(z=0;z<a.length;++z)if(J.de(a[z],b))return!0
-return!1},"call$1","gdj",2,0,null,104],
+return!1},"call$1","gdj",2,0,null,104,[]],
 gl0:function(a){return a.length===0},
 gor:function(a){return a.length!==0},
 bu:[function(a){return H.mx(a,"[","]")},"call$0","gXo",0,0,null],
@@ -8691,7 +8932,7 @@
 if(b)return H.VM(a.slice(),[H.Kp(a,0)])
 else{z=H.VM(a.slice(),[H.Kp(a,0)])
 z.fixed$length=init
-return z}},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+return z}},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 gA:function(a){return H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)])},
 giO:function(a){return H.eQ(a)},
 gB:function(a){return a.length},
@@ -8701,11 +8942,11 @@
 a.length=b},
 t:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b>=a.length||b<0)throw H.b(P.N(b))
-return a[b]},"call$1","gIA",2,0,null,47],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){if(!!a.immutable$list)H.vh(P.f("indexed set"))
 if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
-if(b>=a.length||b<0)throw H.b(P.N(b))
-a[b]=c},"call$2","gj3",4,0,null,47,23],
+if(b>=a.length||b<0)throw H.b(new P.bJ("value "+H.d(b)))
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
 $isList:true,
 $isList:true,
 $asWO:null,
@@ -8717,16 +8958,16 @@
 z=H.VM(new Array(a),[b])
 z.fixed$length=init
 return z}}},
-NK:{
-"":"Q;",
-$isNK:true},
+nM:{
+"^":"Q;",
+$isnM:true},
 ZC:{
-"":"NK;"},
+"^":"nM;"},
 Jt:{
-"":"NK;",
+"^":"nM;",
 $isJt:true},
 P:{
-"":"num/Gv;",
+"^":"num/Gv;",
 iM:[function(a,b){var z
 if(typeof b!=="number")throw H.b(new P.AT(b))
 if(a<b)return-1
@@ -8735,11 +8976,11 @@
 if(this.gzP(a)===z)return 0
 if(this.gzP(a))return-1
 return 1}return 0}else if(isNaN(a)){if(this.gG0(b))return 0
-return 1}else return-1},"call$1","gYc",2,0,null,180],
+return 1}else return-1},"call$1","gYc",2,0,null,180,[]],
 gzP:function(a){return a===0?1/a<0:a<0},
 gG0:function(a){return isNaN(a)},
 gx8:function(a){return isFinite(a)},
-JV:[function(a,b){return a%b},"call$1","gKG",2,0,null,180],
+JV:[function(a,b){return a%b},"call$1","gKG",2,0,null,180,[]],
 yu:[function(a){var z
 if(a>=-2147483648&&a<=2147483647)return a|0
 if(isFinite(a)){z=a<0?Math.ceil(a):Math.floor(a)
@@ -8751,77 +8992,79 @@
 if(b>20)throw H.b(P.C3(b))
 z=a.toFixed(b)
 if(a===0&&this.gzP(a))return"-"+z
-return z},"call$1","gfE",2,0,null,339],
+return z},"call$1","gfE",2,0,null,333,[]],
 WZ:[function(a,b){if(b<2||b>36)throw H.b(P.C3(b))
-return a.toString(b)},"call$1","gEI",2,0,null,28],
+return a.toString(b)},"call$1","gEI",2,0,null,28,[]],
 bu:[function(a){if(a===0&&1/a<0)return"-0.0"
 else return""+a},"call$0","gXo",0,0,null],
 giO:function(a){return a&0x1FFFFFFF},
 J:[function(a){return-a},"call$0","gVd",0,0,null],
 g:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a+b},"call$1","gF1n",2,0,null,104],
+return a+b},"call$1","gF1n",2,0,null,104,[]],
 W:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a-b},"call$1","gTG",2,0,null,104],
+return a-b},"call$1","gTG",2,0,null,104,[]],
 V:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a/b},"call$1","gJj",2,0,null,104],
+return a/b},"call$1","gJj",2,0,null,104,[]],
 U:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a*b},"call$1","gEH",2,0,null,104],
+return a*b},"call$1","gEH",2,0,null,104,[]],
 Y:[function(a,b){var z=a%b
 if(z===0)return 0
 if(z>0)return z
 if(b<0)return z-b
-else return z+b},"call$1","gQR",2,0,null,104],
+else return z+b},"call$1","gQR",2,0,null,104,[]],
 Z:[function(a,b){if((a|0)===a&&(b|0)===b&&0!==b&&-1!==b)return a/b|0
-else return this.yu(a/b)},"call$1","gdG",2,0,null,104],
-cU:[function(a,b){return(a|0)===a?a/b|0:this.yu(a/b)},"call$1","gPf",2,0,null,104],
+else return this.yu(a/b)},"call$1","gdG",2,0,null,104,[]],
+cU:[function(a,b){return(a|0)===a?a/b|0:this.yu(a/b)},"call$1","gPf",2,0,null,104,[]],
 O:[function(a,b){if(b<0)throw H.b(new P.AT(b))
-return b>31?0:a<<b>>>0},"call$1","gq8",2,0,null,104],
-W4:[function(a,b){return b>31?0:a<<b>>>0},"call$1","gGu",2,0,null,104],
+return b>31?0:a<<b>>>0},"call$1","gq8",2,0,null,104,[]],
+W4:[function(a,b){return b>31?0:a<<b>>>0},"call$1","gGu",2,0,null,104,[]],
 m:[function(a,b){var z
 if(b<0)throw H.b(new P.AT(b))
 if(a>0)z=b>31?0:a>>>b
 else{z=b>31?31:b
-z=a>>z>>>0}return z},"call$1","gyp",2,0,null,104],
+z=a>>z>>>0}return z},"call$1","gyp",2,0,null,104,[]],
 GG:[function(a,b){var z
 if(a>0)z=b>31?0:a>>>b
 else{z=b>31?31:b
-z=a>>z>>>0}return z},"call$1","gMe",2,0,null,104],
+z=a>>z>>>0}return z},"call$1","gMe",2,0,null,104,[]],
 i:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return(a&b)>>>0},"call$1","gAp",2,0,null,104],
+return(a&b)>>>0},"call$1","gAp",2,0,null,104,[]],
+w:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
+return(a^b)>>>0},"call$1","gttE",2,0,null,104,[]],
 C:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a<b},"call$1","gix",2,0,null,104],
+return a<b},"call$1","gix",2,0,null,104,[]],
 D:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a>b},"call$1","gh1",2,0,null,104],
+return a>b},"call$1","gh1",2,0,null,104,[]],
 E:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a<=b},"call$1","gf5",2,0,null,104],
+return a<=b},"call$1","gf5",2,0,null,104,[]],
 F:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a>=b},"call$1","gNH",2,0,null,104],
+return a>=b},"call$1","gNH",2,0,null,104,[]],
 $isnum:true,
-static:{"":"xr,LN"}},
+static:{"^":"zc,LN"}},
 im:{
-"":"int/P;",
+"^":"int/P;",
 gbx:function(a){return C.yw},
 $isdouble:true,
 $isnum:true,
 $isint:true},
 GW:{
-"":"double/P;",
+"^":"double/P;",
 gbx:function(a){return C.O4},
 $isdouble:true,
 $isnum:true},
 vT:{
-"":"im;"},
+"^":"im;"},
 VP:{
-"":"vT;"},
+"^":"vT;"},
 BQ:{
-"":"VP;"},
+"^":"VP;"},
 O:{
-"":"String/Gv;",
+"^":"String/Gv;",
 j:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(P.u(b))
 if(b<0)throw H.b(P.N(b))
 if(b>=a.length)throw H.b(P.N(b))
-return a.charCodeAt(b)},"call$1","gSu",2,0,null,47],
-dd:[function(a,b){return H.ZT(a,b)},"call$1","gYv",2,0,null,340],
+return a.charCodeAt(b)},"call$1","gSu",2,0,null,47,[]],
+dd:[function(a,b){return H.ZT(a,b)},"call$1","gYv",2,0,null,334,[]],
 wL:[function(a,b,c){var z,y,x,w
 if(c<0||c>b.length)throw H.b(P.TE(c,0,b.length))
 z=a.length
@@ -8832,21 +9075,21 @@
 if(w>=y)H.vh(P.N(w))
 w=b.charCodeAt(w)
 if(x>=z)H.vh(P.N(x))
-if(w!==a.charCodeAt(x))return}return new H.tQ(c,b,a)},"call$2","grS",2,2,null,336,26,115],
+if(w!==a.charCodeAt(x))return}return new H.tQ(c,b,a)},"call$2","grS",2,2,null,330,26,[],115,[]],
 g:[function(a,b){if(typeof b!=="string")throw H.b(new P.AT(b))
-return a+b},"call$1","gF1n",2,0,null,104],
+return a+b},"call$1","gF1n",2,0,null,104,[]],
 Tc:[function(a,b){var z,y
 z=b.length
 y=a.length
 if(z>y)return!1
-return b===this.yn(a,y-z)},"call$1","gvi",2,0,null,104],
-h8:[function(a,b,c){return H.ys(a,b,c)},"call$2","gpd",4,0,null,105,106],
-Fr:[function(a,b){return a.split(b)},"call$1","gOG",2,0,null,98],
+return b===this.yn(a,y-z)},"call$1","gvi",2,0,null,104,[]],
+h8:[function(a,b,c){return H.ys(a,b,c)},"call$2","gpd",4,0,null,105,[],106,[]],
+Fr:[function(a,b){return a.split(b)},"call$1","gOG",2,0,null,98,[]],
 Qi:[function(a,b,c){var z
 if(c>a.length)throw H.b(P.TE(c,0,a.length))
 if(typeof b==="string"){z=c+b.length
 if(z>a.length)return!1
-return b===a.substring(c,z)}return J.I8(b,a,c)!=null},function(a,b){return this.Qi(a,b,0)},"nC","call$2",null,"gcV",2,2,null,336,98,47],
+return b===a.substring(c,z)}return J.I8(b,a,c)!=null},function(a,b){return this.Qi(a,b,0)},"nC","call$2",null,"gcV",2,2,null,330,98,[],47,[]],
 Nj:[function(a,b,c){var z
 if(typeof b!=="number"||Math.floor(b)!==b)H.vh(P.u(b))
 if(c==null)c=a.length
@@ -8855,7 +9098,7 @@
 if(z.C(b,0))throw H.b(P.N(b))
 if(z.D(b,c))throw H.b(P.N(b))
 if(J.z8(c,a.length))throw H.b(P.N(c))
-return a.substring(b,c)},function(a,b){return this.Nj(a,b,null)},"yn","call$2",null,"gKj",2,2,null,77,80,125],
+return a.substring(b,c)},function(a,b){return this.Nj(a,b,null)},"yn","call$2",null,"gKj",2,2,null,77,80,[],125,[]],
 hc:[function(a){return a.toLowerCase()},"call$0","gCW",0,0,null],
 bS:[function(a){var z,y,x,w,v
 for(z=a.length,y=0;y<z;){if(y>=z)H.vh(P.N(y))
@@ -8868,9 +9111,14 @@
 x=a.charCodeAt(v)
 if(x===32||x===13||J.Ga(x));else break}if(y===0&&w===z)return a
 return a.substring(y,w)},"call$0","gZH",0,0,null],
-gZm:function(a){return new J.Qe(a)},
-XU:[function(a,b,c){if(c<0||c>a.length)throw H.b(P.TE(c,0,a.length))
-return a.indexOf(b,c)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,98,115],
+XU:[function(a,b,c){var z,y,x,w
+if(b==null)H.vh(new P.AT(null))
+if(c<0||c>a.length)throw H.b(P.TE(c,0,a.length))
+if(typeof b==="string")return a.indexOf(b,c)
+z=J.rY(b)
+if(typeof b==="object"&&b!==null&&!!z.$isVR){y=b.yk(a,c)
+return y==null?-1:y.QK.index}for(x=a.length,w=c;w<=x;++w)if(z.wL(b,a,w)!=null)return w
+return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,98,[],115,[]],
 Pk:[function(a,b,c){var z,y,x
 c=a.length
 if(typeof b==="string"){z=b.length
@@ -8881,17 +9129,17 @@
 x=c
 while(!0){if(typeof x!=="number")return x.F()
 if(!(x>=0))break
-if(z.wL(b,a,x)!=null)return x;--x}return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,98,115],
+if(z.wL(b,a,x)!=null)return x;--x}return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,98,[],115,[]],
 Is:[function(a,b,c){if(b==null)H.vh(new P.AT(null))
 if(c>a.length)throw H.b(P.TE(c,0,a.length))
-return H.m2(a,b,c)},function(a,b){return this.Is(a,b,0)},"tg","call$2",null,"gdj",2,2,null,336,104,80],
+return H.m2(a,b,c)},function(a,b){return this.Is(a,b,0)},"tg","call$2",null,"gdj",2,2,null,330,104,[],80,[]],
 gl0:function(a){return a.length===0},
 gor:function(a){return a.length!==0},
 iM:[function(a,b){var z
 if(typeof b!=="string")throw H.b(new P.AT(b))
 if(a===b)z=0
 else z=a<b?-1:1
-return z},"call$1","gYc",2,0,null,104],
+return z},"call$1","gYc",2,0,null,104,[]],
 bu:[function(a){return a},"call$0","gXo",0,0,null],
 giO:function(a){var z,y,x
 for(z=a.length,y=0,x=0;x<z;++x){y=536870911&y+a.charCodeAt(x)
@@ -8903,30 +9151,16 @@
 gB:function(a){return a.length},
 t:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b>=a.length||b<0)throw H.b(P.N(b))
-return a[b]},"call$1","gIA",2,0,null,47],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 $isString:true,
 static:{Ga:[function(a){if(a<256)switch(a){case 9:case 10:case 11:case 12:case 13:case 32:case 133:case 160:return!0
 default:return!1}switch(a){case 5760:case 6158:case 8192:case 8193:case 8194:case 8195:case 8196:case 8197:case 8198:case 8199:case 8200:case 8201:case 8202:case 8232:case 8233:case 8239:case 8287:case 12288:case 65279:return!0
-default:return!1}},"call$1","BD",2,0,null,13]}},
-Qe:{
-"":"Iy;iN",
-gB:function(a){return this.iN.length},
-t:[function(a,b){var z,y
-z=this.iN
-if(typeof b!=="number"||Math.floor(b)!==b)H.vh(new P.AT(b))
-y=J.Wx(b)
-if(y.C(b,0))H.vh(new P.bJ("value "+H.d(b)))
-if(y.F(b,z.length))H.vh(new P.bJ("value "+H.d(b)))
-return z.charCodeAt(b)},"call$1","gIA",2,0,null,341],
-$asIy:function(){return[J.im]},
-$asar:function(){return[J.im]},
-$asWO:function(){return[J.im]},
-$ascX:function(){return[J.im]}}}],["_isolate_helper","dart:_isolate_helper",,H,{
-"":"",
+default:return!1}},"call$1","BD",2,0,null,13,[]]}}}],["_isolate_helper","dart:_isolate_helper",,H,{
+"^":"",
 zd:[function(a,b){var z=a.vV(b)
 init.globalState.Xz.bL()
-return z},"call$2","Ag",4,0,null,14,15],
-oT:[function(a){var z,y,x
+return z},"call$2","Ag",4,0,null,14,[],15,[]],
+oT:[function(a){var z,y,x,w,v
 z=new H.f0(0,0,1,null,null,null,null,null,null,null,null,null,a)
 z.i6(a)
 init.globalState=z
@@ -8934,15 +9168,20 @@
 z=init.globalState
 y=z.Hg
 z.Hg=y+1
-x=new H.aX(y,P.L5(null,null,null,J.im,H.yo),P.Ls(null,null,null,J.im),new I())
-init.globalState.Nr=x
-init.globalState.N0=x
+z=P.L5(null,null,null,J.im,H.yo)
+x=P.Ls(null,null,null,J.im)
+w=new H.yo(0,null,!1)
+v=new H.aX(y,z,x,new I(),w,P.Jz(),!1,[],P.Ls(null,null,null,null))
+x.h(0,0)
+v.aU(0,w)
+init.globalState.Nr=v
+init.globalState.N0=v
 z=H.N7()
 y=H.KT(z,[z]).BD(a)
-if(y)x.vV(new H.PK(a))
+if(y)v.vV(new H.PK(a))
 else{z=H.KT(z,[z,z]).BD(a)
-if(z)x.vV(new H.JO(a))
-else x.vV(a)}init.globalState.Xz.bL()},"call$1","wr",2,0,null,16],
+if(z)v.vV(new H.JO(a))
+else v.vV(a)}init.globalState.Xz.bL()},"call$1","wr",2,0,null,16,[]],
 yl:[function(){var z=init.currentScript
 if(z!=null)return String(z.src)
 if(typeof version=="function"&&typeof os=="object"&&"system" in os)return H.ZV()
@@ -8969,26 +9208,31 @@
 y=init.globalState
 r=y.Hg
 y.Hg=r+1
-q=new H.aX(r,P.L5(null,null,null,J.im,H.yo),P.Ls(null,null,null,J.im),new I())
-init.globalState.Xz.Rk.NZ(0,new H.IY(q,new H.jl(w,v,u,t,s),"worker-start"))
-init.globalState.N0=q
+y=P.L5(null,null,null,J.im,H.yo)
+q=P.Ls(null,null,null,J.im)
+p=new H.yo(0,null,!1)
+o=new H.aX(r,y,q,new I(),p,P.Jz(),!1,[],P.Ls(null,null,null,null))
+q.h(0,0)
+o.aU(0,p)
+init.globalState.Xz.Rk.NZ(0,new H.IY(o,new H.jl(w,v,u,t,s),"worker-start"))
+init.globalState.N0=o
 init.globalState.Xz.bL()
 break
 case"spawn-worker":r=y.t(z,"functionName")
-p=y.t(z,"uri")
-o=y.t(z,"args")
-n=y.t(z,"msg")
+n=y.t(z,"uri")
+q=y.t(z,"args")
+p=y.t(z,"msg")
 m=y.t(z,"isSpawnUri")
 y=y.t(z,"replyPort")
-if(p==null)p=$.Cl()
-l=new Worker(p)
+if(n==null)n=$.Cl()
+l=new Worker(n)
 l.onmessage=function(e) { H.Mg(l, e); }
 k=init.globalState
 j=k.hJ
 k.hJ=j+1
 $.p6().u(0,l,j)
 init.globalState.XC.u(0,j,l)
-l.postMessage(H.Gy(H.B7(["command","start","id",j,"replyTo",H.Gy(y),"args",o,"msg",H.Gy(n),"isSpawnUri",m,"functionName",r],P.L5(null,null,null,null,null))))
+l.postMessage(H.Gy(H.B7(["command","start","id",j,"replyTo",H.Gy(y),"args",q,"msg",H.Gy(p),"isSpawnUri",m,"functionName",r],P.L5(null,null,null,null,null))))
 break
 case"message":if(y.t(z,"port")!=null)J.H4(y.t(z,"port"),y.t(z,"msg"))
 init.globalState.Xz.bL()
@@ -8999,40 +9243,40 @@
 break
 case"log":H.ZF(y.t(z,"msg"))
 break
-case"print":if(init.globalState.EF===!0){y=init.globalState.my
+case"print":if(init.globalState.EF===!0){y=init.globalState.vd
 r=H.Gy(H.B7(["command","print","msg",z],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(r)}else P.JS(y.t(z,"msg"))
 break
 case"error":throw H.b(y.t(z,"msg"))
-default:}},"call$2","NB",4,0,null,17,18],
+default:}},"call$2","NB",4,0,null,17,[],18,[]],
 ZF:[function(a){var z,y,x,w
-if(init.globalState.EF===!0){y=init.globalState.my
+if(init.globalState.EF===!0){y=init.globalState.vd
 x=H.Gy(H.B7(["command","log","msg",a],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(x)}else try{$.jk().console.log(a)}catch(w){H.Ru(w)
 z=new H.XO(w,null)
-throw H.b(P.FM(z))}},"call$1","o3",2,0,null,19],
+throw H.b(P.FM(z))}},"call$1","o3",2,0,null,19,[]],
 Gy:[function(a){var z
-if(init.globalState.ji===!0){z=new H.Bj(0,new H.X1())
+if(init.globalState.ji===!0){z=new H.NA(0,new H.X1())
 z.il=new H.fP(null)
 return z.h7(a)}else{z=new H.NO(new H.X1())
 z.il=new H.fP(null)
-return z.h7(a)}},"call$1","hX",2,0,null,20],
+return z.h7(a)}},"call$1","hX",2,0,null,20,[]],
 Hh:[function(a){if(init.globalState.ji===!0)return new H.II(null).QS(a)
-else return a},"call$1","m6",2,0,null,20],
-VO:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","vP",2,0,null,21],
-ZR:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","WZ",2,0,null,21],
+else return a},"call$1","m6",2,0,null,20,[]],
+VO:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","vP",2,0,null,21,[]],
+ZR:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","dD",2,0,null,21,[]],
 PK:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){this.a.call$1([])},"call$0",null,0,0,null,"call"],
 $isEH:true},
 JO:{
-"":"Tp:108;b",
+"^":"Tp:108;b",
 call$0:[function(){this.b.call$2([],null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 f0:{
-"":"a;Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2@,my,XC,w2<",
+"^":"a;Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2@,vd,XC,w2<",
 i6:function(a){var z,y,x,w
 z=$.Qm()==null
 y=$.Nl()
@@ -9042,140 +9286,164 @@
 else y=!0
 this.ji=y
 this.vu=z&&!x
-y=H.IY
-x=H.VM(new P.Sw(null,0,0,0),[y])
-x.Eo(null,y)
-this.Xz=new H.cC(x,0)
+this.Xz=new H.cC(P.NZ(null,H.IY),0)
 this.i2=P.L5(null,null,null,J.im,H.aX)
 this.XC=P.L5(null,null,null,J.im,null)
 if(this.EF===!0){z=new H.JH()
-this.my=z
+this.vd=z
 w=function (e) { H.Mg(z, e); }
 $.jk().onmessage=w
 $.jk().dartPrint = function (object) {}}}},
 aX:{
-"":"a;jO>,Gx,fW,En<",
+"^":"a;jO>,Gx,fW,En<,EE<,Qy,RW<,C9<,lJ",
+v8:[function(a,b){if(!this.Qy.n(0,a))return
+if(this.lJ.h(0,b)&&!this.RW)this.RW=!0},"call$2","gfU",4,0,null,335,[],336,[]],
+NR:[function(a){var z,y,x,w,v,u
+if(!this.RW)return
+z=this.lJ
+z.Rz(0,a)
+if(z.X5===0){for(z=this.C9;y=z.length,y!==0;){if(0>=y)return H.e(z,0)
+x=z.pop()
+y=init.globalState.Xz.Rk
+w=y.av
+v=y.v5
+u=v.length
+w=(w-1&u-1)>>>0
+y.av=w
+if(w<0||w>=u)return H.e(v,w)
+v[w]=x
+if(w===y.eZ)y.VW()
+y.qT=y.qT+1}this.RW=!1}},"call$1","gtS",2,0,null,336,[]],
 vV:[function(a){var z,y
 z=init.globalState.N0
 init.globalState.N0=this
 $=this.En
 y=null
 try{y=a.call$0()}finally{init.globalState.N0=z
-if(z!=null)$=z.gEn()}return y},"call$1","goR",2,0,null,136],
-Zt:[function(a){return this.Gx.t(0,a)},"call$1","gQB",2,0,null,342],
-jT:[function(a,b,c){var z=this.Gx
-if(z.x4(b))throw H.b(P.FM("Registry: ports must be registered only once."))
-z.u(0,b,c)
-this.PC()},"call$2","gKI",4,0,null,342,343],
+if(z!=null)$=z.gEn()}return y},"call$1","gZm",2,0,null,136,[]],
+Ds:[function(a){var z=J.U6(a)
+switch(z.t(a,0)){case"pause":this.v8(z.t(a,1),z.t(a,2))
+break
+case"resume":this.NR(z.t(a,1))
+break
+default:P.JS("UNKOWN MESSAGE: "+H.d(a))}},"call$1","gNo",2,0,null,20,[]],
+Zt:[function(a){return this.Gx.t(0,a)},"call$1","gQB",2,0,null,337,[]],
+aU:[function(a,b){var z=this.Gx
+if(z.x4(a))throw H.b(P.FM("Registry: ports must be registered only once."))
+z.u(0,a,b)},"call$2","gPn",4,0,null,337,[],338,[]],
 PC:[function(){var z=this.jO
 if(this.Gx.X5-this.fW.X5>0)init.globalState.i2.u(0,z,this)
 else init.globalState.i2.Rz(0,z)},"call$0","gi8",0,0,null],
 $isaX:true},
 cC:{
-"":"a;Rk,bZ",
-Jc:[function(){var z=this.Rk
-if(z.av===z.HV)return
-return z.Ux()},"call$0","glk",0,0,null],
+"^":"a;Rk,bZ",
+Jc:[function(){var z,y,x,w,v
+z=this.Rk
+y=z.av
+if(y===z.eZ)return
+z.qT=z.qT+1
+x=z.v5
+w=x.length
+if(y>=w)return H.e(x,y)
+v=x[y]
+x[y]=null
+z.av=(y+1&w-1)>>>0
+return v},"call$0","glk",0,0,null],
 xB:[function(){var z,y,x
 z=this.Jc()
 if(z==null){if(init.globalState.Nr!=null&&init.globalState.i2.x4(init.globalState.Nr.jO)&&init.globalState.vu===!0&&init.globalState.Nr.Gx.X5===0)H.vh(P.FM("Program exited with open ReceivePorts."))
 y=init.globalState
-if(y.EF===!0&&y.i2.X5===0&&y.Xz.bZ===0){y=y.my
+if(y.EF===!0&&y.i2.X5===0&&y.Xz.bZ===0){y=y.vd
 x=H.Gy(H.B7(["command","close"],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(x)}return!1}z.VU()
-return!0},"call$0","gad",0,0,null],
-Wu:[function(){if($.Qm()!=null)new H.RA(this).call$0()
+return!0},"call$0","gUB",0,0,null],
+Js:[function(){if($.Qm()!=null)new H.RA(this).call$0()
 else for(;this.xB(););},"call$0","gVY",0,0,null],
 bL:[function(){var z,y,x,w,v
-if(init.globalState.EF!==!0)this.Wu()
-else try{this.Wu()}catch(x){w=H.Ru(x)
+if(init.globalState.EF!==!0)this.Js()
+else try{this.Js()}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-w=init.globalState.my
+w=init.globalState.vd
 v=H.Gy(H.B7(["command","error","msg",H.d(z)+"\n"+H.d(y)],P.L5(null,null,null,null,null)))
 w.toString
 self.postMessage(v)}},"call$0","gcP",0,0,null]},
 RA:{
-"":"Tp:107;a",
+"^":"Tp:107;a",
 call$0:[function(){if(!this.a.xB())return
-P.rT(C.RT,this)},"call$0",null,0,0,null,"call"],
+P.rT(C.ny,this)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 IY:{
-"":"a;Aq*,i3,G1*",
-VU:[function(){this.Aq.vV(this.i3)},"call$0","gjF",0,0,null],
+"^":"a;Aq*,i3,G1*",
+VU:[function(){if(this.Aq.gRW()){this.Aq.gC9().push(this)
+return}this.Aq.vV(this.i3)},"call$0","gjF",0,0,null],
 $isIY:true},
 JH:{
-"":"a;"},
+"^":"a;"},
 jl:{
-"":"Tp:108;a,b,c,d,e",
+"^":"Tp:108;a,b,c,d,e",
 call$0:[function(){var z,y,x,w,v,u
 z=this.a
 y=this.b
 x=this.c
-w=init.globalState.N0.jO
-$.te=$.te+("_"+w)
-$.eb=$.eb+("_"+w)
-w=$.ty
-$.ty=w+1
-v=new H.yo(w,null,!1)
-u=init.globalState.N0
-u.fW.h(0,w)
-u.jT(0,w,v)
-w=new H.Rd(v,null)
-w.no(v)
-$.D5=w
-J.H4(this.e,["spawned",new H.Z6(v,init.globalState.N0.jO)])
+w=init.globalState.N0
+v=w.jO
+$.te=$.te+("_"+v)
+$.eb=$.eb+("_"+v)
+J.H4(this.e,["spawned",new H.Z6(w.EE,init.globalState.N0.jO),w.Qy])
 if(this.d!==!0)z.call$1(x)
-else{w=H.N7()
-v=H.KT(w,[w,w]).BD(z)
-if(v)z.call$2(y,x)
-else{x=H.KT(w,[w]).BD(z)
+else{v=H.N7()
+u=H.KT(v,[v,v]).BD(z)
+if(u)z.call$2(y,x)
+else{x=H.KT(v,[v]).BD(z)
 if(x)z.call$1(y)
 else z.call$0()}}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-Iy4:{
-"":"a;",
+Iy:{
+"^":"a;",
 $isbC:true},
 Z6:{
-"":"Iy4;JE,Jz",
+"^":"Iy;JE,Jz",
 wR:[function(a,b){var z,y,x,w,v
 z={}
 y=this.Jz
 x=init.globalState.i2.t(0,y)
 if(x==null)return
-if(this.JE.gP0())return
-w=init.globalState.N0!=null&&init.globalState.N0.jO!==y
+w=this.JE
+if(w.gP0())return
+v=init.globalState.N0!=null&&init.globalState.N0.jO!==y
 z.a=b
-if(w)z.a=H.Gy(b)
-y=init.globalState.Xz
-v="receive "+H.d(b)
-y.Rk.NZ(0,new H.IY(x,new H.Ua(z,this,w),v))},"call$1","gX8",2,0,null,20],
+if(v)z.a=H.Gy(b)
+if(x.gEE()===w){x.Ds(z.a)
+return}y=init.globalState.Xz
+w="receive "+H.d(b)
+y.Rk.NZ(0,new H.IY(x,new H.Ua(z,this,v),w))},"call$1","gX8",2,0,null,20,[]],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isZ6&&J.de(this.JE,b.JE)},"call$1","gUJ",2,0,null,104],
-giO:function(a){return this.JE.gng()},
+return typeof b==="object"&&b!==null&&!!z.$isZ6&&J.de(this.JE,b.JE)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){return J.td(this.JE)},
 $isZ6:true,
 $isbC:true},
 Ua:{
-"":"Tp:108;a,b,c",
+"^":"Tp:108;a,b,c",
 call$0:[function(){var z,y
 z=this.b.JE
 if(!z.gP0()){if(this.c){y=this.a
 y.a=H.Hh(y.a)}J.t8(z,this.a.a)}},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ns:{
-"":"Iy4;hQ,bv,Jz",
+"^":"Iy;hQ,bv,Jz",
 wR:[function(a,b){var z,y
 z=H.Gy(H.B7(["command","message","port",this,"msg",b],P.L5(null,null,null,null,null)))
-if(init.globalState.EF===!0){init.globalState.my.toString
+if(init.globalState.EF===!0){init.globalState.vd.toString
 self.postMessage(z)}else{y=init.globalState.XC.t(0,this.hQ)
-if(y!=null)y.postMessage(z)}},"call$1","gX8",2,0,null,20],
+if(y!=null)y.postMessage(z)}},"call$1","gX8",2,0,null,20,[]],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isns&&J.de(this.hQ,b.hQ)&&J.de(this.Jz,b.Jz)&&J.de(this.bv,b.bv)},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$isns&&J.de(this.hQ,b.hQ)&&J.de(this.Jz,b.Jz)&&J.de(this.bv,b.bv)},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z,y,x
 z=J.c1(this.hQ,16)
 y=J.c1(this.Jz,8)
@@ -9185,43 +9453,37 @@
 $isns:true,
 $isbC:true},
 yo:{
-"":"a;ng<,bd,P0<",
+"^":"a;ng>,bd,P0<",
 wy:function(a){return this.bd.call$1(a)},
-cO:[function(a){var z
+cO:[function(a){var z,y
 if(this.P0)return
 this.P0=!0
 this.bd=null
 z=init.globalState.N0
-z.Gx.Rz(0,this.ng)
+y=this.ng
+z.Gx.Rz(0,y)
+z.fW.Rz(0,y)
 z.PC()},"call$0","gJK",0,0,null],
 FL:[function(a,b){if(this.P0)return
-this.wy(b)},"call$1","gfU",2,0,null,344],
+this.wy(b)},"call$1","gT5",2,0,null,339,[]],
 $isyo:true,
-static:{"":"ty"}},
-Rd:{
-"":"qh;vl,da",
-KR:[function(a,b,c,d){var z=this.da
-z.toString
-return H.VM(new P.O9(z),[null]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
-cO:[function(a){this.vl.cO(0)
-this.da.cO(0)},"call$0","gJK",0,0,107],
-no:function(a){var z=P.Ve(this.gJK(this),null,null,null,!0,null)
-this.da=z
-this.vl.bd=z.ght(z)},
-$asqh:function(){return[null]},
-$isqh:true},
-Bj:{
-"":"hz;CN,il",
-DE:[function(a){if(!!a.$isZ6)return["sendport",init.globalState.oL,a.Jz,a.JE.gng()]
+static:{"^":"Vz"}},
+NA:{
+"^":"hz;CN,il",
+DE:[function(a){if(!!a.$isZ6)return["sendport",init.globalState.oL,a.Jz,J.td(a.JE)]
 if(!!a.$isns)return["sendport",a.hQ,a.Jz,a.bv]
-throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21]},
+throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){if(!!a.$isku)return["capability",a.ng]
+throw H.b("Capability not serializable: "+H.d(a))},"call$1","gbM",2,0,null,21,[]]},
 NO:{
-"":"oo;il",
+"^":"oo;il",
 DE:[function(a){if(!!a.$isZ6)return new H.Z6(a.JE,a.Jz)
 if(!!a.$isns)return new H.ns(a.hQ,a.bv,a.Jz)
-throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21]},
+throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){if(!!a.$isku)return new H.ku(a.ng)
+throw H.b("Capability not serializable: "+H.d(a))},"call$1","gbM",2,0,null,21,[]]},
 II:{
-"":"AP;RZ",
+"^":"iY;RZ",
 Vf:[function(a){var z,y,x,w,v,u
 z=J.U6(a)
 y=z.t(a,1)
@@ -9231,41 +9493,43 @@
 if(v==null)return
 u=v.Zt(w)
 if(u==null)return
-return new H.Z6(u,x)}else return new H.ns(y,w,x)},"call$1","gTm",2,0,null,68]},
+return new H.Z6(u,x)}else return new H.ns(y,w,x)},"call$1","gTm",2,0,null,68,[]],
+Op:[function(a){return new H.ku(J.UQ(a,1))},"call$1","gID",2,0,null,68,[]]},
 fP:{
-"":"a;MD",
-t:[function(a,b){return b.__MessageTraverser__attached_info__},"call$1","gIA",2,0,null,6],
+"^":"a;MD",
+t:[function(a,b){return b.__MessageTraverser__attached_info__},"call$1","gIA",2,0,null,6,[]],
 u:[function(a,b,c){this.MD.push(b)
-b.__MessageTraverser__attached_info__=c},"call$2","gj3",4,0,null,6,348],
+b.__MessageTraverser__attached_info__=c},"call$2","gj3",4,0,null,6,[],340,[]],
 Hn:[function(a){this.MD=[]},"call$0","gb6",0,0,null],
 Xq:[function(){var z,y,x
 for(z=this.MD.length,y=0;y<z;++y){x=this.MD
 if(y>=x.length)return H.e(x,y)
 x[y].__MessageTraverser__attached_info__=null}this.MD=null},"call$0","gt6",0,0,null]},
 X1:{
-"":"a;",
-t:[function(a,b){return},"call$1","gIA",2,0,null,6],
-u:[function(a,b,c){},"call$2","gj3",4,0,null,6,348],
+"^":"a;",
+t:[function(a,b){return},"call$1","gIA",2,0,null,6,[]],
+u:[function(a,b,c){},"call$2","gj3",4,0,null,6,[],340,[]],
 Hn:[function(a){},"call$0","gb6",0,0,null],
 Xq:[function(){return},"call$0","gt6",0,0,null]},
 HU:{
-"":"a;",
+"^":"a;",
 h7:[function(a){var z
 if(H.VO(a))return this.Pq(a)
 this.il.Hn(0)
 z=null
-try{z=this.I8(a)}finally{this.il.Xq()}return z},"call$1","gyU",2,0,null,21],
+try{z=this.I8(a)}finally{this.il.Xq()}return z},"call$1","gyU",2,0,null,21,[]],
 I8:[function(a){var z
 if(a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean")return this.Pq(a)
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$isList))return this.wb(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)return this.TI(a)
 if(typeof a==="object"&&a!==null&&!!z.$isbC)return this.DE(a)
-return this.I9(a)},"call$1","gRQ",2,0,null,21],
-I9:[function(a){throw H.b("Message serialization: Illegal value "+H.d(a)+" passed")},"call$1","gSG",2,0,null,21]},
+if(typeof a==="object"&&a!==null&&!!z.$isIU)return this.yf(a)
+return this.I9(a)},"call$1","gRQ",2,0,null,21,[]],
+I9:[function(a){throw H.b("Message serialization: Illegal value "+H.d(a)+" passed")},"call$1","gSG",2,0,null,21,[]]},
 oo:{
-"":"HU;",
-Pq:[function(a){return a},"call$1","gKz",2,0,null,21],
+"^":"HU;",
+Pq:[function(a){return a},"call$1","gKz",2,0,null,21,[]],
 wb:[function(a){var z,y,x,w,v,u
 z=this.il.t(0,a)
 if(z!=null)return z
@@ -9277,7 +9541,7 @@
 this.il.u(0,a,z)
 for(w=z.length,v=0;v<x;++v){u=this.I8(y.t(a,v))
 if(v>=w)return H.e(z,v)
-z[v]=u}return z},"call$1","gqb",2,0,null,68],
+z[v]=u}return z},"call$1","gqb",2,0,null,68,[]],
 TI:[function(a){var z,y
 z={}
 y=this.il.t(0,a)
@@ -9287,30 +9551,31 @@
 z.a=y
 this.il.u(0,a,y)
 a.aN(0,new H.OW(z,this))
-return z.a},"call$1","gnM",2,0,null,144],
-DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21]},
+return z.a},"call$1","gnM",2,0,null,144,[]],
+DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){return H.vh(P.SY(null))},"call$1","gbM",2,0,null,21,[]]},
 OW:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.b
-J.kW(this.a.a,z.I8(a),z.I8(b))},"call$2",null,4,0,null,42,203,"call"],
+J.kW(this.a.a,z.I8(a),z.I8(b))},"call$2",null,4,0,null,42,[],201,[],"call"],
 $isEH:true},
 hz:{
-"":"HU;",
-Pq:[function(a){return a},"call$1","gKz",2,0,null,21],
+"^":"HU;",
+Pq:[function(a){return a},"call$1","gKz",2,0,null,21,[]],
 wb:[function(a){var z,y
 z=this.il.t(0,a)
 if(z!=null)return["ref",z]
 y=this.CN
 this.CN=y+1
 this.il.u(0,a,y)
-return["list",y,this.mE(a)]},"call$1","gqb",2,0,null,68],
+return["list",y,this.mE(a)]},"call$1","gqb",2,0,null,68,[]],
 TI:[function(a){var z,y
 z=this.il.t(0,a)
 if(z!=null)return["ref",z]
 y=this.CN
 this.CN=y+1
 this.il.u(0,a,y)
-return["map",y,this.mE(J.qA(a.gvc(a))),this.mE(J.qA(a.gUQ(a)))]},"call$1","gnM",2,0,null,144],
+return["map",y,this.mE(J.qA(a.gvc(a))),this.mE(J.qA(a.gUQ(a)))]},"call$1","gnM",2,0,null,144,[]],
 mE:[function(a){var z,y,x,w,v
 z=J.U6(a)
 y=z.gB(a)
@@ -9320,13 +9585,14 @@
 w=0
 for(;w<y;++w){v=this.I8(z.t(a,w))
 if(w>=x.length)return H.e(x,w)
-x[w]=v}return x},"call$1","gBv",2,0,null,68],
-DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21]},
-AP:{
-"":"a;",
+x[w]=v}return x},"call$1","gBv",2,0,null,68,[]],
+DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){return H.vh(P.SY(null))},"call$1","gbM",2,0,null,21,[]]},
+iY:{
+"^":"a;",
 QS:[function(a){if(H.ZR(a))return a
 this.RZ=P.Py(null,null,null,null,null)
-return this.XE(a)},"call$1","gia",2,0,null,21],
+return this.XE(a)},"call$1","gia",2,0,null,21,[]],
 XE:[function(a){var z,y
 if(a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean")return a
 z=J.U6(a)
@@ -9335,7 +9601,8 @@
 case"list":return this.Dj(a)
 case"map":return this.tv(a)
 case"sendport":return this.Vf(a)
-default:return this.PR(a)}},"call$1","gN3",2,0,null,21],
+case"capability":return this.Op(a)
+default:return this.PR(a)}},"call$1","gN3",2,0,null,21,[]],
 Dj:[function(a){var z,y,x,w,v
 z=J.U6(a)
 y=z.t(a,1)
@@ -9346,7 +9613,7 @@
 if(typeof w!=="number")return H.s(w)
 v=0
 for(;v<w;++v)z.u(x,v,this.XE(z.t(x,v)))
-return x},"call$1","gMS",2,0,null,21],
+return x},"call$1","gMS",2,0,null,21,[]],
 tv:[function(a){var z,y,x,w,v,u,t,s
 z=P.L5(null,null,null,null,null)
 y=J.U6(a)
@@ -9360,10 +9627,10 @@
 t=J.U6(v)
 s=0
 for(;s<u;++s)z.u(0,this.XE(y.t(w,s)),this.XE(t.t(v,s)))
-return z},"call$1","gwq",2,0,null,21],
-PR:[function(a){throw H.b("Unexpected serialized object")},"call$1","gec",2,0,null,21]},
+return z},"call$1","gwq",2,0,null,21,[]],
+PR:[function(a){throw H.b("Unexpected serialized object")},"call$1","gec",2,0,null,21,[]]},
 yH:{
-"":"a;Kf,zu,p9",
+"^":"a;Kf,zu,p9",
 ed:[function(){var z,y,x
 z=$.jk()
 if(z.setTimeout!=null){if(this.zu)throw H.b(P.f("Timer in event loop cannot be canceled."))
@@ -9389,22 +9656,44 @@
 z.Qa(a,b)
 return z}}},
 FA:{
-"":"Tp:107;a,b",
+"^":"Tp:107;a,b",
 call$0:[function(){this.a.p9=null
 this.b.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Av:{
-"":"Tp:107;c,d",
+"^":"Tp:107;c,d",
 call$0:[function(){this.c.p9=null
 var z=init.globalState.Xz
 z.bZ=z.bZ-1
 this.d.call$0()},"call$0",null,0,0,null,"call"],
-$isEH:true}}],["_js_helper","dart:_js_helper",,H,{
-"":"",
+$isEH:true},
+ku:{
+"^":"a;ng>",
+giO:function(a){var z,y,x
+z=this.ng
+y=J.Wx(z)
+x=y.m(z,0)
+y=y.Z(z,4294967296)
+if(typeof y!=="number")return H.s(y)
+z=x^y
+z=(~z>>>0)+(z<<15>>>0)&4294967295
+z=((z^z>>>12)>>>0)*5&4294967295
+z=((z^z>>>4)>>>0)*2057&4294967295
+return(z^z>>>16)>>>0},
+n:[function(a,b){var z,y
+if(b==null)return!1
+if(b===this)return!0
+z=J.x(b)
+if(typeof b==="object"&&b!==null&&!!z.$isku){z=this.ng
+y=b.ng
+return z==null?y==null:z===y}return!1},"call$1","gUJ",2,0,null,104,[]],
+$isku:true,
+$isIU:true}}],["_js_helper","dart:_js_helper",,H,{
+"^":"",
 wV:[function(a,b){var z,y
 if(b!=null){z=b.x
 if(z!=null)return z}y=J.x(a)
-return typeof a==="object"&&a!==null&&!!y.$isXj},"call$2","b3",4,0,null,6,22],
+return typeof a==="object"&&a!==null&&!!y.$isXj},"call$2","b3",4,0,null,6,[],22,[]],
 d:[function(a){var z
 if(typeof a==="string")return a
 if(typeof a==="number"){if(a!==0)return""+a}else if(!0===a)return"true"
@@ -9412,12 +9701,12 @@
 else if(a==null)return"null"
 z=J.AG(a)
 if(typeof z!=="string")throw H.b(P.u(a))
-return z},"call$1","mQ",2,0,null,23],
-Hz:[function(a){throw H.b(P.f("Can't use '"+H.d(a)+"' in reflection because it is not included in a @MirrorsUsed annotation."))},"call$1","IT",2,0,null,24],
+return z},"call$1","Sa",2,0,null,23,[]],
+Hz:[function(a){throw H.b(P.f("Can't use '"+H.d(a)+"' in reflection because it is not included in a @MirrorsUsed annotation."))},"call$1","IT",2,0,null,24,[]],
 eQ:[function(a){var z=a.$identityHash
 if(z==null){z=Math.random()*0x3fffffff|0
-a.$identityHash=z}return z},"call$1","Y0",2,0,null,6],
-vx:[function(a){throw H.b(P.cD(a))},"call$1","Rm",2,0,25,26],
+a.$identityHash=z}return z},"call$1","Y0",2,0,null,6,[]],
+vx:[function(a){throw H.b(P.cD(a))},"call$1","Rm",2,0,25,26,[]],
 BU:[function(a,b,c){var z,y,x,w,v,u
 if(c==null)c=H.Rm()
 if(typeof a!=="string")H.vh(new P.AT(a))
@@ -9444,7 +9733,7 @@
 if(!(v<u))break
 y.j(w,0)
 if(y.j(w,v)>x)return c.call$1(a);++v}}}}if(z==null)return c.call$1(a)
-return parseInt(a,b)},"call$3","Yv",6,0,null,27,28,29],
+return parseInt(a,b)},"call$3","Yv",6,0,null,27,[],28,[],29,[]],
 IH:[function(a,b){var z,y
 if(typeof a!=="string")H.vh(new P.AT(a))
 if(b==null)b=H.Rm()
@@ -9452,30 +9741,21 @@
 z=parseFloat(a)
 if(isNaN(z)){y=J.rr(a)
 if(y==="NaN"||y==="+NaN"||y==="-NaN")return z
-return b.call$1(a)}return z},"call$2","zb",4,0,null,27,29],
+return b.call$1(a)}return z},"call$2","zb",4,0,null,27,[],29,[]],
 lh:[function(a){var z,y,x
 z=C.AS(J.x(a))
 if(z==="Object"){y=String(a.constructor).match(/^\s*function\s*(\S*)\s*\(/)[1]
 if(typeof y==="string")z=y}x=J.rY(z)
 if(x.j(z,0)===36)z=x.yn(z,1)
 x=H.oX(a)
-return H.d(z)+H.ia(x,0,null)},"call$1","Ig",2,0,null,6],
-a5:[function(a){return"Instance of '"+H.lh(a)+"'"},"call$1","V8",2,0,null,6],
-mz:[function(){var z,y,x
-if(typeof self!="undefined")return self.location.href
-if(typeof version=="function"&&typeof os=="object"&&"system" in os){z=os.system("pwd")
-y=z.length
-x=y-1
-if(x<0)return H.e(z,x)
-if(z[x]==="\n")z=C.xB.Nj(z,0,x)}else z=null
-if(typeof version=="function"&&typeof system=="function")z=environment.PWD
-return z!=null?C.xB.g("file://",z)+"/":null},"call$0","y9",0,0,null],
+return H.d(z)+H.ia(x,0,null)},"call$1","Ig",2,0,null,6,[]],
+a5:[function(a){return"Instance of '"+H.lh(a)+"'"},"call$1","jb",2,0,null,6,[]],
 VK:[function(a){var z,y,x,w,v,u
 z=a.length
 for(y=z<=500,x="",w=0;w<z;w+=500){if(y)v=a
 else{u=w+500
 u=u<z?u:z
-v=a.slice(w,u)}x+=String.fromCharCode.apply(null,v)}return x},"call$1","Xr",2,0,null,30],
+v=a.slice(w,u)}x+=String.fromCharCode.apply(null,v)}return x},"call$1","ma",2,0,null,30,[]],
 Cq:[function(a){var z,y,x
 z=[]
 z.$builtinTypeInfo=[J.im]
@@ -9485,12 +9765,12 @@
 if(typeof x!=="number"||Math.floor(x)!==x)throw H.b(P.u(x))
 if(x<=65535)z.push(x)
 else if(x<=1114111){z.push(55296+(C.jn.GG(x-65536,10)&1023))
-z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.VK(z)},"call$1","AL",2,0,null,31],
+z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.VK(z)},"call$1","AL",2,0,null,31,[]],
 eT:[function(a){var z,y
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();){y=z.lo
 if(typeof y!=="number"||Math.floor(y)!==y)throw H.b(P.u(y))
 if(y<0)throw H.b(P.u(y))
-if(y>65535)return H.Cq(a)}return H.VK(a)},"call$1","Wb",2,0,null,32],
+if(y>65535)return H.Cq(a)}return H.VK(a)},"call$1","Wb",2,0,null,32,[]],
 zW:[function(a,b,c,d,e,f,g,h){var z,y,x,w
 if(typeof a!=="number"||Math.floor(a)!==a)H.vh(new P.AT(a))
 if(typeof b!=="number"||Math.floor(b)!==b)H.vh(new P.AT(b))
@@ -9505,13 +9785,13 @@
 if(x.E(a,0)||x.C(a,100)){w=new Date(y)
 if(h)w.setUTCFullYear(a)
 else w.setFullYear(a)
-return w.valueOf()}return y},"call$8","ny",16,0,null,33,34,35,36,37,38,39,40],
+return w.valueOf()}return y},"call$8","mV",16,0,null,33,[],34,[],35,[],36,[],37,[],38,[],39,[],40,[]],
 o2:[function(a){if(a.date===void 0)a.date=new Date(a.y3)
-return a.date},"call$1","j1",2,0,null,41],
+return a.date},"call$1","j1",2,0,null,41,[]],
 of:[function(a,b){if(a==null||typeof a==="boolean"||typeof a==="number"||typeof a==="string")throw H.b(new P.AT(a))
-return a[b]},"call$2","De",4,0,null,6,42],
+return a[b]},"call$2","De",4,0,null,6,[],42,[]],
 aw:[function(a,b,c){if(a==null||typeof a==="boolean"||typeof a==="number"||typeof a==="string")throw H.b(new P.AT(a))
-a[b]=c},"call$3","aW",6,0,null,6,42,23],
+a[b]=c},"call$3","WJ",6,0,null,6,[],42,[],23,[]],
 zo:[function(a,b,c){var z,y,x
 z={}
 z.a=0
@@ -9520,7 +9800,7 @@
 if(b!=null){z.a=0+b.length
 C.Nm.FV(y,b)}z.b=""
 if(c!=null&&!c.gl0(c))c.aN(0,new H.Cj(z,y,x))
-return J.jf(a,new H.LI(C.Ka,"call$"+z.a+z.b,0,y,x,null))},"call$3","Ro",6,0,null,15,43,44],
+return J.jf(a,new H.LI(C.Ka,"call$"+z.a+z.b,0,y,x,null))},"call$3","pT",6,0,null,15,[],43,[],44,[]],
 Ek:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 if(c!=null&&!c.gl0(c)){y=J.x(a)["call*"]
@@ -9532,7 +9812,7 @@
 if(w!==b.length)return H.zo(a,b,c)
 v=P.L5(null,null,null,null,null)
 for(u=x.hG,t=x.Rn,s=0;s<u;++s){r=s+w
-v.u(0,init.metadata[t[r+u+3]],init.metadata[x.BX(0,r)])}z.a=!1
+v.u(0,init.metadata[t[2*r+u+3]],init.metadata[x.BX(0,r)])}z.a=!1
 c.aN(0,new H.u8(z,v))
 if(z.a)return H.zo(a,b,c)
 J.bj(b,v.gUQ(v))
@@ -9541,28 +9821,29 @@
 C.Nm.FV(q,b)
 y=a["call$"+p]
 if(y==null)return H.zo(a,b,c)
-return y.apply(a,q)},"call$3","ra",6,0,null,15,43,44],
+return y.apply(a,q)},"call$3","ra",6,0,null,15,[],43,[],44,[]],
 pL:[function(a){if(a=="String")return C.Kn
 if(a=="int")return C.wq
 if(a=="double")return C.yX
 if(a=="num")return C.oD
 if(a=="bool")return C.Fm
 if(a=="List")return C.l0
-return init.allClasses[a]},"call$1","Tg",2,0,null,45],
+if(a=="Null")return C.x0
+return init.allClasses[a]},"call$1","aC",2,0,null,45,[]],
 Pq:[function(){var z={x:0}
 delete z.x
 return z},"call$0","vg",0,0,null],
-s:[function(a){throw H.b(P.u(a))},"call$1","Ff",2,0,null,46],
+s:[function(a){throw H.b(P.u(a))},"call$1","Ff",2,0,null,46,[]],
 e:[function(a,b){if(a==null)J.q8(a)
 if(typeof b!=="number"||Math.floor(b)!==b)H.s(b)
-throw H.b(P.N(b))},"call$2","x3",4,0,null,41,47],
+throw H.b(P.N(b))},"call$2","x3",4,0,null,41,[],47,[]],
 b:[function(a){var z
 if(a==null)a=new P.LK()
 z=new Error()
 z.dartException=a
 if("defineProperty" in Object){Object.defineProperty(z, "message", { get: H.Ju })
 z.name=""}else z.toString=H.Ju
-return z},"call$1","Vb",2,0,null,48],
+return z},"call$1","Vb",2,0,null,48,[]],
 Ju:[function(){return J.AG(this.dartException)},"call$0","Eu",0,0,null],
 vh:[function(a){var z
 if(a==null)a=new P.LK()
@@ -9570,7 +9851,7 @@
 z.dartException=a
 if("defineProperty" in Object){Object.defineProperty(z, "message", { get: H.Ju })
 z.name=""}else z.toString=H.Ju
-throw z},"call$1","xE",2,0,null,48],
+throw z},"call$1","xE",2,0,null,48,[]],
 Ru:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=new H.Am(a)
 if(a==null)return
@@ -9610,28 +9891,28 @@
 return z.call$1(new H.W0(y,v))}}}v=typeof y==="string"?y:""
 return z.call$1(new H.vV(v))}if(a instanceof RangeError){if(typeof y==="string"&&y.indexOf("call stack")!==-1)return new P.VS()
 return z.call$1(new P.AT(null))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof y==="string"&&y==="too much recursion")return new P.VS()
-return a},"call$1","v2",2,0,null,48],
+return a},"call$1","v2",2,0,null,48,[]],
 CU:[function(a){if(a==null||typeof a!='object')return J.v1(a)
-else return H.eQ(a)},"call$1","Zs",2,0,null,6],
+else return H.eQ(a)},"call$1","Zs",2,0,null,6,[]],
 B7:[function(a,b){var z,y,x,w
 z=a.length
 for(y=0;y<z;y=w){x=y+1
 w=x+1
-b.u(0,a[y],a[x])}return b},"call$2","nD",4,0,null,50,51],
+b.u(0,a[y],a[x])}return b},"call$2","nD",4,0,null,50,[],51,[]],
 ft:[function(a,b,c,d,e,f,g){var z=J.x(c)
 if(z.n(c,0))return H.zd(b,new H.dr(a))
 else if(z.n(c,1))return H.zd(b,new H.TL(a,d))
 else if(z.n(c,2))return H.zd(b,new H.KX(a,d,e))
 else if(z.n(c,3))return H.zd(b,new H.uZ(a,d,e,f))
 else if(z.n(c,4))return H.zd(b,new H.OQ(a,d,e,f,g))
-else throw H.b(P.FM("Unsupported number of arguments for wrapped closure"))},"call$7","Le",14,0,null,52,14,53,54,55,56,57],
+else throw H.b(P.FM("Unsupported number of arguments for wrapped closure"))},"call$7","Le",14,0,null,52,[],14,[],53,[],54,[],55,[],56,[],57,[]],
 tR:[function(a,b){var z
 if(a==null)return
 z=a.$identity
 if(!!z)return z
 z=(function(closure, arity, context, invoke) {  return function(a1, a2, a3, a4) {     return invoke(closure, context, arity, a1, a2, a3, a4);  };})(a,b,init.globalState.N0,H.ft)
 a.$identity=z
-return z},"call$2","qN",4,0,null,52,58],
+return z},"call$2","qN",4,0,null,52,[],58,[]],
 iA:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=b[0]
 z.$stubName
@@ -9660,7 +9941,7 @@
 n=o.$callName
 if(n!=null){m=d?o:H.SD(o,t)
 w[n]=m}}w["call*"]=z
-return v},"call$6","Eh",12,0,null,41,59,60,61,62,63],
+return v},"call$6","Eh",12,0,null,41,[],59,[],60,[],61,[],62,[],63,[]],
 vq:[function(a,b){var z=H.eZ
 switch(a){case 0:return function(F,S){return function(){return F.call(S(this))}}(b,z)
 case 1:return function(F,S){return function(a){return F.call(S(this),a)}}(b,z)
@@ -9668,24 +9949,24 @@
 case 3:return function(F,S){return function(a,b,c){return F.call(S(this),a,b,c)}}(b,z)
 case 4:return function(F,S){return function(a,b,c,d){return F.call(S(this),a,b,c,d)}}(b,z)
 case 5:return function(F,S){return function(a,b,c,d,e){return F.call(S(this),a,b,c,d,e)}}(b,z)
-default:return function(f,s){return function(){return f.apply(s(this),arguments)}}(b,z)}},"call$2","X5",4,0,null,58,15],
+default:return function(f,s){return function(){return f.apply(s(this),arguments)}}(b,z)}},"call$2","X5",4,0,null,58,[],15,[]],
 SD:[function(a,b){var z,y,x,w
 if(b)return H.Oj(a)
 z=a.length
 if(typeof dart_precompiled=="function")return H.vq(z,a)
-else if(z===0){y=$.mJ
+else if(z===0){y=$.bf
 if(y==null){y=H.B3("self")
-$.mJ=y}y="return function(){return F.call(this."+H.d(y)+");"
+$.bf=y}y="return function(){return F.call(this."+H.d(y)+");"
 x=$.OK
 $.OK=J.WB(x,1)
 return new Function("F",y+H.d(x)+"}")(a)}else if(1<=z&&z<27){w="abcdefghijklmnopqrstuvwxyz".split("").splice(0,z).join(",")
 y="return function("+w+"){return F.call(this."
-x=$.mJ
+x=$.bf
 if(x==null){x=H.B3("self")
-$.mJ=x}x=y+H.d(x)+","+w+");"
+$.bf=x}x=y+H.d(x)+","+w+");"
 y=$.OK
 $.OK=J.WB(y,1)
-return new Function("F",x+H.d(y)+"}")(a)}else return H.vq(z,a)},"call$2","Fw",4,0,null,15,64],
+return new Function("F",x+H.d(y)+"}")(a)}else return H.vq(z,a)},"call$2","Fw",4,0,null,15,[],64,[]],
 Z4:[function(a,b,c){var z,y
 z=H.eZ
 y=H.yS
@@ -9696,7 +9977,7 @@
 case 4:return function(n,s,r){return function(a,b,c){return s(this)[n](r(this),a,b,c)}}(b,z,y)
 case 5:return function(n,s,r){return function(a,b,c,d){return s(this)[n](r(this),a,b,c,d)}}(b,z,y)
 case 6:return function(n,s,r){return function(a,b,c,d,e){return s(this)[n](r(this),a,b,c,d,e)}}(b,z,y)
-default:return function(f,s,r,a){return function(){a=[r(this)];Array.prototype.push.apply(a,arguments);return f.apply(s(this),a)}}(c,z,y)}},"call$3","SG",6,0,null,58,12,15],
+default:return function(f,s,r,a){return function(){a=[r(this)];Array.prototype.push.apply(a,arguments);return f.apply(s(this),a)}}(c,z,y)}},"call$3","VT",6,0,null,58,[],12,[],15,[]],
 Oj:[function(a){var z,y,x,w,v
 z=a.$stubName
 y=a.length
@@ -9708,39 +9989,39 @@
 x="return function("+v+"){return this."+H.d(H.oN())+"."+z+"(this."+H.d(H.Wz())+","+v+");"
 w=$.OK
 $.OK=J.WB(w,1)
-return new Function(x+H.d(w)+"}")()}else return H.Z4(y,z,a)},"call$1","S4",2,0,null,15],
-qm:[function(a,b,c,d,e,f){b.fixed$length=init
+return new Function(x+H.d(w)+"}")()}else return H.Z4(y,z,a)},"call$1","S4",2,0,null,15,[]],
+Kq:[function(a,b,c,d,e,f){b.fixed$length=init
 c.fixed$length=init
-return H.iA(a,b,c,!!d,e,f)},"call$6","Rz",12,0,null,41,59,60,61,62,12],
+return H.iA(a,b,c,!!d,e,f)},"call$6","lu",12,0,null,41,[],59,[],60,[],61,[],62,[],12,[]],
 SE:[function(a,b){var z=J.U6(b)
-throw H.b(H.aq(H.lh(a),z.Nj(b,3,z.gB(b))))},"call$2","H7",4,0,null,23,66],
+throw H.b(H.aq(H.lh(a),z.Nj(b,3,z.gB(b))))},"call$2","H7",4,0,null,23,[],66,[]],
 Go:[function(a,b){var z
 if(a!=null)z=typeof a==="object"&&J.x(a)[b]
 else z=!0
 if(z)return a
-H.SE(a,b)},"call$2","SR",4,0,null,23,66],
-ag:[function(a){throw H.b(P.Gz("Cyclic initialization for static "+H.d(a)))},"call$1","RK",2,0,null,67],
-KT:[function(a,b,c){return new H.tD(a,b,c,null)},"call$3","HN",6,0,null,69,70,71],
-Og:[function(a,b){var z=a.name
+H.SE(a,b)},"call$2","SR",4,0,null,23,[],66,[]],
+ag:[function(a){throw H.b(P.Gz("Cyclic initialization for static "+H.d(a)))},"call$1","RK",2,0,null,67,[]],
+KT:[function(a,b,c){return new H.tD(a,b,c,null)},"call$3","HN",6,0,null,69,[],70,[],71,[]],
+uK:[function(a,b){var z=a.name
 if(b==null||b.length===0)return new H.tu(z)
-return new H.fw(z,b,null)},"call$2","He",4,0,null,72,73],
+return new H.fw(z,b,null)},"call$2","iw",4,0,null,72,[],73,[]],
 N7:[function(){return C.KZ},"call$0","cI",0,0,null],
-mm:[function(a){return new H.cu(a,null)},"call$1","ut",2,0,null,12],
+mm:[function(a){return new H.cu(a,null)},"call$1","ut",2,0,null,12,[]],
 VM:[function(a,b){if(a!=null)a.$builtinTypeInfo=b
-return a},"call$2","aa",4,0,null,74,75],
+return a},"call$2","aa",4,0,null,74,[],75,[]],
 oX:[function(a){if(a==null)return
-return a.$builtinTypeInfo},"call$1","Qn",2,0,null,74],
-IM:[function(a,b){return H.Y9(a["$as"+H.d(b)],H.oX(a))},"call$2","JW",4,0,null,74,76],
+return a.$builtinTypeInfo},"call$1","Qn",2,0,null,74,[]],
+IM:[function(a,b){return H.Y9(a["$as"+H.d(b)],H.oX(a))},"call$2","PE",4,0,null,74,[],76,[]],
 ip:[function(a,b,c){var z=H.IM(a,b)
-return z==null?null:z[c]},"call$3","Cn",6,0,null,74,76,47],
+return z==null?null:z[c]},"call$3","Cn",6,0,null,74,[],76,[],47,[]],
 Kp:[function(a,b){var z=H.oX(a)
-return z==null?null:z[b]},"call$2","tC",4,0,null,74,47],
+return z==null?null:z[b]},"call$2","tC",4,0,null,74,[],47,[]],
 Ko:[function(a,b){if(a==null)return"dynamic"
 else if(typeof a==="object"&&a!==null&&a.constructor===Array)return a[0].builtin$cls+H.ia(a,1,b)
 else if(typeof a=="function")return a.builtin$cls
 else if(typeof a==="number"&&Math.floor(a)===a)if(b==null)return C.jn.bu(a)
 else return b.call$1(a)
-else return},"call$2$onTypeVariable","bR",2,3,null,77,11,78],
+else return},"call$2$onTypeVariable","bR",2,3,null,77,11,[],78,[]],
 ia:[function(a,b,c){var z,y,x,w,v,u
 if(a==null)return""
 z=P.p9("")
@@ -9750,33 +10031,33 @@
 if(v!=null)w=!1
 u=H.Ko(v,c)
 u=typeof u==="string"?u:H.d(u)
-z.vM=z.vM+u}return w?"":"<"+H.d(z)+">"},"call$3$onTypeVariable","iM",4,3,null,77,79,80,78],
+z.vM=z.vM+u}return w?"":"<"+H.d(z)+">"},"call$3$onTypeVariable","iM",4,3,null,77,79,[],80,[],78,[]],
 dJ:[function(a){var z=typeof a==="object"&&a!==null&&a.constructor===Array?"List":J.x(a).constructor.builtin$cls
-return z+H.ia(a.$builtinTypeInfo,0,null)},"call$1","Yx",2,0,null,6],
+return z+H.ia(a.$builtinTypeInfo,0,null)},"call$1","Yx",2,0,null,6,[]],
 Y9:[function(a,b){if(typeof a==="object"&&a!==null&&a.constructor===Array)b=a
 else if(typeof a=="function"){a=H.ml(a,null,b)
 if(typeof a==="object"&&a!==null&&a.constructor===Array)b=a
-else if(typeof a=="function")b=H.ml(a,null,b)}return b},"call$2","zL",4,0,null,81,82],
+else if(typeof a=="function")b=H.ml(a,null,b)}return b},"call$2","zL",4,0,null,81,[],82,[]],
 RB:[function(a,b,c,d){var z,y
 if(a==null)return!1
 z=H.oX(a)
 y=J.x(a)
 if(y[b]==null)return!1
-return H.hv(H.Y9(y[d],z),c)},"call$4","Ym",8,0,null,6,83,84,85],
+return H.hv(H.Y9(y[d],z),c)},"call$4","Ym",8,0,null,6,[],83,[],84,[],85,[]],
 hv:[function(a,b){var z,y
 if(a==null||b==null)return!0
 z=a.length
 for(y=0;y<z;++y)if(!H.t1(a[y],b[y]))return!1
-return!0},"call$2","QY",4,0,null,86,87],
-IG:[function(a,b,c){return H.ml(a,b,H.IM(b,c))},"call$3","k2",6,0,null,88,89,90],
+return!0},"call$2","QY",4,0,null,86,[],87,[]],
+IG:[function(a,b,c){return H.ml(a,b,H.IM(b,c))},"call$3","k2",6,0,null,88,[],89,[],90,[]],
 Gq:[function(a,b){var z,y
-if(a==null)return b==null||b.builtin$cls==="a"||b.builtin$cls==="PE"
+if(a==null)return b==null||b.builtin$cls==="a"||b.builtin$cls==="Null"
 if(b==null)return!0
 z=H.oX(a)
 a=J.x(a)
 if(z!=null){y=z.slice()
 y.splice(0,0,a)}else y=a
-return H.t1(y,b)},"call$2","TU",4,0,null,91,87],
+return H.t1(y,b)},"call$2","TU",4,0,null,91,[],87,[]],
 t1:[function(a,b){var z,y,x,w,v,u,t
 if(a===b)return!0
 if(a==null||b==null)return!0
@@ -9794,7 +10075,7 @@
 if(!y&&t==null||!w)return!0
 y=y?a.slice(1):null
 w=w?b.slice(1):null
-return H.hv(H.Y9(t,y),w)},"call$2","jm",4,0,null,86,87],
+return H.hv(H.Y9(t,y),w)},"call$2","jm",4,0,null,86,[],87,[]],
 Hc:[function(a,b,c){var z,y,x,w,v
 if(b==null&&a==null)return!0
 if(b==null)return c
@@ -9804,7 +10085,7 @@
 if(c){if(z<y)return!1}else if(z!==y)return!1
 for(x=0;x<y;++x){w=a[x]
 v=b[x]
-if(!(H.t1(w,v)||H.t1(v,w)))return!1}return!0},"call$3","C6",6,0,null,86,87,92],
+if(!(H.t1(w,v)||H.t1(v,w)))return!1}return!0},"call$3","C6",6,0,null,86,[],87,[],92,[]],
 Vt:[function(a,b){var z,y,x,w,v,u
 if(b==null)return!0
 if(a==null)return!1
@@ -9815,7 +10096,7 @@
 if(!Object.hasOwnProperty.call(a,w))return!1
 v=b[w]
 u=a[w]
-if(!(H.t1(v,u)||H.t1(u,v)))return!1}return!0},"call$2","oq",4,0,null,86,87],
+if(!(H.t1(v,u)||H.t1(u,v)))return!1}return!0},"call$2","oq",4,0,null,86,[],87,[]],
 Ly:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 if(!("func" in a))return!1
 if("void" in a){if(!("void" in b)&&"ret" in b)return!1}else if(!("void" in b)){z=a.ret
@@ -9837,12 +10118,12 @@
 n=w[m]
 if(!(H.t1(o,n)||H.t1(n,o)))return!1}for(m=0;m<q;++l,++m){o=v[l]
 n=u[m]
-if(!(H.t1(o,n)||H.t1(n,o)))return!1}}return H.Vt(a.named,b.named)},"call$2","Sj",4,0,null,86,87],
-ml:[function(a,b,c){return a.apply(b,c)},"call$3","Ey",6,0,null,15,41,82],
+if(!(H.t1(o,n)||H.t1(n,o)))return!1}}return H.Vt(a.named,b.named)},"call$2","Sj",4,0,null,86,[],87,[]],
+ml:[function(a,b,c){return a.apply(b,c)},"call$3","Ey",6,0,null,15,[],41,[],82,[]],
 uc:[function(a){var z=$.NF
-return"Instance of "+(z==null?"<Unknown>":z.call$1(a))},"call$1","zB",2,0,null,93],
-Su:[function(a){return H.eQ(a)},"call$1","cx",2,0,null,6],
-iw:[function(a,b,c){Object.defineProperty(a, b, {value: c, enumerable: false, writable: true, configurable: true})},"call$3","OU",6,0,null,93,66,23],
+return"Instance of "+(z==null?"<Unknown>":z.call$1(a))},"call$1","zB",2,0,null,93,[]],
+Su:[function(a){return H.eQ(a)},"call$1","cx",2,0,null,6,[]],
+bm:[function(a,b,c){Object.defineProperty(a, b, {value: c, enumerable: false, writable: true, configurable: true})},"call$3","C5",6,0,null,93,[],66,[],23,[]],
 w3:[function(a){var z,y,x,w,v,u
 z=$.NF.call$1(a)
 y=$.nw[z]
@@ -9868,16 +10149,16 @@
 if(v==="*")throw H.b(P.SY(z))
 if(init.leafTags[z]===true){u=H.Va(x)
 Object.defineProperty(Object.getPrototypeOf(a), init.dispatchPropertyName, {value: u, enumerable: false, writable: true, configurable: true})
-return u.i}else return H.Lc(a,x)},"call$1","eU",2,0,null,93],
+return u.i}else return H.Lc(a,x)},"call$1","eU",2,0,null,93,[]],
 Lc:[function(a,b){var z,y
 z=Object.getPrototypeOf(a)
 y=J.Qu(b,z,null,null)
 Object.defineProperty(z, init.dispatchPropertyName, {value: y, enumerable: false, writable: true, configurable: true})
-return b},"call$2","qF",4,0,null,93,7],
-Va:[function(a){return J.Qu(a,!1,null,!!a.$isXj)},"call$1","UN",2,0,null,7],
+return b},"call$2","qF",4,0,null,93,[],7,[]],
+Va:[function(a){return J.Qu(a,!1,null,!!a.$isXj)},"call$1","oe",2,0,null,7,[]],
 VF:[function(a,b,c){var z=b.prototype
 if(init.leafTags[a]===true)return J.Qu(z,!1,null,!!z.$isXj)
-else return J.Qu(z,c,null,null)},"call$3","di",6,0,null,94,95,8],
+else return J.Qu(z,c,null,null)},"call$3","vi",6,0,null,94,[],95,[],8,[]],
 XD:[function(){if(!0===$.Bv)return
 $.Bv=!0
 H.Z1()},"call$0","Ki",0,0,null],
@@ -9909,8 +10190,8 @@
 t=z.prototypeForTag
 $.NF=new H.dC(v)
 $.TX=new H.wN(u)
-$.x7=new H.VX(t)},"call$0","Qs",0,0,null],
-ud:[function(a,b){return a(b)||b},"call$2","n8",4,0,null,96,97],
+$.x7=new H.VX(t)},"call$0","Bk",0,0,null],
+ud:[function(a,b){return a(b)||b},"call$2","rM",4,0,null,96,[],97,[]],
 ZT:[function(a,b){var z,y,x,w,v,u
 z=H.VM([],[P.Od])
 y=b.length
@@ -9920,13 +10201,13 @@
 z.push(new H.tQ(v,b,a))
 u=v+x
 if(u===y)break
-else w=v===u?w+1:u}return z},"call$2","tl",4,0,null,102,103],
+else w=v===u?w+1:u}return z},"call$2","tl",4,0,null,102,[],103,[]],
 m2:[function(a,b,c){var z,y
 if(typeof b==="string")return C.xB.XU(a,b,c)!==-1
 else{z=J.rY(b)
 if(typeof b==="object"&&b!==null&&!!z.$isVR){z=C.xB.yn(a,c)
 y=b.Ej
-return y.test(z)}else return J.pO(z.dd(b,C.xB.yn(a,c)))}},"call$3","VZ",6,0,null,41,104,80],
+return y.test(z)}else return J.pO(z.dd(b,C.xB.yn(a,c)))}},"call$3","WL",6,0,null,41,[],104,[],80,[]],
 ys:[function(a,b,c){var z,y,x,w,v
 if(typeof b==="string")if(b==="")if(a==="")return c
 else{z=P.p9("")
@@ -9940,61 +10221,61 @@
 if(typeof b==="object"&&b!==null&&!!w.$isVR){v=b.gF4()
 v.lastIndex=0
 return a.replace(v,c.replace("$","$$$$"))}else{if(b==null)H.vh(new P.AT(null))
-throw H.b("String.replaceAll(Pattern) UNIMPLEMENTED")}}},"call$3","eY",6,0,null,41,105,106],
+throw H.b("String.replaceAll(Pattern) UNIMPLEMENTED")}}},"call$3","uF",6,0,null,41,[],105,[],106,[]],
 Zd:{
-"":"a;"},
+"^":"a;"},
 xQ:{
-"":"a;"},
-Q9:{
-"":"a;"},
+"^":"a;"},
+F0:{
+"^":"a;"},
 oH:{
-"":"a;",
+"^":"a;",
 gl0:function(a){return J.de(this.gB(this),0)},
 gor:function(a){return!J.de(this.gB(this),0)},
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 Ix:[function(){throw H.b(P.f("Cannot modify unmodifiable Map"))},"call$0","gPb",0,0,null],
-u:[function(a,b,c){return this.Ix()},"call$2","gj3",4,0,null,42,203],
-Rz:[function(a,b){return this.Ix()},"call$1","gRI",2,0,null,42],
+u:[function(a,b,c){return this.Ix()},"call$2","gj3",4,0,null,42,[],201,[]],
+Rz:[function(a,b){return this.Ix()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return this.Ix()},"call$0","gyP",0,0,null],
-FV:[function(a,b){return this.Ix()},"call$1","gDY",2,0,null,104],
+FV:[function(a,b){return this.Ix()},"call$1","gDY",2,0,null,104,[]],
 $isZ0:true},
 LPe:{
-"":"oH;B>,eZ,tc",
-di:[function(a){return this.gUQ(this).Vr(0,new H.bw(this,a))},"call$1","gmc",2,0,null,102],
+"^":"oH;B>,HV,tc",
+di:[function(a){return this.gUQ(this).Vr(0,new H.bw(this,a))},"call$1","gmc",2,0,null,102,[]],
 x4:[function(a){if(typeof a!=="string")return!1
 if(a==="__proto__")return!1
-return this.eZ.hasOwnProperty(a)},"call$1","gV9",2,0,null,42],
+return this.HV.hasOwnProperty(a)},"call$1","gV9",2,0,null,42,[]],
 t:[function(a,b){if(typeof b!=="string")return
 if(!this.x4(b))return
-return this.eZ[b]},"call$1","gIA",2,0,null,42],
-aN:[function(a,b){J.kH(this.tc,new H.WT(this,b))},"call$1","gjw",2,0,null,110],
+return this.HV[b]},"call$1","gIA",2,0,null,42,[]],
+aN:[function(a,b){J.kH(this.tc,new H.WT(this,b))},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){return H.VM(new H.XR(this),[H.Kp(this,0)])},
 gUQ:function(a){return H.K1(this.tc,new H.jJ(this),H.Kp(this,0),H.Kp(this,1))},
 $isyN:true},
 bw:{
-"":"Tp;a,b",
-call$1:[function(a){return J.de(a,this.b)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){return J.de(a,this.b)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"JF",args:[b]}},this.a,"LPe")}},
 WT:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.b.call$2(a,this.a.t(0,a))},"call$1",null,2,0,null,42,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.b.call$2(a,this.a.t(0,a))},"call$1",null,2,0,null,42,[],"call"],
 $isEH:true},
 jJ:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,42,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,42,[],"call"],
 $isEH:true},
 XR:{
-"":"mW;Y3",
+"^":"mW;Y3",
 gA:function(a){return J.GP(this.Y3.tc)}},
 LI:{
-"":"a;lK,uk,xI,rq,FX,Nc",
+"^":"a;lK,uk,xI,rq,FX,Nc",
 gWa:function(){var z,y,x
 z=this.lK
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$iswv)return z
 x=$.bx().t(0,z)
-if(x!=null){y=J.Gn(x,":")
+if(x!=null){y=x.split(":")
 if(0>=y.length)return H.e(y,0)
 z=y[0]}y=new H.GD(z)
 this.lK=y
@@ -10039,11 +10320,11 @@
 if(u!=null)x=!0
 else z=null}s=!0}else s=!1
 if(typeof u=="function"){if(!("$reflectable" in u))H.Hz(J.GL(this.gWa()))
-if(s)return new H.IW(H.zh(u),u,x,z)
-else return new H.Ny(u,x,z)}else return new H.F3(z)},"call$1","gLk",2,0,null,6],
-static:{"":"hAw,oY,pB"}},
-Ny:{
-"":"a;mr,eK,Ot",
+if(s)return new H.IW(H.zh(u),y,u,x,z)
+else return new H.A2(y,u,x,z)}else return new H.F3(z)},"call$1","gLk",2,0,null,6,[]],
+static:{"^":"hAw,oY,Y8"}},
+A2:{
+"^":"a;Pi<,mr,eK<,Ot",
 gpf:function(){return!1},
 Bj:[function(a,b){var z,y
 if(!this.eK){if(typeof b!=="object"||b===null||b.constructor!==Array)b=P.F(b,!0,null)
@@ -10051,44 +10332,44 @@
 C.Nm.FV(y,b)
 z=this.Ot
 z=z!=null?z:a
-b=y}return this.mr.apply(z,b)},"call$2","gUT",4,0,null,140,82]},
+b=y}return this.mr.apply(z,b)},"call$2","gUT",4,0,null,140,[],82,[]]},
 IW:{
-"":"Ny;qa,mr,eK,Ot",
+"^":"A2;qa,Pi,mr,eK,Ot",
 To:function(a){return this.qa.call$1(a)},
 Bj:[function(a,b){var z,y,x,w,v,u,t
-if(!this.eK){if(typeof b!=="object"||b===null||b.constructor!==Array)b=P.F(b,!0,null)
-z=J.q8(b)
-y=a}else{x=[a]
-C.Nm.FV(x,b)
-y=this.Ot
-y=y!=null?y:a
-z=x.length-1
-b=x}w=this.qa
-v=w.Rv
-u=v+w.hG
-if(w.Mo&&z>v)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+J.q8(b)+" arguments."))
-else if(z<v)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+z+" arguments (too few)."))
-else if(z>u)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+z+" arguments (too many)."))
-for(v=J.w1(b),t=z;t<u;++t)v.h(b,init.metadata[w.BX(0,t)])
-return this.mr.apply(y,b)},"call$2","gUT",4,0,null,140,82]},
+z=this.qa
+y=z.Rv
+x=y+z.hG
+if(!this.eK){if(typeof b==="object"&&b!==null&&b.constructor===Array){w=b.length
+if(w<x)b=P.F(b,!0,null)}else{b=P.F(b,!0,null)
+w=b.length}v=a}else{u=[a]
+C.Nm.FV(u,b)
+v=this.Ot
+v=v!=null?v:a
+w=u.length-1
+b=u}if(z.Mo&&w>y)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+b.length+" arguments."))
+else if(w<y)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+w+" arguments (too few)."))
+else if(w>x)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+w+" arguments (too many)."))
+for(t=w;t<x;++t)C.Nm.h(b,init.metadata[z.BX(0,t)])
+return this.mr.apply(v,b)},"call$2","gUT",4,0,null,140,[],82,[]]},
 F3:{
-"":"a;e0?",
+"^":"a;e0?",
 gpf:function(){return!0},
 Bj:[function(a,b){var z=this.e0
-return J.jf(z==null?a:z,b)},"call$2","gUT",4,0,null,140,332]},
+return J.jf(z==null?a:z,b)},"call$2","gUT",4,0,null,140,[],326,[]]},
 FD:{
-"":"a;mr,Rn>,XZ,Rv,hG,Mo,AM",
+"^":"a;mr,Rn>,XZ,Rv,hG,Mo,AM",
 BX:[function(a,b){var z=this.Rv
 if(b<z)return
-return this.Rn[3+b-z]},"call$1","gkv",2,0,null,350],
+return this.Rn[3+b-z]},"call$1","gkv",2,0,null,342,[]],
 hl:[function(a){var z,y
 z=this.AM
 if(typeof z=="number")return init.metadata[z]
 else if(typeof z=="function"){y=new a()
 H.VM(y,y["<>"])
-return z.apply({$receiver:y})}else throw H.b(H.Ef("Unexpected function type"))},"call$1","gIX",2,0,null,351],
+return z.apply({$receiver:y})}else throw H.b(H.Ef("Unexpected function type"))},"call$1","gIX",2,0,null,343,[]],
 gx5:function(){return this.mr.$reflectionName},
-static:{"":"t4,FV,C1,mr",zh:function(a){var z,y,x,w
+static:{"^":"t4,FV,C1,bt",zh:function(a){var z,y,x,w
 z=a.$reflectionInfo
 if(z==null)return
 z.fixed$length=init
@@ -10098,21 +10379,21 @@
 w=z[1]
 return new H.FD(a,z,(y&1)===1,x,w>>1,(w&1)===1,z[2])}}},
 Cj:{
-"":"Tp:352;a,b,c",
+"^":"Tp:344;a,b,c",
 call$2:[function(a,b){var z=this.a
 z.b=z.b+"$"+H.d(a)
 this.c.push(a)
 this.b.push(b)
-z.a=z.a+1},"call$2",null,4,0,null,12,46,"call"],
+z.a=z.a+1},"call$2",null,4,0,null,12,[],46,[],"call"],
 $isEH:true},
 u8:{
-"":"Tp:352;a,b",
+"^":"Tp:344;a,b",
 call$2:[function(a,b){var z=this.b
 if(z.x4(a))z.u(0,a,b)
-else this.a.a=!0},"call$2",null,4,0,null,350,23,"call"],
+else this.a.a=!0},"call$2",null,4,0,null,342,[],23,[],"call"],
 $isEH:true},
 Zr:{
-"":"a;bT,rq,Xs,Fa,Ga,EP",
+"^":"a;bT,rq,Xs,Fa,Ga,EP",
 qS:[function(a){var z,y,x
 z=new RegExp(this.bT).exec(a)
 if(z==null)return
@@ -10127,8 +10408,8 @@
 if(x!==-1)y.method=z[x+1]
 x=this.EP
 if(x!==-1)y.receiver=z[x+1]
-return y},"call$1","gul",2,0,null,20],
-static:{"":"lm,k1,Re,fN,qi,rZ,BX,tt,dt,A7",LX:[function(a){var z,y,x,w,v,u
+return y},"call$1","gul",2,0,null,20,[]],
+static:{"^":"lm,k1,Re,fN,qi,rZ,BX,tt,dt,A7",LX:[function(a){var z,y,x,w,v,u
 a=a.replace(String({}), '$receiver$').replace(new RegExp("[[\\]{}()*+?.\\\\^$|]",'g'),'\\$&')
 z=a.match(/\\\$[a-zA-Z]+\\\$/g)
 if(z==null)z=[]
@@ -10137,29 +10418,29 @@
 w=z.indexOf("\\$expr\\$")
 v=z.indexOf("\\$method\\$")
 u=z.indexOf("\\$receiver\\$")
-return new H.Zr(a.replace('\\$arguments\\$','((?:x|[^x])*)').replace('\\$argumentsExpr\\$','((?:x|[^x])*)').replace('\\$expr\\$','((?:x|[^x])*)').replace('\\$method\\$','((?:x|[^x])*)').replace('\\$receiver\\$','((?:x|[^x])*)'),y,x,w,v,u)},"call$1","dx",2,0,null,20],S7:[function(a){return function($expr$) {
+return new H.Zr(a.replace('\\$arguments\\$','((?:x|[^x])*)').replace('\\$argumentsExpr\\$','((?:x|[^x])*)').replace('\\$expr\\$','((?:x|[^x])*)').replace('\\$method\\$','((?:x|[^x])*)').replace('\\$receiver\\$','((?:x|[^x])*)'),y,x,w,v,u)},"call$1","dx",2,0,null,20,[]],S7:[function(a){return function($expr$) {
   var $argumentsExpr$ = '$arguments$'
   try {
     $expr$.$method$($argumentsExpr$);
   } catch (e) {
     return e.message;
   }
-}(a)},"call$1","XG",2,0,null,49],Mj:[function(a){return function($expr$) {
+}(a)},"call$1","XG",2,0,null,49,[]],Mj:[function(a){return function($expr$) {
   try {
     $expr$.$method$;
   } catch (e) {
     return e.message;
   }
-}(a)},"call$1","cl",2,0,null,49]}},
+}(a)},"call$1","cl",2,0,null,49,[]]}},
 W0:{
-"":"Ge;K9,Ga",
+"^":"Ge;K9,Ga",
 bu:[function(a){var z=this.Ga
 if(z==null)return"NullError: "+H.d(this.K9)
 return"NullError: Cannot call \""+H.d(z)+"\" on null"},"call$0","gXo",0,0,null],
 $ismp:true,
 $isGe:true},
 az:{
-"":"Ge;K9,Ga,EP",
+"^":"Ge;K9,Ga,EP",
 bu:[function(a){var z,y
 z=this.Ga
 if(z==null)return"NoSuchMethodError: "+H.d(this.K9)
@@ -10174,17 +10455,17 @@
 z=z?null:b.receiver
 return new H.az(a,y,z)}}},
 vV:{
-"":"Ge;K9",
+"^":"Ge;K9",
 bu:[function(a){var z=this.K9
 return C.xB.gl0(z)?"Error":"Error: "+z},"call$0","gXo",0,0,null]},
 Am:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isGe)if(a.$thrownJsError==null)a.$thrownJsError=this.a
-return a},"call$1",null,2,0,null,146,"call"],
+return a},"call$1",null,2,0,null,152,[],"call"],
 $isEH:true},
 XO:{
-"":"a;lA,ui",
+"^":"a;lA,ui",
 bu:[function(a){var z,y
 z=this.ui
 if(z!=null)return z
@@ -10194,49 +10475,49 @@
 this.ui=z
 return z},"call$0","gXo",0,0,null]},
 dr:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return this.a.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TL:{
-"":"Tp:108;b,c",
+"^":"Tp:108;b,c",
 call$0:[function(){return this.b.call$1(this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 KX:{
-"":"Tp:108;d,e,f",
+"^":"Tp:108;d,e,f",
 call$0:[function(){return this.d.call$2(this.e,this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 uZ:{
-"":"Tp:108;UI,bK,Gq,Rm",
+"^":"Tp:108;UI,bK,Gq,Rm",
 call$0:[function(){return this.UI.call$3(this.bK,this.Gq,this.Rm)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 OQ:{
-"":"Tp:108;w3,HZ,mG,xC,cj",
+"^":"Tp:108;w3,HZ,mG,xC,cj",
 call$0:[function(){return this.w3.call$4(this.HZ,this.mG,this.xC,this.cj)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Tp:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"Closure"},"call$0","gXo",0,0,null],
 $isTp:true,
 $isEH:true},
 Bp:{
-"":"Tp;"},
+"^":"Tp;"},
 v:{
-"":"Bp;nw<,jm<,EP,RA>",
+"^":"Bp;nw<,jm<,EP,RA>",
 n:[function(a,b){var z
 if(b==null)return!1
 if(this===b)return!0
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isv)return!1
-return this.nw===b.nw&&this.jm===b.jm&&this.EP===b.EP},"call$1","gUJ",2,0,null,104],
+return this.nw===b.nw&&this.jm===b.jm&&this.EP===b.EP},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z,y
 z=this.EP
 if(z==null)y=H.eQ(this.nw)
 else y=typeof z!=="object"?J.v1(z):H.eQ(z)
-return(y^H.eQ(this.jm))>>>0},
+return J.UN(y,H.eQ(this.jm))},
 $isv:true,
-static:{"":"mJ,P4",eZ:[function(a){return a.gnw()},"call$1","PR",2,0,null,52],yS:[function(a){return a.EP},"call$1","h0",2,0,null,52],oN:[function(){var z=$.mJ
+static:{"^":"bf,P4",eZ:[function(a){return a.gnw()},"call$1","PR",2,0,null,52,[]],yS:[function(a){return a.EP},"call$1","h0",2,0,null,52,[]],oN:[function(){var z=$.bf
 if(z==null){z=H.B3("self")
-$.mJ=z}return z},"call$0","uT",0,0,null],Wz:[function(){var z=$.P4
+$.bf=z}return z},"call$0","uT",0,0,null],Wz:[function(){var z=$.P4
 if(z==null){z=H.B3("receiver")
 $.P4=z}return z},"call$0","TT",0,0,null],B3:[function(a){var z,y,x,w,v
 z=new H.v("self","target","receiver","name")
@@ -10244,30 +10525,30 @@
 y.fixed$length=init
 x=y
 for(y=x.length,w=0;w<y;++w){v=x[w]
-if(z[v]===a)return v}},"call$1","ec",2,0,null,65]}},
+if(z[v]===a)return v}},"call$1","ec",2,0,null,65,[]]}},
 Ll:{
-"":"a;Jy"},
+"^":"a;Jy"},
 dN:{
-"":"a;Jy"},
+"^":"a;Jy"},
 GT:{
-"":"a;oc>"},
+"^":"a;oc>"},
 Pe:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return this.G1},"call$0","gXo",0,0,null],
 $isGe:true,
 static:{aq:function(a,b){return new H.Pe("CastError: Casting value of type "+a+" to incompatible type "+H.d(b))}}},
 Eq:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"RuntimeError: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{Ef:function(a){return new H.Eq(a)}}},
 lb:{
-"":"a;"},
+"^":"a;"},
 tD:{
-"":"lb;dw,Iq,is,p6",
+"^":"lb;dw,Iq,is,p6",
 BD:[function(a){var z=this.rP(a)
-return z==null?!1:H.Ly(z,this.za())},"call$1","gQ4",2,0,null,49],
+return z==null?!1:H.Ly(z,this.za())},"call$1","gQ4",2,0,null,49,[]],
 rP:[function(a){var z=J.x(a)
-return"$signature" in z?z.$signature():null},"call$1","gie",2,0,null,91],
+return"$signature" in z?z.$signature():null},"call$1","gie",2,0,null,91,[]],
 za:[function(){var z,y,x,w,v,u,t
 z={ "func": "dynafunc" }
 y=this.dw
@@ -10298,18 +10579,18 @@
 for(y=t.length,w=!1,v=0;v<y;++v,w=!0){s=t[v]
 if(w)x+=", "
 x+=H.d(z[s].za())+" "+s}x+="}"}}return x+(") -> "+H.d(this.dw))},"call$0","gXo",0,0,null],
-static:{"":"Ot",Dz:[function(a){var z,y,x
+static:{"^":"Ot",Dz:[function(a){var z,y,x
 a=a
 z=[]
 for(y=a.length,x=0;x<y;++x)z.push(a[x].za())
-return z},"call$1","At",2,0,null,68]}},
+return z},"call$1","eL",2,0,null,68,[]]}},
 hJ:{
-"":"lb;",
+"^":"lb;",
 bu:[function(a){return"dynamic"},"call$0","gXo",0,0,null],
 za:[function(){return},"call$0","gpA",0,0,null],
 $ishJ:true},
 tu:{
-"":"lb;oc>",
+"^":"lb;oc>",
 za:[function(){var z,y
 z=this.oc
 y=init.allClasses[z]
@@ -10317,7 +10598,7 @@
 return y},"call$0","gpA",0,0,null],
 bu:[function(a){return this.oc},"call$0","gXo",0,0,null]},
 fw:{
-"":"lb;oc>,re<,Et",
+"^":"lb;oc>,re<,Et",
 za:[function(){var z,y
 z=this.Et
 if(z!=null)return z
@@ -10330,13 +10611,13 @@
 return y},"call$0","gpA",0,0,null],
 bu:[function(a){return this.oc+"<"+J.XS(this.re,", ")+">"},"call$0","gXo",0,0,null]},
 Zz:{
-"":"Ge;K9",
+"^":"Ge;K9",
 bu:[function(a){return"Unsupported operation: "+this.K9},"call$0","gXo",0,0,null],
 $ismp:true,
 $isGe:true,
 static:{WE:function(a){return new H.Zz(a)}}},
 cu:{
-"":"a;LU<,ke",
+"^":"a;LU<,ke",
 bu:[function(a){var z,y,x
 z=this.ke
 if(z!=null)return z
@@ -10349,25 +10630,25 @@
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iscu&&J.de(this.LU,b.LU)},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$iscu&&J.de(this.LU,b.LU)},"call$1","gUJ",2,0,null,104,[]],
 $iscu:true,
 $isuq:true},
 Lm:{
-"":"a;XP<,oc>,kU>"},
+"^":"a;XP<,oc>,kU>"},
 dC:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 wN:{
-"":"Tp:353;b",
-call$2:[function(a,b){return this.b(a,b)},"call$2",null,4,0,null,91,94,"call"],
+"^":"Tp:345;b",
+call$2:[function(a,b){return this.b(a,b)},"call$2",null,4,0,null,91,[],94,[],"call"],
 $isEH:true},
 VX:{
-"":"Tp:25;c",
-call$1:[function(a){return this.c(a)},"call$1",null,2,0,null,94,"call"],
+"^":"Tp:25;c",
+call$1:[function(a){return this.c(a)},"call$1",null,2,0,null,94,[],"call"],
 $isEH:true},
 VR:{
-"":"a;Ej,Ii,Ua",
+"^":"a;Ej,Ii,Ua",
 gF4:function(){var z=this.Ii
 if(z!=null)return z
 z=this.Ej
@@ -10384,17 +10665,16 @@
 if(typeof a!=="string")H.vh(new P.AT(a))
 z=this.Ej.exec(a)
 if(z==null)return
-return H.yx(this,z)},"call$1","gvz",2,0,null,340],
+return H.yx(this,z)},"call$1","gvz",2,0,null,334,[]],
 zD:[function(a){if(typeof a!=="string")H.vh(new P.AT(a))
-return this.Ej.test(a)},"call$1","guf",2,0,null,340],
-dd:[function(a,b){if(typeof b!=="string")H.vh(new P.AT(b))
-return new H.KW(this,b)},"call$1","gYv",2,0,null,340],
+return this.Ej.test(a)},"call$1","guf",2,0,null,334,[]],
+dd:[function(a,b){return new H.KW(this,b)},"call$1","gYv",2,0,null,334,[]],
 yk:[function(a,b){var z,y
 z=this.gF4()
 z.lastIndex=b
 y=z.exec(a)
 if(y==null)return
-return H.yx(this,y)},"call$2","gow",4,0,null,26,115],
+return H.yx(this,y)},"call$2","gow",4,0,null,26,[],115,[]],
 Bh:[function(a,b){var z,y,x,w
 z=this.gAT()
 z.lastIndex=b
@@ -10405,13 +10685,13 @@
 if(w<0)return H.e(y,w)
 if(y[w]!=null)return
 J.wg(y,w)
-return H.yx(this,y)},"call$2","gq0",4,0,null,26,115],
+return H.yx(this,y)},"call$2","gm4",4,0,null,26,[],115,[]],
 wL:[function(a,b,c){var z
 if(c>=0){z=J.q8(b)
 if(typeof z!=="number")return H.s(z)
 z=c>z}else z=!0
 if(z)throw H.b(P.TE(c,0,J.q8(b)))
-return this.Bh(b,c)},function(a,b){return this.wL(a,b,0)},"R4","call$2",null,"grS",2,2,null,336,26,115],
+return this.Bh(b,c)},function(a,b){return this.wL(a,b,0)},"R4","call$2",null,"grS",2,2,null,330,26,[],115,[]],
 $isVR:true,
 $iscT:true,
 static:{v4:[function(a,b,c,d){var z,y,x,w,v
@@ -10421,24 +10701,24 @@
 w=(function() {try {return new RegExp(a, z + y + x);} catch (e) {return e;}})()
 if(w instanceof RegExp)return w
 v=String(w)
-throw H.b(P.cD("Illegal RegExp pattern: "+a+", "+v))},"call$4","ka",8,0,null,98,99,100,101]}},
+throw H.b(P.cD("Illegal RegExp pattern: "+a+", "+v))},"call$4","ka",8,0,null,98,[],99,[],100,[],101,[]]}},
 EK:{
-"":"a;zO,QK<",
+"^":"a;zO,QK<",
 t:[function(a,b){var z=this.QK
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 VO:function(a,b){},
 $isOd:true,
 static:{yx:function(a,b){var z=new H.EK(a,b)
 z.VO(a,b)
 return z}}},
 KW:{
-"":"mW;Gf,rv",
+"^":"mW;Gf,rv",
 gA:function(a){return new H.Pb(this.Gf,this.rv,null)},
 $asmW:function(){return[P.Od]},
 $ascX:function(){return[P.Od]}},
 Pb:{
-"":"a;VV,rv,Wh",
+"^":"a;VV,rv,Wh",
 gl:function(){return this.Wh},
 G:[function(){var z,y,x
 if(this.rv==null)return!1
@@ -10453,22 +10733,22 @@
 z=this.VV.yk(this.rv,x)
 this.Wh=z
 if(z==null){this.rv=null
-return!1}return!0},"call$0","guK",0,0,null]},
+return!1}return!0},"call$0","gqy",0,0,null]},
 tQ:{
-"":"a;M,J9,zO",
+"^":"a;M,J9,zO",
 t:[function(a,b){if(!J.de(b,0))H.vh(P.N(b))
-return this.zO},"call$1","gIA",2,0,null,354],
+return this.zO},"call$1","gIA",2,0,null,346,[]],
 $isOd:true}}],["app_bootstrap","index.html_bootstrap.dart",,E,{
-"":"",
-QL:[function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/breakpoint_list.dart","package:observatory/src/observatory_elements/service_ref.dart","package:observatory/src/observatory_elements/class_ref.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/field_ref.dart","package:observatory/src/observatory_elements/function_ref.dart","package:observatory/src/observatory_elements/instance_ref.dart","package:observatory/src/observatory_elements/library_ref.dart","package:observatory/src/observatory_elements/class_view.dart","package:observatory/src/observatory_elements/code_ref.dart","package:observatory/src/observatory_elements/disassembly_entry.dart","package:observatory/src/observatory_elements/code_view.dart","package:observatory/src/observatory_elements/collapsible_content.dart","package:observatory/src/observatory_elements/field_view.dart","package:observatory/src/observatory_elements/function_view.dart","package:observatory/src/observatory_elements/isolate_summary.dart","package:observatory/src/observatory_elements/isolate_list.dart","package:observatory/src/observatory_elements/instance_view.dart","package:observatory/src/observatory_elements/json_view.dart","package:observatory/src/observatory_elements/script_ref.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/heap_profile.dart","package:observatory/src/observatory_elements/script_view.dart","package:observatory/src/observatory_elements/stack_frame.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar_isolate.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/isolate_profile.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","main.dart"]
+"^":"",
+QL:[function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/breakpoint_list.dart","package:observatory/src/observatory_elements/service_ref.dart","package:observatory/src/observatory_elements/class_ref.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/field_ref.dart","package:observatory/src/observatory_elements/function_ref.dart","package:observatory/src/observatory_elements/instance_ref.dart","package:observatory/src/observatory_elements/library_ref.dart","package:observatory/src/observatory_elements/class_view.dart","package:observatory/src/observatory_elements/code_ref.dart","package:observatory/src/observatory_elements/disassembly_entry.dart","package:observatory/src/observatory_elements/code_view.dart","package:observatory/src/observatory_elements/collapsible_content.dart","package:observatory/src/observatory_elements/field_view.dart","package:observatory/src/observatory_elements/function_view.dart","package:observatory/src/observatory_elements/script_ref.dart","package:observatory/src/observatory_elements/isolate_summary.dart","package:observatory/src/observatory_elements/isolate_list.dart","package:observatory/src/observatory_elements/instance_view.dart","package:observatory/src/observatory_elements/json_view.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/heap_profile.dart","package:observatory/src/observatory_elements/script_view.dart","package:observatory/src/observatory_elements/stack_frame.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar_isolate.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/isolate_profile.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","main.dart"]
 $.uP=!1
-F.E2()},"call$0","Im",0,0,107]},1],["breakpoint_list_element","package:observatory/src/observatory_elements/breakpoint_list.dart",,B,{
-"":"",
+F.E2()},"call$0","Pc",0,0,107]},1],["breakpoint_list_element","package:observatory/src/observatory_elements/breakpoint_list.dart",,B,{
+"^":"",
 G6:{
-"":["Vf;eE%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-grs:[function(a){return a.eE},null,null,1,0,358,"msg",359,360],
-srs:[function(a,b){a.eE=this.ct(a,C.UX,a.eE,b)},null,null,3,0,361,23,"msg",359],
-"@":function(){return[C.PT]},
+"^":["Vf;BW%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+grs:[function(a){return a.BW},null,null,1,0,350,"msg",351,352],
+srs:[function(a,b){a.BW=this.ct(a,C.UX,a.BW,b)},null,null,3,0,353,23,[],"msg",351],
+"@":function(){return[C.lT]},
 static:{Dw:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -10477,20 +10757,20 @@
 w=J.O
 v=W.cv
 v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
-a.eE=z
+a.BW=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.J0.ZL(a)
-C.J0.oX(a)
-return a},null,null,0,0,108,"new BreakpointListElement$created" /* new BreakpointListElement$created:0:0 */]}},
-"+BreakpointListElement":[362],
+C.J0.G6(a)
+return a},null,null,0,0,108,"new BreakpointListElement$created"]}},
+"+BreakpointListElement":[354],
 Vf:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["class_ref_element","package:observatory/src/observatory_elements/class_ref.dart",,Q,{
-"":"",
-kf:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":"",
+Tg:{
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.OS]},
 static:{rt:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10499,18 +10779,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.YZ.ZL(a)
-C.YZ.oX(a)
-return a},null,null,0,0,108,"new ClassRefElement$created" /* new ClassRefElement$created:0:0 */]}},
-"+ClassRefElement":[364]}],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{
-"":"",
+C.YZ.G6(a)
+return a},null,null,0,0,108,"new ClassRefElement$created"]}},
+"+ClassRefElement":[357]}],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{
+"^":"",
 Ps:{
-"":["pv;F0%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gRu:[function(a){return a.F0},null,null,1,0,358,"cls",359,360],
-sRu:[function(a,b){a.F0=this.ct(a,C.XA,a.F0,b)},null,null,3,0,361,23,"cls",359],
+"^":["pv;F0%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gRu:[function(a){return a.F0},null,null,1,0,350,"cls",351,352],
+sRu:[function(a,b){a.F0=this.ct(a,C.XA,a.F0,b)},null,null,3,0,353,23,[],"cls",351],
 "@":function(){return[C.aQ]},
 static:{zg:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10520,17 +10801,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.kk.ZL(a)
-C.kk.oX(a)
-return a},null,null,0,0,108,"new ClassViewElement$created" /* new ClassViewElement$created:0:0 */]}},
-"+ClassViewElement":[365],
+C.kk.G6(a)
+return a},null,null,0,0,108,"new ClassViewElement$created"]}},
+"+ClassViewElement":[358],
 pv:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["code_ref_element","package:observatory/src/observatory_elements/code_ref.dart",,O,{
-"":"",
+"^":"",
 CN:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.U8]},
 static:{On:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10539,19 +10820,20 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.IK.ZL(a)
-C.IK.oX(a)
-return a},null,null,0,0,108,"new CodeRefElement$created" /* new CodeRefElement$created:0:0 */]}},
-"+CodeRefElement":[364]}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{
-"":"",
+C.IK.G6(a)
+return a},null,null,0,0,108,"new CodeRefElement$created"]}},
+"+CodeRefElement":[357]}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{
+"^":"",
 vc:{
-"":["Vfx;eJ%-366,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtT:[function(a){return a.eJ},null,null,1,0,367,"code",359,360],
-stT:[function(a,b){a.eJ=this.ct(a,C.b1,a.eJ,b)},null,null,3,0,368,23,"code",359],
-gtgn:[function(a){return"panel panel-success"},null,null,1,0,369,"cssPanelClass"],
+"^":["Vfx;eJ%-359,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtT:[function(a){return a.eJ},null,null,1,0,360,"code",351,352],
+stT:[function(a,b){a.eJ=this.ct(a,C.b1,a.eJ,b)},null,null,3,0,361,23,[],"code",351],
+grj:[function(a){return"panel panel-success"},null,null,1,0,362,"cssPanelClass"],
 "@":function(){return[C.xW]},
 static:{Fe:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10561,29 +10843,29 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.YD.ZL(a)
-C.YD.oX(a)
-return a},null,null,0,0,108,"new CodeViewElement$created" /* new CodeViewElement$created:0:0 */]}},
-"+CodeViewElement":[370],
+C.YD.G6(a)
+return a},null,null,0,0,108,"new CodeViewElement$created"]}},
+"+CodeViewElement":[363],
 Vfx:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["collapsible_content_element","package:observatory/src/observatory_elements/collapsible_content.dart",,R,{
-"":"",
+"^":"",
 i6:{
-"":["Dsd;zh%-371,HX%-371,Uy%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gl7:[function(a){return a.zh},null,null,1,0,369,"iconClass",359,372],
-sl7:[function(a,b){a.zh=this.ct(a,C.Di,a.zh,b)},null,null,3,0,25,23,"iconClass",359],
-gai:[function(a){return a.HX},null,null,1,0,369,"displayValue",359,372],
-sai:[function(a,b){a.HX=this.ct(a,C.Jw,a.HX,b)},null,null,3,0,25,23,"displayValue",359],
-gxj:[function(a){return a.Uy},null,null,1,0,373,"collapsed"],
+"^":["Dsd;zh%-364,HX%-364,Uy%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gl7:[function(a){return a.zh},null,null,1,0,362,"iconClass",351,365],
+sl7:[function(a,b){a.zh=this.ct(a,C.Di,a.zh,b)},null,null,3,0,25,23,[],"iconClass",351],
+gai:[function(a){return a.HX},null,null,1,0,362,"displayValue",351,365],
+sai:[function(a,b){a.HX=this.ct(a,C.Jw,a.HX,b)},null,null,3,0,25,23,[],"displayValue",351],
+gxj:[function(a){return a.Uy},null,null,1,0,366,"collapsed"],
 sxj:[function(a,b){a.Uy=b
-this.SS(a)},null,null,3,0,374,375,"collapsed"],
+this.SS(a)},null,null,3,0,367,368,[],"collapsed"],
 i4:[function(a){Z.uL.prototype.i4.call(this,a)
 this.SS(a)},"call$0","gQd",0,0,107,"enteredView"],
 jp:[function(a,b,c,d){a.Uy=a.Uy!==!0
 this.SS(a)
-this.SS(a)},"call$3","gl8",6,0,376,18,307,74,"toggleDisplay"],
+this.SS(a)},"call$3","gl8",6,0,369,18,[],301,[],74,[],"toggleDisplay"],
 SS:[function(a){var z,y
 z=a.Uy
 y=a.zh
@@ -10591,7 +10873,7 @@
 a.HX=this.ct(a,C.Jw,a.HX,"none")}else{a.zh=this.ct(a,C.Di,y,"glyphicon glyphicon-chevron-up")
 a.HX=this.ct(a,C.Jw,a.HX,"block")}},"call$0","glg",0,0,107,"_refresh"],
 "@":function(){return[C.Gu]},
-static:{"":"Vl<-371,DI<-371",Hv:[function(a){var z,y,x,w
+static:{"^":"Vl<-364,DI<-364",Hv:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -10602,37 +10884,37 @@
 a.Uy=!0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.j8.ZL(a)
-C.j8.oX(a)
-return a},null,null,0,0,108,"new CollapsibleContentElement$created" /* new CollapsibleContentElement$created:0:0 */]}},
-"+CollapsibleContentElement":[377],
+C.j8.G6(a)
+return a},null,null,0,0,108,"new CollapsibleContentElement$created"]}},
+"+CollapsibleContentElement":[370],
 Dsd:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["custom_element.polyfill","package:custom_element/polyfill.dart",,B,{
-"":"",
+"^":"",
 G9:function(){var z,y
 z=$.cM()
 if(z==null)return!0
 y=J.UQ(z,"CustomElements")
-if(y==null)return"register" in document
+if(y==null)return"registerElement" in document
 return J.de(J.UQ(y,"ready"),!0)},
 wJ:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){if(B.G9()){var z=H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[null])
 z.L7(null,null)
 return z}z=H.VM(new W.RO(document,"WebComponentsReady",!1),[null])
 return z.gtH(z)},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["dart._internal","dart:_internal",,H,{
-"":"",
+"^":"",
 bQ:[function(a,b){var z
-for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.lo)},"call$2","Mn",4,0,null,109,110],
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.lo)},"call$2","Mn",4,0,null,109,[],110,[]],
 Ck:[function(a,b){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)if(b.call$1(z.lo)===!0)return!0
-return!1},"call$2","cs",4,0,null,109,110],
+return!1},"call$2","cs",4,0,null,109,[],110,[]],
 n3:[function(a,b,c){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b=c.call$2(b,z.lo)
-return b},"call$3","hp",6,0,null,109,111,112],
+return b},"call$3","hp",6,0,null,109,[],111,[],112,[]],
 mx:[function(a,b,c){var z,y,x
 for(y=0;x=$.RM(),y<x.length;++y)if(x[y]===a)return H.d(b)+"..."+H.d(c)
 z=P.p9("")
@@ -10641,19 +10923,19 @@
 z.We(a,", ")
 z.KF(c)}finally{x=$.RM()
 if(0>=x.length)return H.e(x,0)
-x.pop()}return z.gvM()},"call$3","FQ",6,0,null,109,113,114],
-S6:[function(a,b,c){var z=J.Wx(b)
+x.pop()}return z.gvM()},"call$3","FQ",6,0,null,109,[],113,[],114,[]],
+K0:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.D(b,a.length))throw H.b(P.TE(b,0,a.length))
 z=J.Wx(c)
-if(z.C(c,b)||z.D(c,a.length))throw H.b(P.TE(c,b,a.length))},"call$3","p5",6,0,null,68,115,116],
-qG:[function(a,b,c,d,e){var z,y
-H.S6(a,b,c)
+if(z.C(c,b)||z.D(c,a.length))throw H.b(P.TE(c,b,a.length))},"call$3","Ze",6,0,null,68,[],115,[],116,[]],
+Og:[function(a,b,c,d,e){var z,y
+H.K0(a,b,c)
 z=J.xH(c,b)
 if(J.de(z,0))return
 y=J.Wx(e)
 if(y.C(e,0))throw H.b(new P.AT(e))
-if(J.z8(y.g(e,z),J.q8(d)))throw H.b(P.w("Not enough elements"))
-H.Gj(d,e,a,b,z)},"call$5","it",10,0,null,68,115,116,105,117],
+if(J.z8(y.g(e,z),J.q8(d)))throw H.b(new P.lj("Not enough elements"))
+H.tb(d,e,a,b,z)},"call$5","rK",10,0,null,68,[],115,[],116,[],105,[],117,[]],
 IC:[function(a,b,c){var z,y,x,w,v,u
 z=J.Wx(b)
 if(z.C(b,0)||z.D(b,a.length))throw H.b(P.TE(b,0,a.length))
@@ -10665,34 +10947,34 @@
 z=z.g(b,x)
 w=a.length
 if(!!a.immutable$list)H.vh(P.f("set range"))
-H.qG(a,z,w,a,b)
+H.Og(a,z,w,a,b)
 for(z=y.gA(c);z.G();b=u){v=z.lo
 u=J.WB(b,1)
-C.Nm.u(a,b,v)}},"call$3","f3",6,0,null,68,47,109],
-Gj:[function(a,b,c,d,e){var z,y,x,w,v
+C.Nm.u(a,b,v)}},"call$3","f3",6,0,null,68,[],47,[],109,[]],
+tb:[function(a,b,c,d,e){var z,y,x,w,v
 z=J.Wx(b)
 if(z.C(b,d))for(y=J.xH(z.g(b,e),1),x=J.xH(J.WB(d,e),1),z=J.U6(a);w=J.Wx(y),w.F(y,b);y=w.W(y,1),x=J.xH(x,1))C.Nm.u(c,x,z.t(a,y))
-else for(w=J.U6(a),x=d,y=b;v=J.Wx(y),v.C(y,z.g(b,e));y=v.g(y,1),x=J.WB(x,1))C.Nm.u(c,x,w.t(a,y))},"call$5","E9",10,0,null,118,119,120,121,122],
-Ri:[function(a,b,c,d){var z
+else for(w=J.U6(a),x=d,y=b;v=J.Wx(y),v.C(y,z.g(b,e));y=v.g(y,1),x=J.WB(x,1))C.Nm.u(c,x,w.t(a,y))},"call$5","e8",10,0,null,118,[],119,[],120,[],121,[],122,[]],
+TK:[function(a,b,c,d){var z
 if(c>=a.length)return-1
 for(z=c;z<d;++z){if(z>=a.length)return H.e(a,z)
-if(J.de(a[z],b))return z}return-1},"call$4","Nk",8,0,null,123,124,80,125],
-lO:[function(a,b,c){var z,y
+if(J.de(a[z],b))return z}return-1},"call$4","Yh",8,0,null,123,[],124,[],80,[],125,[]],
+eX:[function(a,b,c){var z,y
 if(typeof c!=="number")return c.C()
 if(c<0)return-1
 z=a.length
 if(c>=z)c=z-1
 for(y=c;y>=0;--y){if(y>=a.length)return H.e(a,y)
-if(J.de(a[y],b))return y}return-1},"call$3","MW",6,0,null,123,124,80],
+if(J.de(a[y],b))return y}return-1},"call$3","Gf",6,0,null,123,[],124,[],80,[]],
 ZE:[function(a,b,c,d){if(J.Hb(J.xH(c,b),32))H.d1(a,b,c,d)
-else H.d4(a,b,c,d)},"call$4","UR",8,0,null,123,126,127,128],
+else H.d4(a,b,c,d)},"call$4","UR",8,0,null,123,[],126,[],127,[],128,[]],
 d1:[function(a,b,c,d){var z,y,x,w,v,u
 for(z=J.WB(b,1),y=J.U6(a);x=J.Wx(z),x.E(z,c);z=x.g(z,1)){w=y.t(a,z)
 v=z
 while(!0){u=J.Wx(v)
 if(!(u.D(v,b)&&J.z8(d.call$2(y.t(a,u.W(v,1)),w),0)))break
 y.u(a,v,y.t(a,u.W(v,1)))
-v=u.W(v,1)}y.u(a,v,w)}},"call$4","aH",8,0,null,123,126,127,128],
+v=u.W(v,1)}y.u(a,v,w)}},"call$4","aH",8,0,null,123,[],126,[],127,[],128,[]],
 d4:[function(a,b,a0,a1){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c
 z=J.Wx(a0)
 y=J.IJ(J.WB(z.W(a0,b),1),6)
@@ -10793,16 +11075,16 @@
 k=e}else{t.u(a,i,t.t(a,j))
 d=x.W(j,1)
 t.u(a,j,h)
-j=d}break}}H.ZE(a,k,j,a1)}else H.ZE(a,k,j,a1)},"call$4","Hm",8,0,null,123,126,127,128],
+j=d}break}}H.ZE(a,k,j,a1)}else H.ZE(a,k,j,a1)},"call$4","Hm",8,0,null,123,[],126,[],127,[],128,[]],
 aL:{
-"":"mW;",
+"^":"mW;",
 gA:function(a){return H.VM(new H.a7(this,this.gB(this),0,null),[H.ip(this,"aL",0)])},
 aN:[function(a,b){var z,y
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){b.call$1(this.Zv(0,y))
-if(z!==this.gB(this))throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,378],
+if(z!==this.gB(this))throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
 gl0:function(a){return J.de(this.gB(this),0)},
 grZ:function(a){if(J.de(this.gB(this),0))throw H.b(new P.lj("No elements"))
 return this.Zv(0,J.xH(this.gB(this),1))},
@@ -10811,13 +11093,13 @@
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(J.de(this.Zv(0,y),b))return!0
-if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gdj",2,0,null,124],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gdj",2,0,null,124,[]],
 Vr:[function(a,b){var z,y
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(b.call$1(this.Zv(0,y))===!0)return!0
-if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gG2",2,0,null,379],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gG2",2,0,null,372,[]],
 zV:[function(a,b){var z,y,x,w,v,u
 z=this.gB(this)
 if(b.length!==0){y=J.x(z)
@@ -10837,17 +11119,17 @@
 for(;v<z;++v){u=this.Zv(0,v)
 u=typeof u==="string"?u:H.d(u)
 w.vM=w.vM+u
-if(z!==this.gB(this))throw H.b(P.a4(this))}return w.vM}},"call$1","gnr",0,2,null,334,335],
-ev:[function(a,b){return P.mW.prototype.ev.call(this,this,b)},"call$1","gIR",2,0,null,379],
-ez:[function(a,b){return H.VM(new H.A8(this,b),[null,null])},"call$1","gIr",2,0,null,110],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return w.vM}},"call$1","gnr",0,2,null,328,329,[]],
+ev:[function(a,b){return P.mW.prototype.ev.call(this,this,b)},"call$1","gIR",2,0,null,372,[]],
+ez:[function(a,b){return H.VM(new H.A8(this,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
 es:[function(a,b,c){var z,y,x
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=b
 x=0
 for(;x<z;++x){y=c.call$2(y,this.Zv(0,x))
-if(z!==this.gB(this))throw H.b(P.a4(this))}return y},"call$2","gTu",4,0,null,111,112],
-eR:[function(a,b){return H.j5(this,b,null,null)},"call$1","gVQ",2,0,null,122],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return y},"call$2","gTu",4,0,null,111,[],112,[]],
+eR:[function(a,b){return H.j5(this,b,null,null)},"call$1","gZo",2,0,null,122,[]],
 tt:[function(a,b){var z,y,x
 if(b){z=H.VM([],[H.ip(this,"aL",0)])
 C.Nm.sB(z,this.gB(this))}else{y=this.gB(this)
@@ -10860,10 +11142,10 @@
 if(!(x<y))break
 y=this.Zv(0,x)
 if(x>=z.length)return H.e(z,x)
-z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 $isyN:true},
 nH:{
-"":"aL;l6,SH,AN",
+"^":"aL;l6,SH,AN",
 gMa:function(){var z,y
 z=J.q8(this.l6)
 y=this.AN
@@ -10883,8 +11165,8 @@
 return J.xH(x,y)},
 Zv:[function(a,b){var z=J.WB(this.gjX(),b)
 if(J.u6(b,0)||J.J5(z,this.gMa()))throw H.b(P.TE(b,0,this.gB(this)))
-return J.i4(this.l6,z)},"call$1","goY",2,0,null,47],
-eR:[function(a,b){return H.j5(this.l6,J.WB(this.SH,b),this.AN,null)},"call$1","gVQ",2,0,null,122],
+return J.i4(this.l6,z)},"call$1","goY",2,0,null,47,[]],
+eR:[function(a,b){return H.j5(this.l6,J.WB(this.SH,b),this.AN,null)},"call$1","gZo",2,0,null,122,[]],
 qZ:[function(a,b){var z,y,x
 if(J.u6(b,0))throw H.b(P.N(b))
 z=this.AN
@@ -10892,7 +11174,7 @@
 if(z==null)return H.j5(this.l6,y,J.WB(y,b),null)
 else{x=J.WB(y,b)
 if(J.u6(z,x))return this
-return H.j5(this.l6,y,x,null)}},"call$1","gcB",2,0,null,122],
+return H.j5(this.l6,y,x,null)}},"call$1","gVw",2,0,null,122,[]],
 Hd:function(a,b,c,d){var z,y,x
 z=this.SH
 y=J.Wx(z)
@@ -10904,7 +11186,7 @@
 z.Hd(a,b,c,d)
 return z}}},
 a7:{
-"":"a;l6,SW,G7,lo",
+"^":"a;l6,SW,G7,lo",
 gl:function(){return this.lo},
 G:[function(){var z,y,x,w
 z=this.l6
@@ -10916,9 +11198,9 @@
 if(w>=x){this.lo=null
 return!1}this.lo=y.Zv(z,w)
 this.G7=this.G7+1
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 i1:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 mb:function(a){return this.T6.call$1(a)},
 gA:function(a){var z=new H.MH(null,J.GP(this.l6),this.T6)
 z.$builtinTypeInfo=this.$builtinTypeInfo
@@ -10926,53 +11208,53 @@
 gB:function(a){return J.q8(this.l6)},
 gl0:function(a){return J.FN(this.l6)},
 grZ:function(a){return this.mb(J.MQ(this.l6))},
-Zv:[function(a,b){return this.mb(J.i4(this.l6,b))},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.mb(J.i4(this.l6,b))},"call$1","goY",2,0,null,47,[]],
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]},
 static:{K1:function(a,b,c,d){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isyN)return H.VM(new H.xy(a,b),[c,d])
 return H.VM(new H.i1(a,b),[c,d])}}},
 xy:{
-"":"i1;l6,T6",
+"^":"i1;l6,T6",
 $isyN:true},
 MH:{
-"":"Yl;lo,OI,T6",
+"^":"Yl;lo,OI,T6",
 mb:function(a){return this.T6.call$1(a)},
 G:[function(){var z=this.OI
 if(z.G()){this.lo=this.mb(z.gl())
 return!0}this.lo=null
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.lo},
 $asYl:function(a,b){return[b]}},
 A8:{
-"":"aL;CR,T6",
+"^":"aL;CR,T6",
 mb:function(a){return this.T6.call$1(a)},
 gB:function(a){return J.q8(this.CR)},
-Zv:[function(a,b){return this.mb(J.i4(this.CR,b))},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.mb(J.i4(this.CR,b))},"call$1","goY",2,0,null,47,[]],
 $asaL:function(a,b){return[b]},
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]},
 $isyN:true},
 U5:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 gA:function(a){var z=new H.SO(J.GP(this.l6),this.T6)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z}},
 SO:{
-"":"Yl;OI,T6",
+"^":"Yl;OI,T6",
 mb:function(a){return this.T6.call$1(a)},
 G:[function(){for(var z=this.OI;z.G();)if(this.mb(z.gl())===!0)return!0
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.OI.gl()}},
 kV:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 gA:function(a){var z=new H.rR(J.GP(this.l6),this.T6,C.Gw,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]}},
 rR:{
-"":"a;OI,T6,TQ,lo",
+"^":"a;OI,T6,TQ,lo",
 mb:function(a){return this.T6.call$1(a)},
 gl:function(){return this.lo},
 G:[function(){var z,y
@@ -10982,23 +11264,23 @@
 if(y.G()){this.TQ=null
 z=J.GP(this.mb(y.gl()))
 this.TQ=z}else return!1}this.lo=this.TQ.gl()
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 H6:{
-"":"mW;l6,FT",
-eR:[function(a,b){return H.ke(this.l6,this.FT+b,H.Kp(this,0))},"call$1","gVQ",2,0,null,292],
+"^":"mW;l6,FT",
+eR:[function(a,b){return H.ke(this.l6,this.FT+b,H.Kp(this,0))},"call$1","gZo",2,0,null,287,[]],
 gA:function(a){var z=this.l6
 z=new H.U1(z.gA(z),this.FT)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 ap:function(a,b,c){},
 static:{ke:function(a,b,c){var z
-if(!!a.$isyN){z=H.VM(new H.d5(a,b),[c])
+if(!!a.$isyN){z=H.VM(new H.wB(a,b),[c])
 z.ap(a,b,c)
-return z}return H.bk(a,b,c)},bk:function(a,b,c){var z=H.VM(new H.H6(a,b),[c])
+return z}return H.mi(a,b,c)},mi:function(a,b,c){var z=H.VM(new H.H6(a,b),[c])
 z.ap(a,b,c)
 return z}}},
-d5:{
-"":"H6;l6,FT",
+wB:{
+"^":"H6;l6,FT",
 gB:function(a){var z,y
 z=this.l6
 y=J.xH(z.gB(z),this.FT)
@@ -11006,120 +11288,132 @@
 return 0},
 $isyN:true},
 U1:{
-"":"Yl;OI,FT",
+"^":"Yl;OI,FT",
 G:[function(){var z,y
 for(z=this.OI,y=0;y<this.FT;++y)z.G()
 this.FT=0
-return z.G()},"call$0","guK",0,0,null],
+return z.G()},"call$0","gqy",0,0,null],
 gl:function(){return this.OI.gl()}},
 SJ:{
-"":"a;",
-G:[function(){return!1},"call$0","guK",0,0,null],
+"^":"a;",
+G:[function(){return!1},"call$0","gqy",0,0,null],
 gl:function(){return}},
 SU7:{
-"":"a;",
+"^":"a;",
 sB:function(a,b){throw H.b(P.f("Cannot change the length of a fixed-length list"))},
-h:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","gDY",2,0,null,109],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gRI",2,0,null,124],
-V1:[function(a){throw H.b(P.f("Cannot clear a fixed-length list"))},"call$0","gyP",0,0,null]},
-JJ:{
-"":"a;",
-u:[function(a,b,c){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$2","gj3",4,0,null,47,23],
+h:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","ght",2,0,null,23,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$2","gQG",4,0,null,47,[],23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","gDY",2,0,null,109,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gRI",2,0,null,124,[]],
+V1:[function(a){throw H.b(P.f("Cannot clear a fixed-length list"))},"call$0","gyP",0,0,null],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gNM",2,0,null,47,[]]},
+Qr:{
+"^":"a;",
+u:[function(a,b,c){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot change the length of an unmodifiable list"))},
-h:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","gDY",2,0,null,109],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gRI",2,0,null,124],
-So:[function(a,b){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$1","gH7",0,2,null,77,128],
+h:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","ght",2,0,null,23,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$2","gQG",4,0,null,47,[],23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","gDY",2,0,null,109,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gRI",2,0,null,124,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$1","gH7",0,2,null,77,128,[]],
 V1:[function(a){throw H.b(P.f("Cannot clear an unmodifiable list"))},"call$0","gyP",0,0,null],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$4","gam",6,2,null,336,115,116,109,117],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
-Iy:{
-"":"ar+JJ;",
+w2Y:{
+"^":"ar+Qr;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 iK:{
-"":"aL;CR",
+"^":"aL;CR",
 gB:function(a){return J.q8(this.CR)},
 Zv:[function(a,b){var z,y
 z=this.CR
 y=J.U6(z)
-return y.Zv(z,J.xH(J.xH(y.gB(z),1),b))},"call$1","goY",2,0,null,47]},
+return y.Zv(z,J.xH(J.xH(y.gB(z),1),b))},"call$1","goY",2,0,null,47,[]]},
 GD:{
-"":"a;fN>",
+"^":"a;fN>",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isGD&&J.de(this.fN,b.fN)},"call$1","gUJ",2,0,null,104],
-giO:function(a){return 536870911&664597*J.v1(this.fN)},
+return typeof b==="object"&&b!==null&&!!z.$isGD&&J.de(this.fN,b.fN)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){var z=J.v1(this.fN)
+if(typeof z!=="number")return H.s(z)
+return 536870911&664597*z},
 bu:[function(a){return"Symbol(\""+H.d(this.fN)+"\")"},"call$0","gXo",0,0,null],
 $isGD:true,
 $iswv:true,
-static:{"":"zP",le:[function(a){var z=J.U6(a)
+static:{"^":"zP",le:[function(a){var z=J.U6(a)
 if(z.gl0(a)===!0)return a
 if(z.nC(a,"_"))throw H.b(new P.AT("\""+H.d(a)+"\" is a private identifier"))
 z=$.R0().Ej
 if(typeof a!=="string")H.vh(new P.AT(a))
 if(!z.test(a))throw H.b(new P.AT("\""+H.d(a)+"\" is not an identifier or an empty String"))
-return a},"call$1","kh",2,0,null,12]}}}],["dart._js_mirrors","dart:_js_mirrors",,H,{
-"":"",
+return a},"call$1","kh",2,0,null,12,[]]}}}],["dart._js_mirrors","dart:_js_mirrors",,H,{
+"^":"",
 YC:[function(a){if(a==null)return
-return new H.GD(a)},"call$1","Rc",2,0,null,12],
-X7:[function(a){return H.YC(H.d(a.fN)+"=")},"call$1","JP",2,0,null,129],
+return new H.GD(a)},"call$1","Rc",2,0,null,12,[]],
+X7:[function(a){return H.YC(H.d(a.fN)+"=")},"call$1","JP",2,0,null,129,[]],
 vn:[function(a){var z=J.x(a)
-if(typeof a==="object"&&a!==null&&!!z.$isTp)return new H.Sz(a)
-else return new H.iu(a)},"call$1","Yf",2,0,130,131],
-jO:[function(a){var z=$.Sl().t(0,a)
-if(J.de(a,"dynamic"))return $.Cr()
-return H.tT(H.YC(z==null?a:z),a)},"call$1","vC",2,0,null,132],
-tT:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+if(typeof a==="object"&&a!==null&&!!z.$isTp)return new H.Sz(a,4)
+else return new H.iu(a,4)},"call$1","Yf",2,0,130,131,[]],
+jO:[function(a){var z,y
+z=$.Sl().t(0,a)
+y=J.x(a)
+if(y.n(a,"dynamic"))return $.P8()
+if(y.n(a,"void"))return $.oj()
+return H.tT(H.YC(z==null?a:z),a)},"call$1","vC",2,0,null,132,[]],
+tT:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
+z=J.U6(b)
+y=z.u8(b,"/")
+if(y>-1)b=z.yn(b,y+1)
 z=$.tY
 if(z==null){z=H.Pq()
-$.tY=z}y=z[b]
-if(y!=null)return y
+$.tY=z}x=z[b]
+if(x!=null)return x
 z=J.U6(b)
-x=z.u8(b,"<")
-if(x!==-1){w=H.jO(z.Nj(b,0,x)).gJi()
-y=new H.bl(w,z.Nj(b,x+1,J.xH(z.gB(b),1)),null,null,null,null,null,null,null,null,null,null,null,null,null,w.gIf())
-$.tY[b]=y
-return y}v=H.pL(b)
-if(v==null){u=init.functionAliases[b]
-if(u!=null){y=new H.ng(b,null,a)
-y.CM=new H.Ar(init.metadata[u],null,null,null,y)
-$.tY[b]=y
-return y}throw H.b(P.f("Cannot find class for: "+H.d(a.fN)))}z=J.x(v)
-t=typeof v==="object"&&v!==null&&!!z.$isGv?v.constructor:v
-s=t["@"]
-if(s==null){r=null
-q=null}else{r=s[""]
-z=J.U6(r)
-if(typeof r==="object"&&r!==null&&(r.constructor===Array||!!z.$isList)){q=z.Mu(r,1,z.gB(r)).br(0)
-r=z.t(r,0)}else q=null
-if(typeof r!=="string")r=""}z=J.Gn(r,";")
+w=z.u8(b,"<")
+if(w!==-1){v=H.jO(z.Nj(b,0,w)).gJi()
+x=new H.bl(v,z.Nj(b,w+1,J.xH(z.gB(b),1)),null,null,null,null,null,null,null,null,null,null,null,null,null,v.gIf())
+$.tY[b]=x
+return x}u=H.pL(b)
+if(u==null){t=init.functionAliases[b]
+if(t!=null){x=new H.ng(b,null,a)
+x.CM=new H.Ar(init.metadata[t],null,null,null,x)
+$.tY[b]=x
+return x}throw H.b(P.f("Cannot find class for: "+H.d(a.fN)))}z=J.x(u)
+s=typeof u==="object"&&u!==null&&!!z.$isGv?u.constructor:u
+r=s["@"]
+if(r==null){q=null
+p=null}else{q=r["^"]
+z=J.U6(q)
+if(typeof q==="object"&&q!==null&&(q.constructor===Array||!!z.$isList)){p=z.Mu(q,1,z.gB(q)).br(0)
+q=z.t(q,0)}else p=null
+if(typeof q!=="string")q=""}z=J.uH(q,";")
 if(0>=z.length)return H.e(z,0)
-p=J.Gn(z[0],"+")
-if(p.length>1&&$.Sl().t(0,b)==null)y=H.MJ(p,b)
-else{o=new H.Wf(b,v,r,q,H.Pq(),null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,a)
-n=t.prototype["<>"]
-if(n==null||n.length===0)y=o
-else{for(z=n.length,m="dynamic",l=1;l<z;++l)m+=",dynamic"
-y=new H.bl(o,m,null,null,null,null,null,null,null,null,null,null,null,null,null,o.If)}}$.tY[b]=y
-return y},"call$2","ER",4,0,null,129,132],
+o=J.uH(z[0],"+")
+if(o.length>1&&$.Sl().t(0,b)==null)x=H.MJ(o,b)
+else{n=new H.Wf(b,u,q,p,H.Pq(),null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,a)
+m=s.prototype["<>"]
+if(m==null||m.length===0)x=n
+else{for(z=m.length,l="dynamic",k=1;k<z;++k)l+=",dynamic"
+x=new H.bl(n,l,null,null,null,null,null,null,null,null,null,null,null,null,null,n.If)}}$.tY[b]=x
+return x},"call$2","ER",4,0,null,129,[],132,[]],
 Vv:[function(a){var z,y,x
 z=P.L5(null,null,null,null,null)
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();){x=y.lo
-if(!x.gxV()&&!x.glT()&&!x.ghB())z.u(0,x.gIf(),x)}return z},"call$1","yM",2,0,null,133],
+if(!x.gxV()&&!x.glT()&&!x.ghB())z.u(0,x.gIf(),x)}return z},"call$1","yM",2,0,null,133,[]],
 Fk:[function(a){var z,y,x
 z=P.L5(null,null,null,null,null)
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();){x=y.lo
-if(x.gxV())z.u(0,x.gIf(),x)}return z},"call$1","Pj",2,0,null,133],
+if(x.gxV())z.u(0,x.gIf(),x)}return z},"call$1","Pj",2,0,null,133,[]],
 vE:[function(a,b){var z,y,x,w,v,u
 z=P.L5(null,null,null,null,null)
 z.FV(0,b)
@@ -11129,7 +11423,7 @@
 v=z.t(0,H.YC(v.Nj(w,0,J.xH(v.gB(w),1))))
 u=J.x(v)
 if(typeof v==="object"&&v!==null&&!!u.$isRY)continue}if(x.gxV())continue
-z.to(x.gIf(),new H.YX(x))}return z},"call$2","un",4,0,null,133,134],
+z.to(x.gIf(),new H.YX(x))}return z},"call$2","un",4,0,null,133,[],134,[]],
 MJ:[function(a,b){var z,y,x,w
 z=[]
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();)z.push(H.jO(y.lo))
@@ -11137,21 +11431,21 @@
 x.G()
 w=x.lo
 for(;x.G();)w=new H.BI(w,x.lo,null,null,H.YC(b))
-return w},"call$2","R9",4,0,null,135,132],
+return w},"call$2","V8",4,0,null,135,[],132,[]],
 w2:[function(a,b){var z,y,x
 z=J.U6(a)
 y=0
 while(!0){x=z.gB(a)
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
-if(J.de(z.t(a,y).gIf(),H.YC(b)))return y;++y}throw H.b(new P.AT("Type variable not present in list."))},"call$2","QB",4,0,null,137,12],
+if(J.de(z.t(a,y).gIf(),H.YC(b)))return y;++y}throw H.b(new P.AT("Type variable not present in list."))},"call$2","QB",4,0,null,137,[],12,[]],
 Jf:[function(a,b){var z,y,x,w,v,u,t
 z={}
 z.a=null
 for(y=a;y!=null;){x=J.x(y)
 if(typeof y==="object"&&y!==null&&!!x.$isMs){z.a=y
 break}if(typeof y==="object"&&y!==null&&!!x.$isrN)break
-y=y.gXP()}if(b==null)return $.Cr()
+y=y.gXP()}if(b==null)return $.P8()
 else{x=z.a
 if(x==null)w=H.Ko(b,null)
 else if(x.gHA())if(typeof b==="number"){v=init.metadata[b]
@@ -11161,9 +11455,9 @@
 if(typeof b==="number"){t=z.call$1(b)
 x=J.x(t)
 if(typeof t==="object"&&t!==null&&!!x.$iscw)return t}w=H.Ko(b,new H.jB(z))}}if(w!=null)return H.jO(w)
-return P.re(C.yQ)},"call$2","xN",4,0,null,138,11],
+return P.re(C.yQ)},"call$2","xN",4,0,null,138,[],11,[]],
 fb:[function(a,b){if(a==null)return b
-return H.YC(H.d(a.gvd().fN)+"."+H.d(b.fN))},"call$2","WS",4,0,null,138,139],
+return H.YC(H.d(a.gUx().fN)+"."+H.d(b.fN))},"call$2","WS",4,0,null,138,[],139,[]],
 pj:[function(a){var z,y,x,w
 z=a["@"]
 if(z!=null)return z()
@@ -11173,7 +11467,7 @@
 return H.VM(new H.A8(y,new H.ye()),[null,null]).br(0)}x=Function.prototype.toString.call(a)
 w=C.xB.cn(x,new H.VR(H.v4("\"[0-9,]*\";?[ \n\r]*}",!1,!0,!1),null,null))
 if(w===-1)return C.xD;++w
-return H.VM(new H.A8(H.VM(new H.A8(C.xB.Nj(x,w,C.xB.XU(x,"\"",w)).split(","),P.ya()),[null,null]),new H.O1()),[null,null]).br(0)},"call$1","C7",2,0,null,140],
+return H.VM(new H.A8(H.VM(new H.A8(C.xB.Nj(x,w,C.xB.XU(x,"\"",w)).split(","),P.ya()),[null,null]),new H.O1()),[null,null]).br(0)},"call$1","C7",2,0,null,140,[]],
 jw:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r
 z=J.U6(b)
 if(typeof b==="object"&&b!==null&&(b.constructor===Array||!!z.$isList)){y=H.Mk(z.t(b,0),",")
@@ -11184,20 +11478,20 @@
 s=x[v]
 v=t}else s=null
 r=H.pS(u,s,a,c)
-if(r!=null)d.push(r)}},"call$4","Sv",8,0,null,138,141,61,51],
+if(r!=null)d.push(r)}},"call$4","Sv",8,0,null,138,[],141,[],61,[],51,[]],
 Mk:[function(a,b){var z=J.U6(a)
 if(z.gl0(a)===!0)return H.VM([],[J.O])
-return z.Fr(a,b)},"call$2","nK",4,0,null,26,98],
+return z.Fr(a,b)},"call$2","nK",4,0,null,26,[],98,[]],
 BF:[function(a){switch(a){case"==":case"[]":case"*":case"/":case"%":case"~/":case"+":case"<<":case">>":case">=":case">":case"<=":case"<":case"&":case"^":case"|":case"-":case"unary-":case"[]=":case"~":return!0
-default:return!1}},"call$1","IX",2,0,null,12],
+default:return!1}},"call$1","IX",2,0,null,12,[]],
 Y6:[function(a){var z,y
 z=J.x(a)
-if(z.n(a,"")||z.n(a,"$methodsWithOptionalArguments"))return!0
+if(z.n(a,"^")||z.n(a,"$methodsWithOptionalArguments"))return!0
 y=z.t(a,0)
 z=J.x(y)
-return z.n(y,"*")||z.n(y,"+")},"call$1","uG",2,0,null,42],
+return z.n(y,"*")||z.n(y,"+")},"call$1","uG",2,0,null,42,[]],
 Sn:{
-"":"a;L5,Aq>",
+"^":"a;L5,Aq>",
 gvU:function(){var z,y,x,w
 z=this.L5
 if(z!=null)return z
@@ -11206,7 +11500,7 @@
 y.u(0,w.gFP(),w)}z=H.VM(new H.Oh(y),[P.iD,P.D4])
 this.L5=z
 return z},
-static:{"":"QG,Q3,Ct",dF:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+static:{"^":"QG,Q3,Ct",dF:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z=P.L5(null,null,null,J.O,[J.Q,P.D4])
 y=init.libraries
 if(y==null)return z
@@ -11214,7 +11508,7 @@
 v=J.U6(w)
 u=v.t(w,0)
 t=v.t(w,1)
-s=P.r6($.cO().ej(t))
+s=P.r6($.qG().ej(t))
 r=v.t(w,2)
 q=v.t(w,3)
 p=v.t(w,4)
@@ -11224,48 +11518,52 @@
 l=p==null?C.xD:p()
 J.bi(z.to(u,new H.nI()),new H.Uz(s,r,q,l,o,n,m,null,null,null,null,null,null,null,null,null,null,H.YC(u)))}return z},"call$0","jc",0,0,null]}},
 nI:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return H.VM([],[P.D4])},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TY:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return this.gOO()},"call$0","gXo",0,0,null],
-Hy:[function(a,b){throw H.b(P.SY(null))},"call$2","gdk",4,0,null,41,165],
+IB:[function(a){throw H.b(P.SY(null))},"call$1","gft",2,0,null,41,[]],
+Hy:[function(a,b){throw H.b(P.SY(null))},"call$2","gdk",4,0,null,41,[],165,[]],
 $isej:true},
 Lj:{
-"":"TY;MA",
+"^":"TY;MA",
 gOO:function(){return"Isolate"},
 gcZ:function(){var z=$.Cm().gvU().nb
 return z.gUQ(z).XG(0,new H.mb())},
 $isej:true},
 mb:{
-"":"Tp:381;",
-call$1:[function(a){return a.gGD()},"call$1",null,2,0,null,380,"call"],
+"^":"Tp:374;",
+call$1:[function(a){return a.gGD()},"call$1",null,2,0,null,373,[],"call"],
 $isEH:true},
-mZ:{
-"":"TY;If<",
-gvd:function(){return H.fb(this.gXP(),this.gIf())},
+am:{
+"^":"TY;If<",
+gUx:function(){return H.fb(this.gXP(),this.gIf())},
 gq4:function(){return J.co(this.gIf().fN,"_")},
 bu:[function(a){return this.gOO()+" on '"+H.d(this.gIf().fN)+"'"},"call$0","gXo",0,0,null],
-jd:[function(a,b){throw H.b(H.Ef("Should not call _invoke"))},"call$2","gqi",4,0,null,43,44],
+jd:[function(a,b){throw H.b(H.Ef("Should not call _invoke"))},"call$2","gqi",4,0,null,43,[],44,[]],
 $isNL:true,
 $isej:true},
 cw:{
-"":"EE;XP<,xW,Nz,LQ,If",
+"^":"EE;XP<,xW,Nz,LQ,If",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iscw&&J.de(this.If,b.If)&&this.XP.n(0,b.XP)},"call$1","gUJ",2,0,null,104],
-giO:function(a){var z=this.XP
-return(1073741823&J.v1(C.Gp.LU)^17*J.v1(this.If)^19*z.giO(z))>>>0},
+return typeof b==="object"&&b!==null&&!!z.$iscw&&J.de(this.If,b.If)&&this.XP.n(0,b.XP)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){var z,y
+z=J.v1(C.Gp.LU)
+if(typeof z!=="number")return H.s(z)
+y=this.XP
+return(1073741823&z^17*J.v1(this.If)^19*y.giO(y))>>>0},
 gOO:function(){return"TypeVariableMirror"},
 $iscw:true,
-$istg:true,
+$isac:true,
 $isX9:true,
 $isNL:true,
 $isej:true},
 EE:{
-"":"mZ;If",
+"^":"am;If",
 gOO:function(){return"TypeMirror"},
 gXP:function(){return},
 gc9:function(){return H.vh(P.SY(null))},
@@ -11278,9 +11576,9 @@
 $isNL:true,
 $isej:true},
 Uz:{
-"":"NZ;FP<,aP,wP,le,LB,GD<,ae<,SD,zE,P8,mX,T1,fX,M2,uA,Db,xO,If",
+"^":"uh;FP<,aP,wP,le,LB,GD<,ae<,SD,zE,P8,mX,T1,fX,M2,uA,Db,xO,If",
 gOO:function(){return"LibraryMirror"},
-gvd:function(){return this.If},
+gUx:function(){return this.If},
 gEO:function(){return this.gm8()},
 gqh:function(){var z,y,x,w
 z=this.P8
@@ -11302,13 +11600,16 @@
 if(w==null)w=this.gcc().nb.t(0,a)
 if(w==null)throw H.b(P.lr(this,H.X7(a),[b],null,null))
 w.Hy(this,b)
-return H.vn(b)},"call$2","gtd",4,0,null,65,165],
+return H.vn(b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z=this.gQH().nb.t(0,a)
+if(z==null)throw H.b(P.lr(this,a,[],null,null))
+return H.vn(z.IB(this))},"call$1","gPo",2,0,null,65,[]],
 F2:[function(a,b,c){var z,y
 z=this.gQH().nb.t(0,a)
 if(z==null)throw H.b(P.lr(this,a,b,c,null))
 y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isZk)if(!("$reflectable" in z.dl))H.Hz(a.gfN(a))
-return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+if(typeof z==="object"&&z!==null&&!!y.$isZk&&!("$reflectable" in z.dl))H.Hz(a.gfN(a))
+return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gm8:function(){var z,y,x,w,v,u,t,s,r,q,p
 z=this.SD
 if(z!=null)return z
@@ -11324,9 +11625,8 @@
 s=w[t]
 r=$.Sl().t(0,t)
 if(r==null)break c$0
-u=J.rY(r)
-q=u.nC(r,"new ")
-if(q){u=u.yn(r,4)
+q=J.rY(r).nC(r,"new ")
+if(q){u=C.xB.yn(r,4)
 r=H.ys(u,"$",".")}p=H.Sd(r,s,!q,q)
 y.push(p)
 p.nz=this}++v}this.SD=y
@@ -11392,78 +11692,117 @@
 this.xO=z
 return z},
 gXP:function(){return},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isD4:true,
 $isej:true,
 $isNL:true},
-NZ:{
-"":"mZ+M2;",
+uh:{
+"^":"am+M2;",
 $isej:true},
 IB:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 oP:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 YX:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return this.a},"call$0",null,0,0,null,"call"],
 $isEH:true},
 BI:{
-"":"vk;AY<,XW,BB,eL,If",
+"^":"Un;AY<,XW,BB,eL,If",
 gOO:function(){return"ClassMirror"},
 gIf:function(){var z,y
 z=this.BB
 if(z!=null)return z
-y=this.AY.gvd().fN
+y=this.AY.gUx().fN
 z=this.XW
-z=J.kE(y," with ")===!0?H.YC(H.d(y)+", "+H.d(z.gvd().fN)):H.YC(H.d(y)+" with "+H.d(z.gvd().fN))
+z=J.kE(y," with ")===!0?H.YC(H.d(y)+", "+H.d(z.gUx().fN)):H.YC(H.d(y)+" with "+H.d(z.gUx().fN))
 this.BB=z
 return z},
-gvd:function(){return this.gIf()},
+gUx:function(){return this.gIf()},
 gYK:function(){return this.XW.gYK()},
-F2:[function(a,b,c){throw H.b(P.lr(this,a,b,c,null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-PU:[function(a,b){throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,165],
+F2:[function(a,b,c){throw H.b(P.lr(this,a,b,c,null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+rN:[function(a){throw H.b(P.lr(this,a,null,null,null))},"call$1","gPo",2,0,null,65,[]],
+PU:[function(a,b){throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,[],165,[]],
 gkZ:function(){return[this.XW]},
 gHA:function(){return!0},
 gJi:function(){return this},
 gNy:function(){throw H.b(P.SY(null))},
 gw8:function(){return C.hU},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-vk:{
-"":"EE+M2;",
+Un:{
+"^":"EE+M2;",
 $isej:true},
 M2:{
-"":"a;",
+"^":"a;",
 $isej:true},
 iu:{
-"":"M2;Ax<",
+"^":"M2;Ax<,xq",
 gt5:function(a){return H.jO(J.bB(this.Ax).LU)},
 F2:[function(a,b,c){var z=J.GL(a)
-return this.tu(a,0,z+":"+b.length+":0",b)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-tu:[function(a,b,c,d){var z,y,x,w,v,u,t
+return this.tu(a,0,z+":"+b.length+":0",b)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+gK8:function(){var z,y,x
 z=$.eb
 y=this.Ax
+if(y==null)y=J.x(null)
 x=y.constructor[z]
 if(x==null){x=H.Pq()
-y.constructor[z]=x}w=x[c]
-if(w==null){v=$.I6().t(0,c)
-u=b===0?H.j5(J.Gn(c,":"),3,null,null).br(0):C.xD
-t=new H.LI(a,v,b,d,u,null)
-w=t.ZU(y)
-x[c]=w}else t=null
-if(w.gpf())return H.vn(w.Bj(y,t==null?new H.LI(a,$.I6().t(0,c),b,d,[],null):t))
-else return H.vn(w.Bj(y,d))},"call$4","gqi",8,0,null,12,11,383,82],
+y.constructor[z]=x}return x},
+tu:[function(a,b,c,d){var z,y,x,w,v
+z=this.gK8()
+y=z[c]
+if(y==null){x=$.I6().t(0,c)
+w=b===0?H.j5(J.uH(c,":"),3,null,null).br(0):C.xD
+v=new H.LI(a,x,b,d,w,null)
+y=v.ZU(this.Ax)
+z[c]=y}else v=null
+if(y.gpf()){if(v==null)v=new H.LI(a,$.I6().t(0,c),b,d,[],null)
+return H.vn(y.Bj(this.Ax,v))}else return H.vn(y.Bj(this.Ax,d))},"call$4","gqi",8,0,null,12,[],11,[],376,[],82,[]],
 PU:[function(a,b){var z=H.d(a.gfN(a))+"="
 this.tu(H.YC(z),2,z,[b])
-return H.vn(b)},"call$2","gtd",4,0,null,65,165],
-rN:[function(a){return this.tu(a,1,J.GL(a),[])},"call$1","gPo",2,0,null,65],
+return H.vn(b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z,y,x,w
+$loop$0:{z=this.xq
+if(typeof z=="number"||typeof a.$p=="undefined")break $loop$0
+y=a.$p(z)
+if(typeof y=="undefined")break $loop$0
+x=y(this.Ax)
+if(x===y.v)return y.m
+else{w=H.vn(x)
+y.v=x
+y.m=w
+return w}}return this.Dm(a)},"call$1","gPo",2,0,null,65,[]],
+Dm:[function(a){var z,y,x,w,v,u,t
+z=J.GL(a)
+y=this.tu(a,1,z,C.xD)
+x=this.gK8()[z]
+if(x.gpf())return y
+w=this.xq
+if(typeof w=="number"){w=J.xH(w,1)
+this.xq=w
+if(!J.de(w,0))return y
+w=({})
+this.xq=w}v=typeof dart_precompiled!="function"
+if(typeof a.$p=="undefined")a.$p=this.ds(z,v)
+u=x.gPi()
+t=x.geK()?this.QN(u,v):this.x0(u,v)
+w[z]=t
+t.v=t.m=w
+return y},"call$1","gFf",2,0,null,65,[]],
+ds:[function(a,b){if(b)return(function(b){return eval(b)})("(function probe$"+H.d(a)+"(c){return c."+H.d(a)+"})")
+else return(function(n){return(function(c){return c[n]})})(a)},"call$2","gfu",4,0,null,236,[],377,[]],
+x0:[function(a,b){if(!b)return(function(n){return(function(o){return o[n]()})})(a)
+return(function(b){return eval(b)})("(function "+this.Ax.constructor.name+"$"+H.d(a)+"(o){return o."+H.d(a)+"()})")},"call$2","gER",4,0,null,12,[],377,[]],
+QN:[function(a,b){var z=J.x(this.Ax)
+if(!b)return(function(n,i){return(function(o){return i[n](o)})})(a,z)
+return(function(b,i){return eval(b)})("(function "+z.constructor.name+"$"+H.d(a)+"(o){return i."+H.d(a)+"(o)})",z)},"call$2","gpa",4,0,null,12,[],377,[]],
 n:[function(a,b){var z,y
 if(b==null)return!1
 z=J.x(b)
@@ -11471,25 +11810,25 @@
 y=b.Ax
 y=z==null?y==null:z===y
 z=y}else z=!1
-return z},"call$1","gUJ",2,0,null,104],
-giO:function(a){return(H.CU(this.Ax)^909522486)>>>0},
+return z},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){return J.UN(H.CU(this.Ax),909522486)},
 bu:[function(a){return"InstanceMirror on "+H.d(P.hl(this.Ax))},"call$0","gXo",0,0,null],
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isiu:true,
 $isvr:true,
 $isej:true},
 mg:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){var z,y
 z=a.gfN(a)
 y=this.a
 if(y.x4(z))y.u(0,z,b)
-else throw H.b(H.WE("Invoking noSuchMethod with named arguments not implemented"))},"call$2",null,4,0,null,129,23,"call"],
+else throw H.b(H.WE("Invoking noSuchMethod with named arguments not implemented"))},"call$2",null,4,0,null,129,[],23,[],"call"],
 $isEH:true},
 bl:{
-"":"mZ;NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,QY,If",
+"^":"am;NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,RH,If",
 gOO:function(){return"ClassMirror"},
-gCr:function(){for(var z=this.gw8(),z=z.gA(z);z.G();)if(!J.de(z.lo,$.Cr()))return H.d(this.NK.gCr())+"<"+this.EZ+">"
+gCr:function(){for(var z=this.gw8(),z=z.gA(z);z.G();)if(!J.de(z.lo,$.P8()))return H.d(this.NK.gCr())+"<"+this.EZ+">"
 return this.NK.gCr()},
 gNy:function(){return this.NK.gNy()},
 gw8:function(){var z,y,x,w,v,u,t,s
@@ -11539,7 +11878,8 @@
 z=H.VM(new H.Oh(y),[P.wv,P.NL])
 this.Db=z
 return z},
-PU:[function(a,b){return this.NK.PU(a,b)},"call$2","gtd",4,0,null,65,165],
+PU:[function(a,b){return this.NK.PU(a,b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){return this.NK.rN(a)},"call$1","gPo",2,0,null,65,[]],
 gXP:function(){return this.NK.gXP()},
 gc9:function(){return this.NK.gc9()},
 gAY:function(){var z=this.qN
@@ -11547,7 +11887,7 @@
 z=H.Jf(this,init.metadata[J.UQ(init.typeInformation[this.NK.gCr()],0)])
 this.qN=z
 return z},
-F2:[function(a,b,c){return this.NK.F2(a,b,c)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+F2:[function(a,b,c){return this.NK.F2(a,b,c)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gHA:function(){return!1},
 gJi:function(){return this.NK},
 gkZ:function(){var z=this.qm
@@ -11556,38 +11896,39 @@
 this.qm=z
 return z},
 gq4:function(){return J.co(this.NK.gIf().fN,"_")},
-gvd:function(){return this.NK.gvd()},
+gUx:function(){return this.NK.gUx()},
 gYj:function(){return new H.cu(this.gCr(),null)},
 gIf:function(){return this.NK.gIf()},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
+$isbl:true,
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
 tB:{
-"":"Tp:25;a",
+"^":"Tp:25;a",
 call$1:[function(a){var z,y,x
 z=H.BU(a,null,new H.Oo())
 y=this.a
 if(J.de(z,-1))y.push(H.jO(J.rr(a)))
 else{x=init.metadata[z]
-y.push(new H.cw(P.re(x.gXP()),x,z,null,H.YC(J.O6(x))))}},"call$1",null,2,0,null,385,"call"],
+y.push(new H.cw(P.re(x.gXP()),x,z,null,H.YC(J.O6(x))))}},"call$1",null,2,0,null,379,[],"call"],
 $isEH:true},
 Oo:{
-"":"Tp:229;",
-call$1:[function(a){return-1},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return-1},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Tc:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b.call$1(a)},"call$1",null,2,0,null,87,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b.call$1(a)},"call$1",null,2,0,null,87,[],"call"],
 $isEH:true},
 Ax:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){this.a.u(0,a.gIf(),a)
-return a},"call$1",null,2,0,null,386,"call"],
+return a},"call$1",null,2,0,null,380,[],"call"],
 $isEH:true},
 Wf:{
-"":"HZT;Cr<,Tx<,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,QY,nz,If",
+"^":"vk;Cr<,Tx<,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,RH,nz,If",
 gOO:function(){return"ClassMirror"},
 gaB:function(){var z,y
 z=this.Tx
@@ -11599,7 +11940,7 @@
 z=H.VM(new H.Oh(H.Fk(this.gEO())),[P.wv,P.RS])
 this.b0=z
 return z},
-ly:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
+ly:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=this.gaB().prototype
 y=H.kU(z)
 x=H.VM([],[H.Zk])
@@ -11607,20 +11948,22 @@
 if(H.Y6(v))continue
 u=$.bx().t(0,v)
 if(u==null)continue
-t=H.Sd(u,z[v],!1,!1)
-x.push(t)
-t.nz=a}y=H.kU(init.statics[this.Cr])
-for(w=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);w.G();){s=w.lo
-if(H.Y6(s))continue
-r=this.gXP().gae()[s]
-if("$reflectable" in r){q=r.$reflectionName
-if(q==null)continue
-p=J.rY(q).nC(q,"new ")
-if(p){o=C.xB.yn(q,4)
-q=H.ys(o,"$",".")}}else continue
-t=H.Sd(q,r,!p,p)
-x.push(t)
-t.nz=a}return x},"call$1","gN4",2,0,null,387],
+t=z[v]
+if(t.$reflectable==2)continue
+s=H.Sd(u,t,!1,!1)
+x.push(s)
+s.nz=a}y=H.kU(init.statics[this.Cr])
+for(w=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);w.G();){r=w.lo
+if(H.Y6(r))continue
+q=this.gXP().gae()[r]
+if("$reflectable" in q){p=q.$reflectionName
+if(p==null)continue
+o=J.rY(p).nC(p,"new ")
+if(o){n=C.xB.yn(p,4)
+p=H.ys(n,"$",".")}}else continue
+s=H.Sd(p,q,!o,o)
+x.push(s)
+s.nz=a}return x},"call$1","gN4",2,0,null,381,[]],
 gEO:function(){var z=this.qu
 if(z!=null)return z
 z=this.ly(this)
@@ -11635,8 +11978,8 @@
 if(y!=null){x=[x]
 C.Nm.FV(x,y)}H.jw(a,x,!1,z)
 w=init.statics[this.Cr]
-if(w!=null)H.jw(a,w[""],!0,z)
-return z},"call$1","gMp",2,0,null,388],
+if(w!=null)H.jw(a,w["^"],!0,z)
+return z},"call$1","gkW",2,0,null,382,[]],
 gTH:function(){var z=this.zE
 if(z!=null)return z
 z=this.ws(this)
@@ -11676,7 +12019,13 @@
 if(z!=null&&z.gFo()&&!z.gV5()){y=z.gao()
 if(!(y in $))throw H.b(H.Ef("Cannot find \""+y+"\" in current isolate."))
 $[y]=b
-return H.vn(b)}throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,165],
+return H.vn(b)}throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z,y
+z=this.gcc().nb.t(0,a)
+if(z!=null&&z.gFo()){y=z.gao()
+if(!(y in $))throw H.b(H.Ef("Cannot find \""+y+"\" in current isolate."))
+if(y in init.lazies)return H.vn($[init.lazies[y]]())
+else return H.vn($[y])}throw H.b(P.lr(this,a,null,null,null))},"call$1","gPo",2,0,null,65,[]],
 gXP:function(){var z,y
 z=this.nz
 if(z==null){z=this.Tx
@@ -11713,13 +12062,13 @@
 F2:[function(a,b,c){var z=this.ghp().nb.t(0,a)
 if(z==null||!z.gFo())throw H.b(P.lr(this,a,b,c,null))
 if(!z.tB())H.Hz(a.gfN(a))
-return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gHA:function(){return!0},
 gJi:function(){return this},
 MR:[function(a){var z,y
 z=init.typeInformation[this.Cr]
 y=z!=null?H.VM(new H.A8(J.Pr(z,1),new H.t0(a)),[null,null]).br(0):C.Me
-return H.VM(new P.Yp(y),[P.Ms])},"call$1","gki",2,0,null,138],
+return H.VM(new P.Yp(y),[P.Ms])},"call$1","gki",2,0,null,138,[]],
 gkZ:function(){var z=this.qm
 if(z!=null)return z
 z=this.MR(this)
@@ -11739,30 +12088,30 @@
 gw8:function(){return C.hU},
 gYj:function(){if(!J.de(J.q8(this.gNy()),0))throw H.b(P.f("Declarations of generics have no reflected type"))
 return new H.cu(this.Cr,null)},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isWf:true,
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-HZT:{
-"":"EE+M2;",
+vk:{
+"^":"EE+M2;",
 $isej:true},
 Ei:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 U7:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){this.b.u(0,a.gIf(),a)
-return a},"call$1",null,2,0,null,386,"call"],
+return a},"call$1",null,2,0,null,380,[],"call"],
 $isEH:true},
 t0:{
-"":"Tp:389;a",
-call$1:[function(a){return H.Jf(this.a,init.metadata[a])},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:384;a",
+call$1:[function(a){return H.Jf(this.a,init.metadata[a])},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 Ld:{
-"":"mZ;ao<,V5<,Fo<,n6,nz,Ay>,le,If",
+"^":"am;ao<,V5<,Fo<,n6,nz,Ay>,le,If",
 gOO:function(){return"VariableMirror"},
 gt5:function(a){return H.Jf(this.nz,init.metadata[this.Ay])},
 gXP:function(){return this.nz},
@@ -11770,13 +12119,14 @@
 if(z==null){z=this.n6
 z=z==null?C.xD:z()
 this.le=z}return J.C0(z,H.Yf()).br(0)},
+IB:[function(a){return $[this.ao]},"call$1","gft",2,0,null,41,[]],
 Hy:[function(a,b){if(this.V5)throw H.b(P.lr(this,H.X7(this.If),[b],null,null))
-$[this.ao]=b},"call$2","gdk",4,0,null,41,165],
+$[this.ao]=b},"call$2","gdk",4,0,null,41,[],165,[]],
 $isRY:true,
 $isNL:true,
 $isej:true,
 static:{pS:function(a,b,c,d){var z,y,x,w,v,u,t,s,r,q,p,o
-z=J.Gn(a,"-")
+z=J.uH(a,"-")
 y=z.length
 if(y===1)return
 if(0>=y)return H.e(z,0)
@@ -11793,7 +12143,7 @@
 s=y.yn(x,r+1)}else q=s
 p=d?$.Sl().t(0,q):$.bx().t(0,"g"+q)
 if(p==null)p=q
-if(t){o=H.YC(H.d(p)+"=")
+if(t){o=H.YC(p+"=")
 y=c.gEO()
 v=new H.a7(y,y.length,0,null)
 v.$builtinTypeInfo=[H.Kp(y,0)]
@@ -11802,9 +12152,9 @@
 return new H.Ld(s,t,d,b,c,H.BU(z[1],null,null),null,H.YC(p))},GQ:[function(a){if(a>=60&&a<=64)return a-59
 if(a>=123&&a<=126)return a-117
 if(a>=37&&a<=43)return a-27
-return 0},"call$1","fS",2,0,null,136]}},
+return 0},"call$1","fS",2,0,null,136,[]]}},
 Sz:{
-"":"iu;Ax",
+"^":"iu;Ax,xq",
 gMj:function(a){var z,y,x,w,v,u,t,s
 z=$.te
 y=this.Ax
@@ -11821,18 +12171,18 @@
 v=H.BU(w[1],null,null)
 w=J.RE(y)
 if(typeof y==="object"&&y!==null&&!!w.$isv){u=y.gjm()
-y.gnw()
+H.eZ(y)
 t=$.bx().t(0,w.gRA(y))
 if(t==null)H.Hz(t)
 s=H.Sd(t,u,!1,!1)}else s=new H.Zk(y[x],v,!1,!1,!0,!1,!1,null,null,null,null,H.YC(x))
 y.constructor[z]=s
 return s},
 bu:[function(a){return"ClosureMirror on '"+H.d(P.hl(this.Ax))+"'"},"call$0","gXo",0,0,null],
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isvr:true,
 $isej:true},
 Zk:{
-"":"mZ;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,G6,H3,If",
+"^":"am;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,wM,H3,If",
 gOO:function(){return"MethodMirror"},
 gMP:function(){var z=this.H3
 if(z!=null)return z
@@ -11841,8 +12191,8 @@
 tB:[function(){return"$reflectable" in this.dl},"call$0","gX1",0,0,null],
 gXP:function(){return this.nz},
 gdw:function(){this.gc9()
-return this.G6},
-gc9:function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
+return this.wM},
+gc9:function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 z=this.le
 if(z==null){z=this.dl
 y=H.pj(z)
@@ -11856,31 +12206,34 @@
 if(z!=null){x=J.x(z)
 x=typeof z==="object"&&z!==null&&!!x.$isD4
 z=x}else z=!1
-t=z?new H.Ar(v.hl(null),null,null,null,this.nz):new H.Ar(v.hl(this.nz.gJi().gTx()),null,null,null,this.nz)}if(this.xV)this.G6=this.nz
-else this.G6=t.gdw()
+t=z?new H.Ar(v.hl(null),null,null,null,this.nz):new H.Ar(v.hl(this.nz.gJi().gTx()),null,null,null,this.nz)}if(this.xV)this.wM=this.nz
+else this.wM=t.gdw()
 s=v.Mo
-for(z=t.gMP(),z=z.gA(z),x=w.length,r=v.hG,q=0;z.G();q=k){p=z.lo
-o=init.metadata[v.Rn[q+r+3]]
-n=J.RE(p)
-if(q<v.Rv)m=new H.fu(this,n.gAy(p),!1,!1,null,H.YC(o))
-else{l=v.BX(0,q)
-m=new H.fu(this,n.gAy(p),!0,s,l,H.YC(o))}k=q+1
-if(q>=x)return H.e(w,q)
-w[q]=m}}this.H3=H.VM(new P.Yp(w),[P.Ys])
+for(z=t.gMP(),z=z.gA(z),x=w.length,r=v.hG,q=v.Rn,p=0;z.G();p=i){o=z.lo
+n=init.metadata[q[2*p+r+3]]
+m=q[2*p+r+3+1]
+l=J.RE(o)
+if(p<v.Rv)k=new H.fu(this,l.gAy(o),!1,!1,null,m,H.YC(n))
+else{j=v.BX(0,p)
+k=new H.fu(this,l.gAy(o),!0,s,j,m,H.YC(n))}i=p+1
+if(p>=x)return H.e(w,p)
+w[p]=k}}this.H3=H.VM(new P.Yp(w),[P.Ys])
 z=H.VM(new P.Yp(J.C0(y,H.Yf())),[null])
 this.le=z}return z},
 jd:[function(a,b){if(!this.Fo&&!this.xV)throw H.b(H.Ef("Cannot invoke instance method without receiver."))
 if(!J.de(this.Yq,a.length)||this.dl==null)throw H.b(P.lr(this.gXP(),this.If,a,b,null))
-return this.dl.apply($,P.F(a,!0,null))},"call$2","gqi",4,0,null,43,44],
+return this.dl.apply($,P.F(a,!0,null))},"call$2","gqi",4,0,null,43,[],44,[]],
+IB:[function(a){if(this.lT)return this.jd([],null)
+else throw H.b(P.SY("getField on "+H.d(a)))},"call$1","gft",2,0,null,41,[]],
 Hy:[function(a,b){if(this.hB)return this.jd([b],null)
-else throw H.b(P.lr(this,H.X7(this.If),[],null,null))},"call$2","gdk",4,0,null,41,165],
+else throw H.b(P.lr(this,H.X7(this.If),[],null,null))},"call$2","gdk",4,0,null,41,[],165,[]],
 guU:function(){return!this.lT&&!this.hB&&!this.xV},
 $isZk:true,
 $isRS:true,
 $isNL:true,
 $isej:true,
 static:{Sd:function(a,b,c,d){var z,y,x,w,v,u,t
-z=J.Gn(a,":")
+z=a.split(":")
 if(0>=z.length)return H.e(z,0)
 a=z[0]
 y=H.BF(a)
@@ -11895,20 +12248,24 @@
 u=!1}w=H.YC(a)
 return new H.Zk(b,J.WB(v,t),u,x,c,d,y,null,null,null,null,w)}}},
 fu:{
-"":"mZ;XP<,Ay>,Q2<,Sh,BE,If",
+"^":"am;XP<,Ay>,Q2<,Sh,BE,QY,If",
 gOO:function(){return"ParameterMirror"},
 gt5:function(a){return H.Jf(this.XP,this.Ay)},
 gFo:function(){return!1},
 gV5:function(){return!1},
-gc9:function(){return H.vh(P.SY(null))},
+gc9:function(){return J.C0(this.QY,new H.wt()).br(0)},
 $isYs:true,
 $isRY:true,
 $isNL:true,
 $isej:true},
+wt:{
+"^":"Tp:385;",
+call$1:[function(a){return H.vn(init.metadata[a])},"call$1",null,2,0,null,383,[],"call"],
+$isEH:true},
 ng:{
-"":"mZ;Cr<,CM,If",
+"^":"am;Cr<,CM,If",
 gP:function(a){return this.CM},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 gOO:function(){return"TypedefMirror"},
 gJi:function(){return H.vh(P.SY(null))},
 gXP:function(){return H.vh(P.SY(null))},
@@ -11918,30 +12275,31 @@
 $isNL:true,
 $isej:true},
 TN:{
-"":"a;",
+"^":"a;",
 gYj:function(){return H.vh(P.SY(null))},
 gAY:function(){return H.vh(P.SY(null))},
 gkZ:function(){return H.vh(P.SY(null))},
 gYK:function(){return H.vh(P.SY(null))},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
-F2:[function(a,b,c){return H.vh(P.SY(null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-PU:[function(a,b){return H.vh(P.SY(null))},"call$2","gtd",4,0,null,65,23],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
+F2:[function(a,b,c){return H.vh(P.SY(null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+rN:[function(a){return H.vh(P.SY(null))},"call$1","gPo",2,0,null,65,[]],
+PU:[function(a,b){return H.vh(P.SY(null))},"call$2","gtd",4,0,null,65,[],23,[]],
 gNy:function(){return H.vh(P.SY(null))},
 gw8:function(){return H.vh(P.SY(null))},
 gJi:function(){return H.vh(P.SY(null))},
 gIf:function(){return H.vh(P.SY(null))},
-gvd:function(){return H.vh(P.SY(null))},
+gUx:function(){return H.vh(P.SY(null))},
 gq4:function(){return H.vh(P.SY(null))},
 gc9:function(){return H.vh(P.SY(null))}},
 Ar:{
-"":"TN;d9,o3,yA,zM,XP<",
+"^":"TN;d9,o3,yA,zM,XP<",
 gHA:function(){return!0},
 gdw:function(){var z=this.yA
 if(z!=null)return z
 z=this.d9
 if(!!z.void){z=$.oj()
 this.yA=z
-return z}if(!("ret" in z)){z=$.Cr()
+return z}if(!("ret" in z)){z=$.P8()
 this.yA=z
 return z}z=H.Jf(this.XP,z.ret)
 this.yA=z
@@ -11952,10 +12310,10 @@
 y=[]
 z=this.d9
 if("args" in z)for(x=z.args,x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]),w=0;x.G();w=v){v=w+1
-y.push(new H.fu(this,x.lo,!1,!1,null,H.YC("argument"+w)))}else w=0
+y.push(new H.fu(this,x.lo,!1,!1,null,C.iH,H.YC("argument"+w)))}else w=0
 if("opt" in z)for(x=z.opt,x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();w=v){v=w+1
-y.push(new H.fu(this,x.lo,!1,!1,null,H.YC("argument"+w)))}if("named" in z)for(x=H.kU(z.named),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){u=x.lo
-y.push(new H.fu(this,z.named[u],!1,!1,null,H.YC(u)))}z=H.VM(new P.Yp(y),[P.Ys])
+y.push(new H.fu(this,x.lo,!1,!1,null,C.iH,H.YC("argument"+w)))}if("named" in z)for(x=H.kU(z.named),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){u=x.lo
+y.push(new H.fu(this,z.named[u],!1,!1,null,C.iH,H.YC(u)))}z=H.VM(new P.Yp(y),[P.Ys])
 this.zM=z
 return z},
 bu:[function(a){var z,y,x,w,v,u
@@ -11982,50 +12340,53 @@
 $isX9:true,
 $isNL:true},
 rh:{
-"":"Tp:390;a",
+"^":"Tp:386;a",
 call$1:[function(a){var z,y,x
 z=init.metadata[a]
 y=this.a
 x=H.w2(y.a.gNy(),J.O6(z))
-return J.UQ(y.a.gw8(),x)},"call$1",null,2,0,null,47,"call"],
+return J.UQ(y.a.gw8(),x)},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 jB:{
-"":"Tp:391;b",
+"^":"Tp:387;b",
 call$1:[function(a){var z,y
 z=this.b.call$1(a)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$iscw)return H.d(z.Nz)
-return z.gCr()},"call$1",null,2,0,null,47,"call"],
+if((typeof z!=="object"||z===null||!y.$isWf)&&(typeof z!=="object"||z===null||!y.$isbl))if(y.n(z,$.P8()))return"dynamic"
+else if(y.n(z,$.oj()))return"void"
+else return"dynamic"
+return z.gCr()},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 ye:{
-"":"Tp:390;",
-call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:385;",
+call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 O1:{
-"":"Tp:390;",
-call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:385;",
+call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 Oh:{
-"":"a;nb",
+"^":"a;nb",
 gB:function(a){return this.nb.X5},
 gl0:function(a){return this.nb.X5===0},
 gor:function(a){return this.nb.X5!==0},
-t:[function(a,b){return this.nb.t(0,b)},"call$1","gIA",2,0,null,42],
-x4:[function(a){return this.nb.x4(a)},"call$1","gV9",2,0,null,42],
-di:[function(a){return this.nb.di(a)},"call$1","gmc",2,0,null,23],
-aN:[function(a,b){return this.nb.aN(0,b)},"call$1","gjw",2,0,null,110],
+t:[function(a,b){return this.nb.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+x4:[function(a){return this.nb.x4(a)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return this.nb.di(a)},"call$1","gmc",2,0,null,23,[]],
+aN:[function(a,b){return this.nb.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){var z=this.nb
 return H.VM(new P.i5(z),[H.Kp(z,0)])},
 gUQ:function(a){var z=this.nb
 return z.gUQ(z)},
-u:[function(a,b,c){return H.kT()},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){return H.kT()},"call$1","gDY",2,0,null,104],
-Rz:[function(a,b){H.kT()},"call$1","gRI",2,0,null,42],
+u:[function(a,b,c){return H.kT()},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){return H.kT()},"call$1","gDY",2,0,null,104,[]],
+Rz:[function(a,b){H.kT()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return H.kT()},"call$0","gyP",0,0,null],
 $isZ0:true,
 static:{kT:[function(){throw H.b(P.f("Cannot modify an unmodifiable Map"))},"call$0","lY",0,0,null]}},
-"":"Sk<"}],["dart._js_names","dart:_js_names",,H,{
-"":"",
+"^":"Sk<"}],["dart._js_names","dart:_js_names",,H,{
+"^":"",
 hY:[function(a,b){var z,y,x,w,v,u,t
 z=H.kU(a)
 y=H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,J.O])
@@ -12033,10 +12394,10 @@
 u=a[v]
 y.u(0,v,u)
 if(w){t=J.rY(v)
-if(t.nC(v,"g"))y.u(0,"s"+t.yn(v,1),u+"=")}}return y},"call$2","BH",4,0,null,142,143],
+if(t.nC(v,"g"))y.u(0,"s"+t.yn(v,1),u+"=")}}return y},"call$2","BH",4,0,null,142,[],143,[]],
 YK:[function(a){var z=H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,J.O])
 a.aN(0,new H.Xh(z))
-return z},"call$1","OX",2,0,null,144],
+return z},"call$1","OX",2,0,null,144,[]],
 kU:[function(a){var z=H.VM((function(victim, hasOwnProperty) {
   var result = [];
   for (var key in victim) {
@@ -12045,34 +12406,37 @@
   return result;
 })(a, Object.prototype.hasOwnProperty),[null])
 z.fixed$length=init
-return z},"call$1","wp",2,0,null,140],
+return z},"call$1","wp",2,0,null,140,[]],
 Xh:{
-"":"Tp:392;a",
-call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,132,383,"call"],
+"^":"Tp:388;a",
+call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,132,[],376,[],"call"],
 $isEH:true}}],["dart.async","dart:async",,P,{
-"":"",
-K2:[function(a,b,c){var z=H.N7()
-z=H.KT(z,[z,z]).BD(a)
-if(z)return a.call$2(b,c)
-else return a.call$1(b)},"call$3","dB",6,0,null,145,146,147],
+"^":"",
 VH:[function(a,b){var z=H.N7()
 z=H.KT(z,[z,z]).BD(a)
 if(z)return b.O8(a)
-else return b.cR(a)},"call$2","p3",4,0,null,145,148],
-BG:[function(){var z,y,x,w
-for(;y=$.P8(),y.av!==y.HV;){z=y.Ux()
-try{z.call$0()}catch(x){H.Ru(x)
-w=C.jn.cU(C.RT.Fq,1000)
-H.cy(w<0?0:w,P.qZ())
-throw x}}$.TH=!1},"call$0","qZ",0,0,107],
-IA:[function(a){$.P8().NZ(0,a)
-if(!$.TH){P.jL(C.RT,P.qZ())
-$.TH=!0}},"call$1","xc",2,0,null,150],
+else return b.cR(a)},"call$2","p3",4,0,null,145,[],146,[]],
+Cx:[function(){var z=$.S6
+for(;z!=null;){z.Ki()
+z=z.gaw()
+$.S6=z}$.k8=null},"call$0","So",0,0,null],
+BG:[function(){var z
+try{P.Cx()}catch(z){H.Ru(z)
+P.jL(C.ny,P.qZ())
+$.S6=$.S6.gaw()
+throw z}},"call$0","qZ",0,0,107],
+IA:[function(a){var z,y
+z=$.k8
+if(z==null){z=new P.OM(a,null)
+$.k8=z
+$.S6=z
+P.jL(C.ny,P.qZ())}else{y=new P.OM(a,null)
+z.aw=y
+$.k8=y}},"call$1","xc",2,0,null,148,[]],
 rb:[function(a){var z
 if(J.de($.X3,C.NU)){$.X3.wr(a)
 return}z=$.X3
-z.wr(z.xi(a,!0))},"call$1","Rf",2,0,null,150],
-Ve:function(a,b,c,d,e,f){return e?H.VM(new P.ly(b,c,d,a,null,0,null),[f]):H.VM(new P.q1(b,c,d,a,null,0,null),[f])},
+z.wr(z.xi(a,!0))},"call$1","Rf",2,0,null,148,[]],
 bK:function(a,b,c,d){var z
 if(c){z=H.VM(new P.dz(b,a,0,null,null,null,null),[d])
 z.SJ=z
@@ -12088,90 +12452,85 @@
 return}catch(u){w=H.Ru(u)
 y=w
 x=new H.XO(u,null)
-$.X3.hk(y,x)}},"call$1","DC",2,0,null,151],
-YE:[function(a){},"call$1","bZ",2,0,152,23],
-SZ:[function(a,b){$.X3.hk(a,b)},function(a){return P.SZ(a,null)},null,"call$2","call$1","AY",2,2,153,77,146,147],
+$.X3.hk(y,x)}},"call$1","DC",2,0,null,149,[]],
+SN:[function(a){},"call$1","bV",2,0,150,23,[]],
+SZ:[function(a,b){$.X3.hk(a,b)},function(a){return P.SZ(a,null)},null,"call$2","call$1","AY",2,2,151,77,152,[],153,[]],
 dL:[function(){return},"call$0","v3",0,0,107],
 FE:[function(a,b,c){var z,y,x,w
 try{b.call$1(a.call$0())}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-c.call$2(z,y)}},"call$3","CV",6,0,null,154,155,156],
-NX:[function(a,b,c,d){var z,y
-z=a.ed()
-y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isb8)z.wM(new P.dR(b,c,d))
-else b.K5(c,d)},"call$4","QD",8,0,null,157,158,146,147],
-TB:[function(a,b){return new P.uR(a,b)},"call$2","cH",4,0,null,157,158],
-Bb:[function(a,b,c){var z,y
-z=a.ed()
-y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isb8)z.wM(new P.QX(b,c))
-else b.rX(c)},"call$3","iB",6,0,null,157,158,23],
+c.call$2(z,y)}},"call$3","CV",6,0,null,154,[],155,[],156,[]],
+NX:[function(a,b,c,d){a.ed()
+b.K5(c,d)},"call$4","QD",8,0,null,157,[],158,[],152,[],153,[]],
+TB:[function(a,b){return new P.uR(a,b)},"call$2","cH",4,0,null,157,[],158,[]],
+Bb:[function(a,b,c){a.ed()
+b.rX(c)},"call$3","iB",6,0,null,157,[],158,[],23,[]],
 rT:function(a,b){var z
 if(J.de($.X3,C.NU))return $.X3.uN(a,b)
 z=$.X3
 return z.uN(a,z.xi(b,!0))},
 jL:[function(a,b){var z=C.jn.cU(a.Fq,1000)
-return H.cy(z<0?0:z,b)},"call$2","et",4,0,null,159,150],
-L2:[function(a,b,c,d,e){a.Gr(new P.pK(d,e))},"call$5","xP",10,0,160,161,162,148,146,147],
+return H.cy(z<0?0:z,b)},"call$2","et",4,0,null,159,[],148,[]],
+PJ:[function(a){var z=$.X3
+$.X3=a
+return z},"call$1","kb",2,0,null,146,[]],
+L2:[function(a,b,c,d,e){a.Gr(new P.pK(d,e))},"call$5","xP",10,0,160,161,[],162,[],146,[],152,[],153,[]],
 T8:[function(a,b,c,d){var z,y
 if(J.de($.X3,c))return d.call$0()
-z=$.X3
-try{$.X3=c
-y=d.call$0()
-return y}finally{$.X3=z}},"call$4","AI",8,0,163,161,162,148,110],
+z=P.PJ(c)
+try{y=d.call$0()
+return y}finally{$.X3=z}},"call$4","AI",8,0,163,161,[],162,[],146,[],110,[]],
 V7:[function(a,b,c,d,e){var z,y
 if(J.de($.X3,c))return d.call$1(e)
-z=$.X3
-try{$.X3=c
-y=d.call$1(e)
-return y}finally{$.X3=z}},"call$5","MM",10,0,164,161,162,148,110,165],
+z=P.PJ(c)
+try{y=d.call$1(e)
+return y}finally{$.X3=z}},"call$5","MM",10,0,164,161,[],162,[],146,[],110,[],165,[]],
 Qx:[function(a,b,c,d,e,f){var z,y
 if(J.de($.X3,c))return d.call$2(e,f)
-z=$.X3
-try{$.X3=c
-y=d.call$2(e,f)
-return y}finally{$.X3=z}},"call$6","l4",12,0,166,161,162,148,110,54,55],
-Ee:[function(a,b,c,d){return d},"call$4","EU",8,0,167,161,162,148,110],
-cQ:[function(a,b,c,d){return d},"call$4","zi",8,0,168,161,162,148,110],
-VI:[function(a,b,c,d){return d},"call$4","uu",8,0,169,161,162,148,110],
-Tk:[function(a,b,c,d){P.IA(C.NU!==c?c.ce(d):d)},"call$4","G2",8,0,170,161,162,148,110],
-h8:[function(a,b,c,d,e){return P.jL(d,C.NU!==c?c.ce(e):e)},"call$5","KF",10,0,171,161,162,148,159,150],
-XB:[function(a,b,c,d){H.qw(d)},"call$4","YM",8,0,172,161,162,148,173],
-CI:[function(a){J.O2($.X3,a)},"call$1","jt",2,0,174,173],
+z=P.PJ(c)
+try{y=d.call$2(e,f)
+return y}finally{$.X3=z}},"call$6","l4",12,0,166,161,[],162,[],146,[],110,[],54,[],55,[]],
+Ee:[function(a,b,c,d){return d},"call$4","EU",8,0,167,161,[],162,[],146,[],110,[]],
+cQ:[function(a,b,c,d){return d},"call$4","zi",8,0,168,161,[],162,[],146,[],110,[]],
+VI:[function(a,b,c,d){return d},"call$4","uu",8,0,169,161,[],162,[],146,[],110,[]],
+Tk:[function(a,b,c,d){P.IA(C.NU!==c?c.ce(d):d)},"call$4","G2",8,0,170,161,[],162,[],146,[],110,[]],
+h8:[function(a,b,c,d,e){return P.jL(d,C.NU!==c?c.ce(e):e)},"call$5","KF",10,0,171,161,[],162,[],146,[],159,[],148,[]],
+XB:[function(a,b,c,d){H.qw(d)},"call$4","YM",8,0,172,161,[],162,[],146,[],173,[]],
+CI:[function(a){J.O2($.X3,a)},"call$1","Fl",2,0,174,173,[]],
 UA:[function(a,b,c,d,e){var z
-$.oK=P.jt()
+$.oK=P.Fl()
 z=P.Py(null,null,null,null,null)
-return new P.cc(c,d,z)},"call$5","hn",10,0,175,161,162,148,176,177],
+return new P.uo(c,d,z)},"call$5","hn",10,0,175,161,[],162,[],146,[],176,[],177,[]],
 Ca:{
-"":"a;kc>,I4<",
+"^":"a;kc>,I4<",
 $isGe:true},
 Ik:{
-"":"O9;Y8"},
+"^":"O9;Y8"},
 JI:{
-"":"yU;Ae@,iE@,SJ@,Y8,dB,o7,Bd,Lj,Gv,lz,Ri",
+"^":"oh;Ae@,iE@,SJ@,Y8,dB,o7,Bd,Lj,Gv,lz,Ri",
 gY8:function(){return this.Y8},
 uR:[function(a){var z=this.Ae
 if(typeof z!=="number")return z.i()
-return(z&1)===a},"call$1","gLM",2,0,null,393],
+return(z&1)===a},"call$1","gLM",2,0,null,389,[]],
 Ac:[function(){var z=this.Ae
 if(typeof z!=="number")return z.w()
-this.Ae=z^1},"call$0","gUe",0,0,null],
+this.Ae=z^1},"call$0","goX",0,0,null],
 gP4:function(){var z=this.Ae
 if(typeof z!=="number")return z.i()
 return(z&2)!==0},
 dK:[function(){var z=this.Ae
 if(typeof z!=="number")return z.k()
-this.Ae=z|4},"call$0","gyL",0,0,null],
+this.Ae=z|4},"call$0","gno",0,0,null],
 gHj:function(){var z=this.Ae
 if(typeof z!=="number")return z.i()
 return(z&4)!==0},
 uO:[function(){return},"call$0","gp4",0,0,107],
 LP:[function(){return},"call$0","gZ9",0,0,107],
-static:{"":"kb,RG,cP"}},
+static:{"^":"FJ,RG,cP"}},
 Ks:{
-"":"a;nL<,QC<,iE@,SJ@",
+"^":"a;iE@,SJ@",
+gRW:function(){return!1},
 gP4:function(){return(this.Gv&2)!==0},
 SL:[function(){var z=this.Ip
 if(z!=null)return z
@@ -12184,35 +12543,17 @@
 z.siE(y)
 y.sSJ(z)
 a.sSJ(a)
-a.siE(a)},"call$1","gOo",2,0,null,157],
-ET:[function(a){var z,y,x
-if((this.Gv&4)!==0)throw H.b(new P.lj("Subscribing to closed stream"))
-z=$.X3
-y=a?1:0
-x=new P.JI(null,null,null,this,null,null,null,z,y,null,null)
-x.$builtinTypeInfo=this.$builtinTypeInfo
-x.SJ=x
-x.iE=x
-y=this.SJ
-x.SJ=y
-x.iE=this
-y.siE(x)
-this.SJ=x
-x.Ae=this.Gv&1
-if(this.iE===x)P.ot(this.nL)
-return x},"call$1","gwk",2,0,null,346],
+a.siE(a)},"call$1","gOo",2,0,null,157,[]],
 j0:[function(a){if(a.giE()===a)return
 if(a.gP4())a.dK()
 else{this.p1(a)
-if((this.Gv&2)===0&&this.iE===this)this.Of()}},"call$1","gOr",2,0,null,157],
-mO:[function(a){},"call$1","gnx",2,0,null,157],
-m4:[function(a){},"call$1","gyb",2,0,null,157],
+if((this.Gv&2)===0&&this.iE===this)this.Of()}},"call$1","gOr",2,0,null,157,[]],
 q7:[function(){if((this.Gv&4)!==0)return new P.lj("Cannot add new events after calling close")
 return new P.lj("Cannot add new events while doing an addStream")},"call$0","gVo",0,0,null],
 h:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
-this.Iv(b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU",void:true,args:[a]}},this.$receiver,"Ks")},237],
-zw:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
-this.pb(a,b)},function(a){return this.zw(a,null)},"JT","call$2","call$1","gXB",2,2,394,77,146,147],
+this.Iv(b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU",void:true,args:[a]}},this.$receiver,"Ks")},231,[]],
+fDe:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
+this.pb(a,b)},function(a){return this.fDe(a,null)},"JT","call$2","call$1","gXB",2,2,390,77,152,[],153,[]],
 cO:[function(a){var z,y
 z=this.Gv
 if((z&4)!==0)return this.Ip
@@ -12221,8 +12562,8 @@
 y=this.SL()
 this.SY()
 return y},"call$0","gJK",0,0,null],
-Rg:[function(a,b){this.Iv(b)},"call$1","gHR",2,0,null,237],
-V8:[function(a,b){this.pb(a,b)},"call$2","grd",4,0,null,146,147],
+Rg:[function(a,b){this.Iv(b)},"call$1","gHR",2,0,null,231,[]],
+V8:[function(a,b){this.pb(a,b)},"call$2","grd",4,0,null,152,[],153,[]],
 Qj:[function(){var z=this.WX
 this.WX=null
 this.Gv=this.Gv&4294967287
@@ -12246,101 +12587,93 @@
 y.sAe(z&4294967293)
 y=w}else y=y.giE()
 this.Gv=this.Gv&4294967293
-if(this.iE===this)this.Of()},"call$1","gxd",2,0,null,378],
+if(this.iE===this)this.Of()},"call$1","gxd",2,0,null,371,[]],
 Of:[function(){if((this.Gv&4)!==0&&this.Ip.Gv===0)this.Ip.OH(null)
 P.ot(this.QC)},"call$0","gVg",0,0,null]},
 dz:{
-"":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
+"^":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
 Iv:[function(a){var z=this.iE
 if(z===this)return
 if(z.giE()===this){this.Gv=this.Gv|2
 this.iE.Rg(0,a)
 this.Gv=this.Gv&4294967293
 if(this.iE===this)this.Of()
-return}this.nE(new P.tK(this,a))},"call$1","gm9",2,0,null,237],
+return}this.nE(new P.tK(this,a))},"call$1","gm9",2,0,null,231,[]],
 pb:[function(a,b){if(this.iE===this)return
-this.nE(new P.OR(this,a,b))},"call$2","gTb",4,0,null,146,147],
+this.nE(new P.OR(this,a,b))},"call$2","gTb",4,0,null,152,[],153,[]],
 SY:[function(){if(this.iE!==this)this.nE(new P.Bg(this))
 else this.Ip.OH(null)},"call$0","gXm",0,0,null]},
 tK:{
-"":"Tp;a,b",
-call$1:[function(a){a.Rg(0,this.b)},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){a.Rg(0,this.b)},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"DU",args:[[P.KA,a]]}},this.a,"dz")}},
 OR:{
-"":"Tp;a,b,c",
-call$1:[function(a){a.V8(this.b,this.c)},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a,b,c",
+call$1:[function(a){a.V8(this.b,this.c)},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"DU",args:[[P.KA,a]]}},this.a,"dz")}},
 Bg:{
-"":"Tp;a",
-call$1:[function(a){a.Qj()},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a",
+call$1:[function(a){a.Qj()},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Zj",args:[[P.JI,a]]}},this.a,"dz")}},
 DL:{
-"":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
+"^":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
 Iv:[function(a){var z,y
 for(z=this.iE;z!==this;z=z.giE()){y=new P.LV(a,null)
 y.$builtinTypeInfo=[null]
-z.w6(y)}},"call$1","gm9",2,0,null,237],
+z.w6(y)}},"call$1","gm9",2,0,null,231,[]],
 pb:[function(a,b){var z
-for(z=this.iE;z!==this;z=z.giE())z.w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,146,147],
+for(z=this.iE;z!==this;z=z.giE())z.w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,152,[],153,[]],
 SY:[function(){var z=this.iE
 if(z!==this)for(;z!==this;z=z.giE())z.w6(C.Wj)
 else this.Ip.OH(null)},"call$0","gXm",0,0,null]},
 b8:{
-"":"a;",
+"^":"a;",
 $isb8:true},
 Ia:{
-"":"a;"},
+"^":"a;"},
 Zf:{
-"":"Ia;MM",
+"^":"Ia;MM",
 oo:[function(a,b){var z=this.MM
 if(z.Gv!==0)throw H.b(P.w("Future already completed"))
-z.OH(b)},function(a){return this.oo(a,null)},"tZ","call$1","call$0","gv6",0,2,395,77,23],
+z.OH(b)},function(a){return this.oo(a,null)},"tZ","call$1","call$0","gv6",0,2,391,77,23,[]],
 w0:[function(a,b){var z
 if(a==null)throw H.b(new P.AT("Error must not be null"))
 z=this.MM
 if(z.Gv!==0)throw H.b(new P.lj("Future already completed"))
-z.CG(a,b)},function(a){return this.w0(a,null)},"pm","call$2","call$1","gYJ",2,2,394,77,146,147]},
+z.CG(a,b)},function(a){return this.w0(a,null)},"pm","call$2","call$1","gYJ",2,2,390,77,152,[],153,[]]},
 vs:{
-"":"a;Gv,Lj<,jk,BQ@,OY,As,qV,o4",
+"^":"a;Gv,Lj<,jk,BQ@,OY,As,qV,o4",
 gcg:function(){return this.Gv>=4},
 gNm:function(){return this.Gv===8},
 swG:function(a){if(a)this.Gv=2
 else this.Gv=0},
 gO1:function(){return this.Gv===2?null:this.OY},
-GP:function(a){return this.gO1().call$1(a)},
 gyK:function(){return this.Gv===2?null:this.As},
 go7:function(){return this.Gv===2?null:this.qV},
 gIa:function(){return this.Gv===2?null:this.o4},
-xY:function(){return this.gIa().call$0()},
 Rx:[function(a,b){var z,y
 z=$.X3
 y=H.VM(new P.vs(0,z,null,null,z.cR(a),null,P.VH(b,$.X3),null),[null])
 this.au(y)
-return y},function(a){return this.Rx(a,null)},"ml","call$2$onError",null,"grf",2,3,null,77,110,156],
+return y},function(a){return this.Rx(a,null)},"ml","call$2$onError",null,"grf",2,3,null,77,110,[],156,[]],
 yd:[function(a,b){var z,y,x
 z=$.X3
 y=P.VH(a,z)
 x=H.VM(new P.vs(0,z,null,null,null,$.X3.cR(b),y,null),[null])
 this.au(x)
-return x},function(a){return this.yd(a,null)},"OA","call$2$test",null,"gue",2,3,null,77,156,379],
-wM:[function(a){var z,y
-z=$.X3
-y=new P.vs(0,z,null,null,null,null,null,z.Al(a))
-y.$builtinTypeInfo=this.$builtinTypeInfo
-this.au(y)
-return y},"call$1","gE1",2,0,null,378],
+return x},function(a){return this.yd(a,null)},"OA","call$2$test",null,"gue",2,3,null,77,156,[],372,[]],
 gDL:function(){return this.jk},
 gcG:function(){return this.jk},
 Am:[function(a){this.Gv=4
-this.jk=a},"call$1","gAu",2,0,null,23],
+this.jk=a},"call$1","gAu",2,0,null,23,[]],
 E6:[function(a,b){this.Gv=8
-this.jk=new P.Ca(a,b)},"call$2","gM6",4,0,null,146,147],
+this.jk=new P.Ca(a,b)},"call$2","gM6",4,0,null,152,[],153,[]],
 au:[function(a){if(this.Gv>=4)this.Lj.wr(new P.da(this,a))
 else{a.sBQ(this.jk)
-this.jk=a}},"call$1","gXA",2,0,null,298],
+this.jk=a}},"call$1","gXA",2,0,null,292,[]],
 L3:[function(){var z,y,x
 z=this.jk
 this.jk=null
@@ -12351,10 +12684,10 @@
 if(typeof a==="object"&&a!==null&&!!z.$isb8){P.GZ(a,this)
 return}y=this.L3()
 this.Am(a)
-P.HZ(this,y)},"call$1","gJJ",2,0,null,23],
+P.HZ(this,y)},"call$1","gJJ",2,0,null,23,[]],
 K5:[function(a,b){var z=this.L3()
 this.E6(a,b)
-P.HZ(this,z)},function(a){return this.K5(a,null)},"Lp","call$2","call$1","gbY",2,2,153,77,146,147],
+P.HZ(this,z)},function(a){return this.K5(a,null)},"Lp","call$2","call$1","gbY",2,2,151,77,152,[],153,[]],
 OH:[function(a){var z,y
 z=J.x(a)
 y=typeof a==="object"&&a!==null&&!!z.$isb8
@@ -12363,24 +12696,24 @@
 if(z){this.rX(a)
 return}if(this.Gv!==0)H.vh(P.w("Future already completed"))
 this.Gv=1
-this.Lj.wr(new P.rH(this,a))},"call$1","gZV",2,0,null,23],
+this.Lj.wr(new P.rH(this,a))},"call$1","gZV",2,0,null,23,[]],
 CG:[function(a,b){if(this.Gv!==0)H.vh(new P.lj("Future already completed"))
 this.Gv=1
-this.Lj.wr(new P.ZL(this,a,b))},"call$2","glC",4,0,null,146,147],
+this.Lj.wr(new P.ZL(this,a,b))},"call$2","glC",4,0,null,152,[],153,[]],
 L7:function(a,b){this.OH(a)},
 $isvs:true,
 $isb8:true,
-static:{"":"ewM,JE,C3n,Cd,dh",Dt:function(a){return H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[a])},GZ:[function(a,b){var z
+static:{"^":"ewM,JE,C3n,oN1,NK",Dt:function(a){return H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[a])},GZ:[function(a,b){var z
 b.swG(!0)
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isvs)if(a.Gv>=4)P.HZ(a,b)
 else a.au(b)
-else a.Rx(new P.xw(b),new P.dm(b))},"call$2","mX",4,0,null,27,74],yE:[function(a,b){var z
+else a.Rx(new P.xw(b),new P.dm(b))},"call$2","mX",4,0,null,27,[],74,[]],yE:[function(a,b){var z
 do{z=b.gBQ()
 b.sBQ(null)
 P.HZ(a,b)
 if(z!=null){b=z
-continue}else break}while(!0)},"call$2","cN",4,0,null,27,149],HZ:[function(a,b){var z,y,x,w,v,u,t,s,r
+continue}else break}while(!0)},"call$2","cN",4,0,null,27,[],147,[]],HZ:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 z.e=a
 for(y=a;!0;){x={}
@@ -12390,133 +12723,167 @@
 z.e.gLj().hk(J.w8(v),v.gI4())
 return}if(b==null)return
 if(b.gBQ()!=null){P.yE(z.e,b)
-return}if(w&&!z.e.gLj().fC(b.gLj())){v=z.e.gcG()
+return}u=b.gLj()
+if(w&&!z.e.gLj().fC(u)){v=z.e.gcG()
 z.e.gLj().hk(J.w8(v),v.gI4())
-return}y=$.X3
-u=b.gLj()
-if(y==null?u!=null:y!==u){b.gLj().Gr(new P.mi(z,b))
-return}x.b=null
+return}t=$.X3
+if(t==null?u!=null:t!==u)$.X3=u
+else t=null
+x.b=null
 x.c=null
 x.d=!1
-b.gLj().Gr(new P.jb(z,x,w,b))
+if(!w)if(b.gO1()!=null)x.b=new P.rq(x,z,b,u).call$0()
+else{x.c=z.e.gDL()
+x.b=!0}else new P.RW(z,x,b,u).call$0()
+if(b.gIa()!=null)new P.RT(z,x,w,b,u).call$0()
+if(t!=null)$.X3=t
 if(x.d)return
 y=x.b===!0
-if(y){u=x.c
-t=J.x(u)
-t=typeof u==="object"&&u!==null&&!!t.$isb8
-u=t}else u=!1
-if(u){s=x.c
-y=J.x(s)
-if(typeof s==="object"&&s!==null&&!!y.$isvs&&s.Gv>=4){b.swG(!0)
-z.e=s
-y=s
-continue}P.GZ(s,b)
-return}if(y){r=b.L3()
-b.Am(x.c)}else{r=b.L3()
+if(y){s=x.c
+r=J.x(s)
+r=typeof s==="object"&&s!==null&&!!r.$isb8
+s=r}else s=!1
+if(s){q=x.c
+y=J.x(q)
+if(typeof q==="object"&&q!==null&&!!y.$isvs&&q.Gv>=4){b.swG(!0)
+z.e=q
+y=q
+continue}P.GZ(q,b)
+return}if(y){p=b.L3()
+b.Am(x.c)}else{p=b.L3()
 v=x.c
 b.E6(J.w8(v),v.gI4())}z.e=b
 y=b
-b=r}},"call$2","WY",4,0,null,27,149]}},
+b=p}},"call$2","WY",4,0,null,27,[],147,[]]}},
 da:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){P.HZ(this.a,this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 xw:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.rX(a)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.rX(a)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 dm:{
-"":"Tp:396;b",
-call$2:[function(a,b){this.b.K5(a,b)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,146,147,"call"],
+"^":"Tp:392;b",
+call$2:[function(a,b){this.b.K5(a,b)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,152,[],153,[],"call"],
 $isEH:true},
 rH:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){this.a.rX(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ZL:{
-"":"Tp:108;a,b,c",
+"^":"Tp:108;a,b,c",
 call$0:[function(){this.a.K5(this.b,this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-mi:{
-"":"Tp:108;c,d",
-call$0:[function(){P.HZ(this.c.e,this.d)},"call$0",null,0,0,null,"call"],
+rq:{
+"^":"Tp:366;b,c,d,e",
+call$0:[function(){var z,y,x,w
+try{this.b.c=this.e.FI(this.d.gO1(),this.c.e.gDL())
+return!0}catch(x){w=H.Ru(x)
+z=w
+y=new H.XO(x,null)
+this.b.c=new P.Ca(z,y)
+return!1}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-jb:{
-"":"Tp:108;c,b,e,f",
+RW:{
+"^":"Tp:107;c,b,f,UI",
 call$0:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
-z={}
-try{r=this.c
-if(!this.e){y=r.e.gDL()
-q=this.f
-p=this.b
-if(q.gO1()!=null){p.c=q.GP(y)
-p.b=!0}else{p.c=y
-p.b=!0}}else{x=r.e.gcG()
-q=this.f
-w=q.gyK()
-v=!0
-if(w!=null)v=w.call$1(J.w8(x))
-p=v===!0&&q.go7()!=null
-o=this.b
-if(p){u=q.go7()
-o.c=P.K2(u,J.w8(x),x.gI4())
-o.b=!0}else{o.c=x
-o.b=!1}p=o}if(q.gIa()!=null){n=q.xY()
-z.a=n
-o=J.x(n)
-if(typeof n==="object"&&n!==null&&!!o.$isb8){q.swG(!0)
-z.a.Rx(new P.wB(r,q),new P.Pu(z,q))
-p.d=!0}}}catch(m){z=H.Ru(m)
-t=z
-s=new H.XO(m,null)
-if(this.e){z=J.w8(this.c.e.gcG())
-r=t
-r=z==null?r==null:z===r
-z=r}else z=!1
+z=this.c.e.gcG()
+r=this.f
+y=r.gyK()
+x=!0
+if(y!=null)try{x=this.UI.FI(y,J.w8(z))}catch(q){r=H.Ru(q)
+w=r
+v=new H.XO(q,null)
+r=J.w8(z)
+p=w
+o=(r==null?p==null:r===p)?z:new P.Ca(w,v)
 r=this.b
-if(z)r.c=this.c.e.gcG()
-else r.c=new P.Ca(t,s)
+r.c=o
+r.b=!1
+return}u=r.go7()
+if(x===!0&&u!=null){try{r=u
+p=H.N7()
+p=H.KT(p,[p,p]).BD(r)
+n=this.UI
+m=this.b
+if(p)m.c=n.mg(u,J.w8(z),z.gI4())
+else m.c=n.FI(u,J.w8(z))}catch(q){r=H.Ru(q)
+t=r
+s=new H.XO(q,null)
+r=J.w8(z)
+p=t
+o=(r==null?p==null:r===p)?z:new P.Ca(t,s)
+r=this.b
+r.c=o
+r.b=!1
+return}this.b.b=!0}else{r=this.b
+r.c=z
 r.b=!1}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-wB:{
-"":"Tp:229;c,UI",
-call$1:[function(a){P.HZ(this.c.e,this.UI)},"call$1",null,2,0,null,397,"call"],
+RT:{
+"^":"Tp:107;c,b,bK,Gq,Rm",
+call$0:[function(){var z,y,x,w,v,u
+z={}
+z.a=null
+try{z.a=this.Rm.Gr(this.Gq.gIa())}catch(w){v=H.Ru(w)
+y=v
+x=new H.XO(w,null)
+if(this.bK){v=J.w8(this.c.e.gcG())
+u=y
+u=v==null?u==null:v===u
+v=u}else v=!1
+u=this.b
+if(v)u.c=this.c.e.gcG()
+else u.c=new P.Ca(y,x)
+u.b=!1}v=z.a
+u=J.x(v)
+if(typeof v==="object"&&v!==null&&!!u.$isb8){v=this.Gq
+v.swG(!0)
+this.b.d=!0
+z.a.Rx(new P.jZ(this.c,v),new P.FZ(z,v))}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-Pu:{
-"":"Tp:396;a,bK",
+jZ:{
+"^":"Tp:223;c,w3",
+call$1:[function(a){P.HZ(this.c.e,this.w3)},"call$1",null,2,0,null,393,[],"call"],
+$isEH:true},
+FZ:{
+"^":"Tp:392;a,HZ",
 call$2:[function(a,b){var z,y,x,w
 z=this.a
 y=z.a
 x=J.x(y)
 if(typeof y!=="object"||y===null||!x.$isvs){w=P.Dt(null)
 z.a=w
-w.E6(a,b)}P.HZ(z.a,this.bK)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,146,147,"call"],
+w.E6(a,b)}P.HZ(z.a,this.HZ)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,152,[],153,[],"call"],
 $isEH:true},
+OM:{
+"^":"a;FR,aw@",
+Ki:function(){return this.FR.call$0()}},
 qh:{
-"":"a;",
-ez:[function(a,b){return H.VM(new P.t3(b,this),[H.ip(this,"qh",0),null])},"call$1","gIr",2,0,null,398],
+"^":"a;",
+ez:[function(a,b){return H.VM(new P.t3(b,this),[H.ip(this,"qh",0),null])},"call$1","gIr",2,0,null,394,[]],
 tg:[function(a,b){var z,y
 z={}
 y=P.Dt(J.kn)
 z.a=null
-z.a=this.KR(new P.YJ(z,this,b,y),!0,new P.DO(y),y.gbY())
-return y},"call$1","gdj",2,0,null,102],
+z.a=this.KR(new P.tG(z,this,b,y),!0,new P.zn(y),y.gbY())
+return y},"call$1","gdj",2,0,null,102,[]],
 aN:[function(a,b){var z,y
 z={}
 y=P.Dt(null)
 z.a=null
 z.a=this.KR(new P.lz(z,this,b,y),!0,new P.M4(y),y.gbY())
-return y},"call$1","gjw",2,0,null,378],
+return y},"call$1","gjw",2,0,null,371,[]],
 Vr:[function(a,b){var z,y
 z={}
 y=P.Dt(J.kn)
 z.a=null
 z.a=this.KR(new P.Jp(z,this,b,y),!0,new P.eN(y),y.gbY())
-return y},"call$1","gG2",2,0,null,379],
+return y},"call$1","gG2",2,0,null,372,[]],
 gB:function(a){var z,y
 z={}
-y=new P.vs(0,$.X3,null,null,null,null,null,null)
-y.$builtinTypeInfo=[J.im]
+y=P.Dt(J.im)
 z.a=0
 this.KR(new P.PI(z),!0,new P.uO(z,y),y.gbY())
 return y},
@@ -12533,7 +12900,7 @@
 return y},"call$0","gRV",0,0,null],
 eR:[function(a,b){var z=H.VM(new P.dq(b,this),[null])
 z.U6(this,b,null)
-return z},"call$1","gVQ",2,0,null,122],
+return z},"call$1","gZo",2,0,null,122,[]],
 gtH:function(a){var z,y
 z={}
 y=P.Dt(H.ip(this,"qh",0))
@@ -12554,281 +12921,202 @@
 y=P.Dt(H.ip(this,"qh",0))
 z.b=null
 z.b=this.KR(new P.ii(z,this,y),!0,new P.ib(z,y),y.gbY())
-return y},"call$1","goY",2,0,null,47],
+return y},"call$1","goY",2,0,null,47,[]],
 $isqh:true},
-YJ:{
-"":"Tp;a,b,c,d",
+tG:{
+"^":"Tp;a,b,c,d",
 call$1:[function(a){var z,y
 z=this.a
 y=this.d
-P.FE(new P.jv(this.c,a),new P.LB(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,"call"],
+P.FE(new P.jv(this.c,a),new P.LB(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 jv:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return J.de(this.f,this.e)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 LB:{
-"":"Tp:374;a,UI",
-call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,399,"call"],
+"^":"Tp:367;a,UI",
+call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,395,[],"call"],
 $isEH:true},
-DO:{
-"":"Tp:108;bK",
+zn:{
+"^":"Tp:108;bK",
 call$0:[function(){this.bK.rX(!1)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 lz:{
-"":"Tp;a,b,c,d",
-call$1:[function(a){P.FE(new P.Rl(this.c,a),new P.Jb(),P.TB(this.a.a,this.d))},"call$1",null,2,0,null,124,"call"],
+"^":"Tp;a,b,c,d",
+call$1:[function(a){P.FE(new P.Rl(this.c,a),new P.Jb(),P.TB(this.a.a,this.d))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 Rl:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return this.e.call$1(this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Jb:{
-"":"Tp:229;",
-call$1:[function(a){},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 M4:{
-"":"Tp:108;UI",
+"^":"Tp:108;UI",
 call$0:[function(){this.UI.rX(null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Jp:{
-"":"Tp;a,b,c,d",
+"^":"Tp;a,b,c,d",
 call$1:[function(a){var z,y
 z=this.a
 y=this.d
-P.FE(new P.h7(this.c,a),new P.pr(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,"call"],
+P.FE(new P.h7(this.c,a),new P.pr(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 h7:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return this.e.call$1(this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 pr:{
-"":"Tp:374;a,UI",
-call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,399,"call"],
+"^":"Tp:367;a,UI",
+call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,395,[],"call"],
 $isEH:true},
 eN:{
-"":"Tp:108;bK",
+"^":"Tp:108;bK",
 call$0:[function(){this.bK.rX(!1)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 PI:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
-z.a=z.a+1},"call$1",null,2,0,null,240,"call"],
+z.a=z.a+1},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 uO:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){this.b.rX(this.a.a)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 j4:{
-"":"Tp:229;a,b",
-call$1:[function(a){P.Bb(this.a.a,this.b,!1)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){P.Bb(this.a.a,this.b,!1)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 i9:{
-"":"Tp:108;c",
+"^":"Tp:108;c",
 call$0:[function(){this.c.rX(!0)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 VV:{
-"":"Tp;a,b",
-call$1:[function(a){this.b.push(a)},"call$1",null,2,0,null,237,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){this.b.push(a)},"call$1",null,2,0,null,231,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.a,"qh")}},
 Dy:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){this.d.rX(this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 lU:{
-"":"Tp;a,b,c",
-call$1:[function(a){P.Bb(this.a.a,this.c,a)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp;a,b,c",
+call$1:[function(a){P.Bb(this.a.a,this.c,a)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 OC:{
-"":"Tp:108;d",
+"^":"Tp:108;d",
 call$0:[function(){this.d.Lp(new P.lj("No elements"))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 UH:{
-"":"Tp;a,b",
+"^":"Tp;a,b",
 call$1:[function(a){var z=this.a
 z.b=!0
-z.a=a},"call$1",null,2,0,null,23,"call"],
+z.a=a},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 Z5:{
-"":"Tp:108;a,c",
+"^":"Tp:108;a,c",
 call$0:[function(){var z=this.a
 if(z.b){this.c.rX(z.a)
 return}this.c.Lp(new P.lj("No elements"))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ii:{
-"":"Tp;a,b,c",
+"^":"Tp;a,b,c",
 call$1:[function(a){var z=this.a
 if(J.de(z.a,0)){P.Bb(z.b,this.c,a)
-return}z.a=J.xH(z.a,1)},"call$1",null,2,0,null,23,"call"],
+return}z.a=J.xH(z.a,1)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 ib:{
-"":"Tp:108;a,d",
+"^":"Tp:108;a,d",
 call$0:[function(){this.d.Lp(new P.bJ("value "+H.d(this.a.a)))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 MO:{
-"":"a;",
+"^":"a;",
 $isMO:true},
-ms:{
-"":"a;",
-gh6:function(){if((this.Gv&8)===0)return this.iP
-return this.iP.gmT()},
-kW:[function(){var z,y
-if((this.Gv&8)===0){z=this.iP
-if(z==null){z=new P.Qk(null,null,0)
-this.iP=z}return z}y=this.iP
-y.gmT()
-return y.gmT()},"call$0","gUo",0,0,null],
-gEe:function(){if((this.Gv&8)!==0)return this.iP.gmT()
-return this.iP},
-BW:[function(){if((this.Gv&4)!==0)return new P.lj("Cannot add event after closing")
-return new P.lj("Cannot add event while adding a stream")},"call$0","gCi",0,0,null],
-h:[function(a,b){if(this.Gv>=4)throw H.b(this.BW())
-this.Rg(0,b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU6",void:true,args:[a]}},this.$receiver,"ms")},23],
-cO:[function(a){var z,y
-z=this.Gv
-if((z&4)!==0)return this.Ip
-if(z>=4)throw H.b(this.BW())
-z|=4
-this.Gv=z
-if(this.Ip==null){y=P.Dt(null)
-this.Ip=y
-if((z&2)!==0)y.rX(null)}z=this.Gv
-if((z&1)!==0)this.SY()
-else if((z&3)===0)this.kW().h(0,C.Wj)
-return this.Ip},"call$0","gJK",0,0,null],
-Rg:[function(a,b){var z=this.Gv
-if((z&1)!==0)this.Iv(b)
-else if((z&3)===0)this.kW().h(0,H.VM(new P.LV(b,null),[H.ip(this,"ms",0)]))},"call$1","gHR",2,0,null,23],
-V8:[function(a,b){var z=this.Gv
-if((z&1)!==0)this.pb(a,b)
-else if((z&3)===0)this.kW().h(0,new P.DS(a,b,null))},"call$2","grd",4,0,null,146,147],
-Qj:[function(){var z=this.iP
-this.iP=z.gmT()
-this.Gv=this.Gv&4294967287
-z.tZ(0)},"call$0","gS2",0,0,null],
-ET:[function(a){var z,y,x,w,v
-if((this.Gv&3)!==0)throw H.b(new P.lj("Stream has already been listened to."))
-z=$.X3
-y=a?1:0
-x=H.VM(new P.yU(this,null,null,null,z,y,null,null),[null])
-w=this.gh6()
-y=this.Gv|1
-this.Gv=y
-if((y&8)!==0){v=this.iP
-v.smT(x)
-v.QE()}else this.iP=x
-x.WN(w)
-x.J7(new P.UO(this))
-return x},"call$1","gwk",2,0,null,346],
-j0:[function(a){var z,y
-if((this.Gv&8)!==0)this.iP.ed()
-this.iP=null
-this.Gv=this.Gv&4294967286|2
-z=new P.Bc(this)
-y=P.ot(this.gQC())
-if(y!=null)y=y.wM(z)
-else z.call$0()
-return y},"call$1","gOr",2,0,null,157],
-mO:[function(a){if((this.Gv&8)!==0)this.iP.yy(0)
-P.ot(this.gp4())},"call$1","gnx",2,0,null,157],
-m4:[function(a){if((this.Gv&8)!==0)this.iP.QE()
-P.ot(this.gZ9())},"call$1","gyb",2,0,null,157]},
-UO:{
-"":"Tp:108;a",
-call$0:[function(){P.ot(this.a.gnL())},"call$0",null,0,0,null,"call"],
-$isEH:true},
-Bc:{
-"":"Tp:107;a",
-call$0:[function(){var z=this.a.Ip
-if(z!=null&&z.Gv===0)z.OH(null)},"call$0",null,0,0,null,"call"],
-$isEH:true},
-vp:{
-"":"a;",
-Iv:[function(a){this.gEe().Rg(0,a)},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){this.gEe().V8(a,b)},"call$2","gTb",4,0,null,146,147],
-SY:[function(){this.gEe().Qj()},"call$0","gXm",0,0,null]},
-lk:{
-"":"a;",
-Iv:[function(a){this.gEe().w6(H.VM(new P.LV(a,null),[null]))},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){this.gEe().w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,146,147],
-SY:[function(){this.gEe().w6(C.Wj)},"call$0","gXm",0,0,null]},
-q1:{
-"":"ZzD;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},
-ZzD:{
-"":"ms+lk;"},
-ly:{
-"":"fE;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},
-fE:{
-"":"ms+vp;"},
 O9:{
-"":"ez;Y8",
-w4:[function(a){return this.Y8.ET(a)},"call$1","gvC",2,0,null,346],
+"^":"ez;",
+w4:[function(a){var z,y,x,w
+z=this.Y8
+if((z.Gv&4)!==0)H.vh(new P.lj("Subscribing to closed stream"))
+y=$.X3
+x=a?1:0
+w=H.VM(new P.JI(null,null,null,z,null,null,null,y,x,null,null),[H.Kp(z,0)])
+w.SJ=w
+w.iE=w
+x=z.SJ
+w.SJ=x
+w.iE=z
+x.siE(w)
+z.SJ=w
+w.Ae=z.Gv&1
+if(z.iE===w)P.ot(z.nL)
+return w},"call$1","gvC",2,0,null,396,[]],
 giO:function(a){return(H.eQ(this.Y8)^892482866)>>>0},
 n:[function(a,b){var z
 if(b==null)return!1
 if(this===b)return!0
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isO9)return!1
-return b.Y8===this.Y8},"call$1","gUJ",2,0,null,104],
+return b.Y8===this.Y8},"call$1","gUJ",2,0,null,104,[]],
 $isO9:true},
-yU:{
-"":"KA;Y8<,dB,o7,Bd,Lj,Gv,lz,Ri",
-tA:[function(){return this.gY8().j0(this)},"call$0","gQC",0,0,400],
-uO:[function(){this.gY8().mO(this)},"call$0","gp4",0,0,107],
-LP:[function(){this.gY8().m4(this)},"call$0","gZ9",0,0,107]},
+oh:{
+"^":"KA;Y8<",
+tA:[function(){return this.gY8().j0(this)},"call$0","gQC",0,0,null],
+uO:[function(){this.gY8()},"call$0","gp4",0,0,107],
+LP:[function(){this.gY8()},"call$0","gZ9",0,0,107]},
 nP:{
-"":"a;"},
+"^":"a;"},
 KA:{
-"":"a;dB,o7<,Bd,Lj<,Gv,lz,Ri",
-WN:[function(a){if(a==null)return
-this.Ri=a
-if(!a.gl0(a)){this.Gv=(this.Gv|64)>>>0
-this.Ri.t2(this)}},"call$1","gNl",2,0,null,401],
-fe:[function(a){this.dB=this.Lj.cR(a)},"call$1","gqd",2,0,null,402],
+"^":"a;dB,o7<,Bd,Lj<,Gv,lz,Ri",
+fe:[function(a){this.dB=this.Lj.cR(a)},"call$1","gqd",2,0,null,397,[]],
 fm:[function(a,b){if(b==null)b=P.AY()
-this.o7=P.VH(b,this.Lj)},"call$1","geO",2,0,null,29],
+this.o7=P.VH(b,this.Lj)},"call$1","geO",2,0,null,29,[]],
 y5:[function(a){if(a==null)a=P.v3()
-this.Bd=this.Lj.Al(a)},"call$1","gNS",2,0,null,403],
-nB:[function(a,b){var z=this.Gv
+this.Bd=this.Lj.Al(a)},"call$1","gNS",2,0,null,398,[]],
+nB:[function(a,b){var z,y,x
+z=this.Gv
 if((z&8)!==0)return
-this.Gv=(z+128|4)>>>0
-if(z<128&&this.Ri!=null)this.Ri.FK()
-if((z&4)===0&&(this.Gv&32)===0)this.J7(this.gp4())},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,404],
+y=(z+128|4)>>>0
+this.Gv=y
+if(z<128&&this.Ri!=null){x=this.Ri
+if(x.Gv===1)x.Gv=3}if((z&4)===0&&(y&32)===0)this.J7(this.gp4())},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,399,[]],
 QE:[function(){var z=this.Gv
 if((z&8)!==0)return
 if(z>=128){z-=128
 this.Gv=z
-if(z<128){if((z&64)!==0){z=this.Ri
-z=!z.gl0(z)}else z=!1
-if(z)this.Ri.t2(this)
-else{z=(this.Gv&4294967291)>>>0
+if(z<128)if((z&64)!==0&&this.Ri.N6!=null)this.Ri.t2(this)
+else{z=(z&4294967291)>>>0
 this.Gv=z
-if((z&32)===0)this.J7(this.gZ9())}}}},"call$0","gDQ",0,0,null],
+if((z&32)===0)this.J7(this.gZ9())}}},"call$0","gDQ",0,0,null],
 ed:[function(){var z=(this.Gv&4294967279)>>>0
 this.Gv=z
 if((z&8)!==0)return this.lz
 this.Ek()
 return this.lz},"call$0","gZS",0,0,null],
-Ek:[function(){var z=(this.Gv|8)>>>0
+gRW:function(){return this.Gv>=128},
+Ek:[function(){var z,y
+z=(this.Gv|8)>>>0
 this.Gv=z
-if((z&64)!==0)this.Ri.FK()
-if((this.Gv&32)===0)this.Ri=null
+if((z&64)!==0){y=this.Ri
+if(y.Gv===1)y.Gv=3}if((z&32)===0)this.Ri=null
 this.lz=this.tA()},"call$0","gbz",0,0,null],
 Rg:[function(a,b){var z=this.Gv
 if((z&8)!==0)return
 if(z<32)this.Iv(b)
-else this.w6(H.VM(new P.LV(b,null),[null]))},"call$1","gHR",2,0,null,237],
+else this.w6(H.VM(new P.LV(b,null),[null]))},"call$1","gHR",2,0,null,231,[]],
 V8:[function(a,b){var z=this.Gv
 if((z&8)!==0)return
 if(z<32)this.pb(a,b)
-else this.w6(new P.DS(a,b,null))},"call$2","grd",4,0,null,146,147],
+else this.w6(new P.DS(a,b,null))},"call$2","grd",4,0,null,152,[],153,[]],
 Qj:[function(){var z=this.Gv
 if((z&8)!==0)return
 z=(z|2)>>>0
@@ -12837,7 +13125,7 @@
 else this.w6(C.Wj)},"call$0","gS2",0,0,null],
 uO:[function(){},"call$0","gp4",0,0,107],
 LP:[function(){},"call$0","gZ9",0,0,107],
-tA:[function(){},"call$0","gQC",0,0,400],
+tA:[function(){},"call$0","gQC",0,0,null],
 w6:[function(a){var z,y
 z=this.Ri
 if(z==null){z=new P.Qk(null,null,0)
@@ -12845,56 +13133,47 @@
 y=this.Gv
 if((y&64)===0){y=(y|64)>>>0
 this.Gv=y
-if(y<128)this.Ri.t2(this)}},"call$1","gnX",2,0,null,405],
+if(y<128)this.Ri.t2(this)}},"call$1","gnX",2,0,null,400,[]],
 Iv:[function(a){var z=this.Gv
 this.Gv=(z|32)>>>0
 this.Lj.m1(this.dB,a)
 this.Gv=(this.Gv&4294967263)>>>0
-this.Kl((z&4)!==0)},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){var z,y,x
+this.Kl((z&4)!==0)},"call$1","gm9",2,0,null,231,[]],
+pb:[function(a,b){var z,y
 z=this.Gv
 y=new P.Vo(this,a,b)
 if((z&1)!==0){this.Gv=(z|16)>>>0
 this.Ek()
-z=this.lz
-x=J.x(z)
-if(typeof z==="object"&&z!==null&&!!x.$isb8)z.wM(y)
-else y.call$0()}else{y.call$0()
-this.Kl((z&4)!==0)}},"call$2","gTb",4,0,null,146,147],
-SY:[function(){var z,y,x
-z=new P.qB(this)
-this.Ek()
+y.call$0()}else{y.call$0()
+this.Kl((z&4)!==0)}},"call$2","gTb",4,0,null,152,[],153,[]],
+SY:[function(){this.Ek()
 this.Gv=(this.Gv|16)>>>0
-y=this.lz
-x=J.x(y)
-if(typeof y==="object"&&y!==null&&!!x.$isb8)y.wM(z)
-else z.call$0()},"call$0","gXm",0,0,null],
+new P.qB(this).call$0()},"call$0","gXm",0,0,null],
 J7:[function(a){var z=this.Gv
 this.Gv=(z|32)>>>0
 a.call$0()
 this.Gv=(this.Gv&4294967263)>>>0
-this.Kl((z&4)!==0)},"call$1","gc2",2,0,null,150],
-Kl:[function(a){var z,y
-if((this.Gv&64)!==0){z=this.Ri
-z=z.gl0(z)}else z=!1
-if(z){z=(this.Gv&4294967231)>>>0
+this.Kl((z&4)!==0)},"call$1","gc2",2,0,null,148,[]],
+Kl:[function(a){var z,y,x
+z=this.Gv
+if((z&64)!==0&&this.Ri.N6==null){z=(z&4294967231)>>>0
 this.Gv=z
-if((z&4)!==0)if(z<128){z=this.Ri
-z=z==null||z.gl0(z)}else z=!1
-else z=!1
-if(z)this.Gv=(this.Gv&4294967291)>>>0}for(;!0;a=y){z=this.Gv
-if((z&8)!==0){this.Ri=null
-return}y=(z&4)!==0
-if(a===y)break
+if((z&4)!==0)if(z<128){y=this.Ri
+y=y==null||y.N6==null}else y=!1
+else y=!1
+if(y){z=(z&4294967291)>>>0
+this.Gv=z}}for(;!0;a=x){if((z&8)!==0){this.Ri=null
+return}x=(z&4)!==0
+if(a===x)break
 this.Gv=(z^32)>>>0
-if(y)this.uO()
+if(x)this.uO()
 else this.LP()
-this.Gv=(this.Gv&4294967263)>>>0}z=this.Gv
-if((z&64)!==0&&z<128)this.Ri.t2(this)},"call$1","ghE",2,0,null,406],
+z=(this.Gv&4294967263)>>>0
+this.Gv=z}if((z&64)!==0&&z<128)this.Ri.t2(this)},"call$1","ghE",2,0,null,401,[]],
 $isMO:true,
-static:{"":"ry,bG,nS,R7,yJ,X8,HX,GC,L3"}},
+static:{"^":"ry,bG,Q9,Ir,Il,X8,HX,GC,f9"}},
 Vo:{
-"":"Tp:107;a,b,c",
+"^":"Tp:107;a,b,c",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 y=z.Gv
@@ -12910,7 +13189,7 @@
 else y.m1(x,v)}z.Gv=(z.Gv&4294967263)>>>0},"call$0",null,0,0,null,"call"],
 $isEH:true},
 qB:{
-"":"Tp:107;a",
+"^":"Tp:107;a",
 call$0:[function(){var z,y
 z=this.a
 y=z.Gv
@@ -12920,43 +13199,41 @@
 z.Gv=(z.Gv&4294967263)>>>0},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ez:{
-"":"qh;",
+"^":"qh;",
 KR:[function(a,b,c,d){var z=this.w4(!0===b)
 z.fe(a)
 z.fm(0,d)
 z.y5(c)
-return z},function(a){return this.KR(a,null,null,null)},"yI",function(a,b,c){return this.KR(a,null,b,c)},"zC","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
+return z},function(a){return this.KR(a,null,null,null)},"yI",function(a,b,c){return this.KR(a,null,b,c)},"zC","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
 w4:[function(a){var z,y
 z=$.X3
 y=a?1:0
 y=new P.KA(null,null,null,z,y,null,null)
 y.$builtinTypeInfo=this.$builtinTypeInfo
-return y},"call$1","gvC",2,0,null,346],
-na:[function(a){},"call$1","gnL",2,0,407,157]},
+return y},"call$1","gvC",2,0,null,396,[]]},
 lx:{
-"":"a;LD@"},
+"^":"a;aw@"},
 LV:{
-"":"lx;P>,LD",
+"^":"lx;P>,aw",
 r6:function(a,b){return this.P.call$1(b)},
-pP:[function(a){a.Iv(this.P)},"call$1","gqp",2,0,null,408]},
+dP:[function(a){a.Iv(this.P)},"call$1","gqp",2,0,null,404,[]]},
 DS:{
-"":"lx;kc>,I4<,LD",
-pP:[function(a){a.pb(this.kc,this.I4)},"call$1","gqp",2,0,null,408]},
+"^":"lx;kc>,I4<,aw",
+dP:[function(a){a.pb(this.kc,this.I4)},"call$1","gqp",2,0,null,404,[]]},
 JF:{
-"":"a;",
-pP:[function(a){a.SY()},"call$1","gqp",2,0,null,408],
-gLD:function(){return},
-sLD:function(a){throw H.b(new P.lj("No events after a done."))}},
-ht:{
-"":"a;",
+"^":"a;",
+dP:[function(a){a.SY()},"call$1","gqp",2,0,null,404,[]],
+gaw:function(){return},
+saw:function(a){throw H.b(new P.lj("No events after a done."))}},
+Je:{
+"^":"a;",
 t2:[function(a){var z=this.Gv
 if(z===1)return
 if(z>=1){this.Gv=1
 return}P.rb(new P.CR(this,a))
-this.Gv=1},"call$1","gQu",2,0,null,408],
-FK:[function(){if(this.Gv===1)this.Gv=3},"call$0","gTg",0,0,null]},
+this.Gv=1},"call$1","gQu",2,0,null,404,[]]},
 CR:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){var z,y
 z=this.a
 y=z.Gv
@@ -12965,35 +13242,35 @@
 z.TO(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Qk:{
-"":"ht;zR,N6,Gv",
+"^":"Je;zR,N6,Gv",
 gl0:function(a){return this.N6==null},
 h:[function(a,b){var z=this.N6
 if(z==null){this.N6=b
-this.zR=b}else{z.sLD(b)
-this.N6=b}},"call$1","ght",2,0,null,405],
+this.zR=b}else{z.saw(b)
+this.N6=b}},"call$1","ght",2,0,null,400,[]],
 TO:[function(a){var z,y
 z=this.zR
-y=z.gLD()
+y=z.gaw()
 this.zR=y
 if(y==null)this.N6=null
-z.pP(a)},"call$1","gTn",2,0,null,408],
+z.dP(a)},"call$1","gTn",2,0,null,404,[]],
 V1:[function(a){if(this.Gv===1)this.Gv=3
 this.N6=null
 this.zR=null},"call$0","gyP",0,0,null]},
-dR:{
-"":"Tp:108;a,b,c",
+v1y:{
+"^":"Tp:108;a,b,c",
 call$0:[function(){return this.a.K5(this.b,this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 uR:{
-"":"Tp:409;a,b",
-call$2:[function(a,b){return P.NX(this.a,this.b,a,b)},"call$2",null,4,0,null,146,147,"call"],
+"^":"Tp:405;a,b",
+call$2:[function(a,b){return P.NX(this.a,this.b,a,b)},"call$2",null,4,0,null,152,[],153,[],"call"],
 $isEH:true},
-QX:{
-"":"Tp:108;a,b",
+Q0:{
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.rX(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 YR:{
-"":"qh;",
+"^":"qh;",
 KR:[function(a,b,c,d){var z,y,x,w,v
 b=!0===b
 z=H.ip(this,"YR",0)
@@ -13005,15 +13282,15 @@
 v.fe(a)
 v.fm(0,d)
 v.y5(c)
-return v},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
-Ml:[function(a,b){b.Rg(0,a)},"call$2","gOa",4,0,null,237,410],
+return v},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
+Ml:[function(a,b){b.Rg(0,a)},"call$2","gOa",4,0,null,231,[],406,[]],
 $asqh:function(a,b){return[b]}},
 fB:{
-"":"KA;UY,Ee,dB,o7,Bd,Lj,Gv,lz,Ri",
+"^":"KA;UY,Ee,dB,o7,Bd,Lj,Gv,lz,Ri",
 Rg:[function(a,b){if((this.Gv&2)!==0)return
-P.KA.prototype.Rg.call(this,this,b)},"call$1","gHR",2,0,null,237],
+P.KA.prototype.Rg.call(this,this,b)},"call$1","gHR",2,0,null,231,[]],
 V8:[function(a,b){if((this.Gv&2)!==0)return
-P.KA.prototype.V8.call(this,a,b)},"call$2","grd",4,0,null,146,147],
+P.KA.prototype.V8.call(this,a,b)},"call$2","grd",4,0,null,152,[],153,[]],
 uO:[function(){var z=this.Ee
 if(z==null)return
 z.yy(0)},"call$0","gp4",0,0,107],
@@ -13022,9 +13299,9 @@
 z.QE()},"call$0","gZ9",0,0,107],
 tA:[function(){var z=this.Ee
 if(z!=null){this.Ee=null
-z.ed()}return},"call$0","gQC",0,0,400],
-vx:[function(a){this.UY.Ml(a,this)},"call$1","gOa",2,0,function(){return H.IG(function(a,b){return{func:"kA",void:true,args:[a]}},this.$receiver,"fB")},237],
-xL:[function(a,b){this.V8(a,b)},"call$2","gRE",4,0,411,146,147],
+z.ed()}return},"call$0","gQC",0,0,null],
+vx:[function(a){this.UY.Ml(a,this)},"call$1","gOa",2,0,function(){return H.IG(function(a,b){return{func:"kA",void:true,args:[a]}},this.$receiver,"fB")},231,[]],
+xL:[function(a,b){this.V8(a,b)},"call$2","gRE",4,0,407,152,[],153,[]],
 nn:[function(){this.Qj()},"call$0","gH1",0,0,107],
 S8:function(a,b,c,d){var z,y
 z=this.gOa()
@@ -13033,7 +13310,7 @@
 $asKA:function(a,b){return[b]},
 $asMO:function(a,b){return[b]}},
 nO:{
-"":"YR;qs,Sb",
+"^":"YR;qs,Sb",
 Dr:function(a){return this.qs.call$1(a)},
 Ml:[function(a,b){var z,y,x,w,v
 z=null
@@ -13041,11 +13318,11 @@
 y=v
 x=new H.XO(w,null)
 b.V8(y,x)
-return}if(z===!0)J.QM(b,a)},"call$2","gOa",4,0,null,412,410],
+return}if(z===!0)J.QM(b,a)},"call$2","gOa",4,0,null,408,[],406,[]],
 $asYR:function(a){return[a,a]},
 $asqh:null},
 t3:{
-"":"YR;TN,Sb",
+"^":"YR;TN,Sb",
 kn:function(a){return this.TN.call$1(a)},
 Ml:[function(a,b){var z,y,x,w,v
 z=null
@@ -13053,23 +13330,25 @@
 y=v
 x=new H.XO(w,null)
 b.V8(y,x)
-return}J.QM(b,z)},"call$2","gOa",4,0,null,412,410]},
+return}J.QM(b,z)},"call$2","gOa",4,0,null,408,[],406,[]]},
 dq:{
-"":"YR;Em,Sb",
+"^":"YR;Em,Sb",
 Ml:[function(a,b){var z=this.Em
 if(z>0){this.Em=z-1
-return}b.Rg(0,a)},"call$2","gOa",4,0,null,412,410],
+return}b.Rg(0,a)},"call$2","gOa",4,0,null,408,[],406,[]],
 U6:function(a,b,c){},
 $asYR:function(a){return[a,a]},
 $asqh:null},
-tU:{
-"":"a;"},
+lO:{
+"^":"a;"},
 aY:{
-"":"a;"},
+"^":"a;"},
 zG:{
-"":"a;E2<,cP<,Jl<,pU<,Fh<,Xp<,aj<,rb<,Zq<,rF,JS>,iq<",
+"^":"a;E2<,cP<,Jl<,pU<,Fh<,Xp<,aj<,rb<,Zq<,rF,JS>,iq<",
 hk:function(a,b){return this.E2.call$2(a,b)},
 Gr:function(a){return this.cP.call$1(a)},
+FI:function(a,b){return this.Jl.call$2(a,b)},
+mg:function(a,b,c){return this.pU.call$3(a,b,c)},
 Al:function(a){return this.Fh.call$1(a)},
 cR:function(a){return this.Xp.call$1(a)},
 O8:function(a){return this.aj.call$1(a)},
@@ -13079,137 +13358,137 @@
 Ch:function(a,b){return this.JS.call$1(b)},
 iT:function(a){return this.iq.call$1$specification(a)}},
 e4:{
-"":"a;"},
+"^":"a;"},
 JB:{
-"":"a;"},
+"^":"a;"},
 Id:{
-"":"a;nU",
-gLj:function(){return this.nU},
+"^":"a;oh",
+gLj:function(){return this.oh},
 c1:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gE2()==null;)z=z.geT(z)
-return y.gE2().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gE2",6,0,null,148,146,147],
+return y.gE2().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gE2",6,0,null,146,[],152,[],153,[]],
 Vn:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gcP()==null;)z=z.geT(z)
-return y.gcP().call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gcP",4,0,null,148,110],
+return y.gcP().call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gcP",4,0,null,146,[],110,[]],
 qG:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gJl()==null;)z=z.geT(z)
-return y.gJl().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gJl",6,0,null,148,110,165],
+return y.gJl().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gJl",6,0,null,146,[],110,[],165,[]],
 nA:[function(a,b,c,d){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gpU()==null;)z=z.geT(z)
-return y.gpU().call$6(z,new P.Id(z.geT(z)),a,b,c,d)},"call$4","gpU",8,0,null,148,110,54,55],
+return y.gpU().call$6(z,new P.Id(z.geT(z)),a,b,c,d)},"call$4","gpU",8,0,null,146,[],110,[],54,[],55,[]],
 TE:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gFh(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gFh",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gFh",4,0,null,146,[],110,[]],
 V6:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gXp(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gXp",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gXp",4,0,null,146,[],110,[]],
 mz:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gaj(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gaj",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gaj",4,0,null,146,[],110,[]],
 RK:[function(a,b){var z,y,x
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.grb()==null;)z=z.geT(z)
 x=z.geT(z)
-y.grb().call$4(z,new P.Id(x),a,b)},"call$2","grb",4,0,null,148,110],
-dJ:[function(a,b,c){var z,y
-z=this.nU
+y.grb().call$4(z,new P.Id(x),a,b)},"call$2","grb",4,0,null,146,[],110,[]],
+pX:[function(a,b,c){var z,y
+z=this.oh
 for(;y=z.gzU(),y.gZq()==null;)z=z.geT(z)
-return y.gZq().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gZq",6,0,null,148,159,110],
+return y.gZq().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gZq",6,0,null,146,[],159,[],110,[]],
 RB:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gJS(y)==null;)z=z.geT(z)
-y.gJS(y).call$4(z,new P.Id(z.geT(z)),b,c)},"call$2","gJS",4,0,null,148,173],
-GT:[function(a,b,c){var z,y,x
-z=this.nU
+y.gJS(y).call$4(z,new P.Id(z.geT(z)),b,c)},"call$2","gJS",4,0,null,146,[],173,[]],
+ld:[function(a,b,c){var z,y,x
+z=this.oh
 for(;y=z.gzU(),y.giq()==null;)z=z.geT(z)
 x=z.geT(z)
-return y.giq().call$5(z,new P.Id(x),a,b,c)},"call$3","giq",6,0,null,148,176,177]},
+return y.giq().call$5(z,new P.Id(x),a,b,c)},"call$3","giq",6,0,null,146,[],176,[],177,[]]},
 WH:{
-"":"a;",
-fC:[function(a){return this.gC5()===a.gC5()},"call$1","gRX",2,0,null,413],
+"^":"a;",
+fC:[function(a){return this.gC5()===a.gC5()},"call$1","gRX",2,0,null,409,[]],
 bH:[function(a){var z,y,x,w
 try{x=this.Gr(a)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$1","gCF",2,0,null,110],
+return this.hk(z,y)}},"call$1","gCF",2,0,null,110,[]],
 m1:[function(a,b){var z,y,x,w
 try{x=this.FI(a,b)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$2","gNY",4,0,null,110,165],
+return this.hk(z,y)}},"call$2","gNY",4,0,null,110,[],165,[]],
 z8:[function(a,b,c){var z,y,x,w
 try{x=this.mg(a,b,c)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$3","gLG",6,0,null,110,54,55],
+return this.hk(z,y)}},"call$3","gLG",6,0,null,110,[],54,[],55,[]],
 xi:[function(a,b){var z=this.Al(a)
 if(b)return new P.TF(this,z)
-else return new P.K5(this,z)},function(a){return this.xi(a,!0)},"ce","call$2$runGuarded",null,"gAX",2,3,null,337,110,414],
+else return new P.K5(this,z)},function(a){return this.xi(a,!0)},"ce","call$2$runGuarded",null,"gAX",2,3,null,331,110,[],410,[]],
 oj:[function(a,b){var z=this.cR(a)
 if(b)return new P.Cg(this,z)
-else return new P.Hs(this,z)},"call$2$runGuarded","gVF",2,3,null,337,110,414],
+else return new P.Hs(this,z)},"call$2$runGuarded","gVF",2,3,null,331,110,[],410,[]],
 PT:[function(a,b){var z=this.O8(a)
 if(b)return new P.dv(this,z)
-else return new P.pV(this,z)},"call$2$runGuarded","gzg",2,3,null,337,110,414]},
+else return new P.pV(this,z)},"call$2$runGuarded","gzg",2,3,null,331,110,[],410,[]]},
 TF:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.bH(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 K5:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){return this.c.Gr(this.d)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Cg:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.m1(this.b,a)},"call$1",null,2,0,null,165,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.m1(this.b,a)},"call$1",null,2,0,null,165,[],"call"],
 $isEH:true},
 Hs:{
-"":"Tp:229;c,d",
-call$1:[function(a){return this.c.FI(this.d,a)},"call$1",null,2,0,null,165,"call"],
+"^":"Tp:223;c,d",
+call$1:[function(a){return this.c.FI(this.d,a)},"call$1",null,2,0,null,165,[],"call"],
 $isEH:true},
 dv:{
-"":"Tp:349;a,b",
-call$2:[function(a,b){return this.a.z8(this.b,a,b)},"call$2",null,4,0,null,54,55,"call"],
+"^":"Tp:341;a,b",
+call$2:[function(a,b){return this.a.z8(this.b,a,b)},"call$2",null,4,0,null,54,[],55,[],"call"],
 $isEH:true},
 pV:{
-"":"Tp:349;c,d",
-call$2:[function(a,b){return this.c.mg(this.d,a,b)},"call$2",null,4,0,null,54,55,"call"],
+"^":"Tp:341;c,d",
+call$2:[function(a,b){return this.c.mg(this.d,a,b)},"call$2",null,4,0,null,54,[],55,[],"call"],
 $isEH:true},
-cc:{
-"":"WH;eT>,zU<,R1",
+uo:{
+"^":"WH;eT>,zU<,R1",
 gC5:function(){return this.eT.gC5()},
 t:[function(a,b){var z,y
 z=this.R1
 y=z.t(0,b)
 if(y!=null||z.x4(b))return y
-return this.eT.t(0,b)},"call$1","gIA",2,0,null,42],
-hk:[function(a,b){return new P.Id(this).c1(this,a,b)},"call$2","gE2",4,0,null,146,147],
-c6:[function(a,b){return new P.Id(this).GT(this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,177],
-Gr:[function(a){return new P.Id(this).Vn(this,a)},"call$1","gcP",2,0,null,110],
-FI:[function(a,b){return new P.Id(this).qG(this,a,b)},"call$2","gJl",4,0,null,110,165],
-mg:[function(a,b,c){return new P.Id(this).nA(this,a,b,c)},"call$3","gpU",6,0,null,110,54,55],
-Al:[function(a){return new P.Id(this).TE(this,a)},"call$1","gFh",2,0,null,110],
-cR:[function(a){return new P.Id(this).V6(this,a)},"call$1","gXp",2,0,null,110],
-O8:[function(a){return new P.Id(this).mz(this,a)},"call$1","gaj",2,0,null,110],
-wr:[function(a){new P.Id(this).RK(this,a)},"call$1","grb",2,0,null,110],
-uN:[function(a,b){return new P.Id(this).dJ(this,a,b)},"call$2","gZq",4,0,null,159,110],
-Ch:[function(a,b){new P.Id(this).RB(0,this,b)},"call$1","gJS",2,0,null,173]},
+return this.eT.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+hk:[function(a,b){return new P.Id(this).c1(this,a,b)},"call$2","gE2",4,0,null,152,[],153,[]],
+c6:[function(a,b){return new P.Id(this).ld(this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,[],177,[]],
+Gr:[function(a){return new P.Id(this).Vn(this,a)},"call$1","gcP",2,0,null,110,[]],
+FI:[function(a,b){return new P.Id(this).qG(this,a,b)},"call$2","gJl",4,0,null,110,[],165,[]],
+mg:[function(a,b,c){return new P.Id(this).nA(this,a,b,c)},"call$3","gpU",6,0,null,110,[],54,[],55,[]],
+Al:[function(a){return new P.Id(this).TE(this,a)},"call$1","gFh",2,0,null,110,[]],
+cR:[function(a){return new P.Id(this).V6(this,a)},"call$1","gXp",2,0,null,110,[]],
+O8:[function(a){return new P.Id(this).mz(this,a)},"call$1","gaj",2,0,null,110,[]],
+wr:[function(a){new P.Id(this).RK(this,a)},"call$1","grb",2,0,null,110,[]],
+uN:[function(a,b){return new P.Id(this).pX(this,a,b)},"call$2","gZq",4,0,null,159,[],110,[]],
+Ch:[function(a,b){new P.Id(this).RB(0,this,b)},"call$1","gJS",2,0,null,173,[]]},
 pK:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){P.IA(new P.eM(this.a,this.b))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 eM:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){var z,y,x
 z=this.c
 P.JS("Uncaught Error: "+H.d(z))
@@ -13221,18 +13500,20 @@
 throw H.b(z)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Uez:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){if(a==null)throw H.b(new P.AT("ZoneValue key must not be null"))
-this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
-W5:{
-"":"a;",
+nU:{
+"^":"a;",
 gE2:function(){return P.xP()},
 hk:function(a,b){return this.gE2().call$2(a,b)},
 gcP:function(){return P.AI()},
 Gr:function(a){return this.gcP().call$1(a)},
 gJl:function(){return P.MM()},
+FI:function(a,b){return this.gJl().call$2(a,b)},
 gpU:function(){return P.l4()},
+mg:function(a,b,c){return this.gpU().call$3(a,b,c)},
 gFh:function(){return P.EU()},
 Al:function(a){return this.gFh().call$1(a)},
 gXp:function(){return P.zi()},
@@ -13245,31 +13526,31 @@
 gZq:function(){return P.KF()},
 uN:function(a,b){return this.gZq().call$2(a,b)},
 gJS:function(a){return P.YM()},
-Ch:function(a,b){return this.gJS(a).call$1(b)},
+Ch:function(a,b){return this.gJS(this).call$1(b)},
 giq:function(){return P.hn()},
 iT:function(a){return this.giq().call$1$specification(a)}},
 R8:{
-"":"WH;",
+"^":"WH;",
 geT:function(a){return},
 gzU:function(){return C.v8},
 gC5:function(){return this},
-fC:[function(a){return a.gC5()===this},"call$1","gRX",2,0,null,413],
-t:[function(a,b){return},"call$1","gIA",2,0,null,42],
-hk:[function(a,b){return P.L2(this,null,this,a,b)},"call$2","gE2",4,0,null,146,147],
-c6:[function(a,b){return P.UA(this,null,this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,177],
-Gr:[function(a){return P.T8(this,null,this,a)},"call$1","gcP",2,0,null,110],
-FI:[function(a,b){return P.V7(this,null,this,a,b)},"call$2","gJl",4,0,null,110,165],
-mg:[function(a,b,c){return P.Qx(this,null,this,a,b,c)},"call$3","gpU",6,0,null,110,54,55],
-Al:[function(a){return a},"call$1","gFh",2,0,null,110],
-cR:[function(a){return a},"call$1","gXp",2,0,null,110],
-O8:[function(a){return a},"call$1","gaj",2,0,null,110],
-wr:[function(a){P.Tk(this,null,this,a)},"call$1","grb",2,0,null,110],
-uN:[function(a,b){return P.h8(this,null,this,a,b)},"call$2","gZq",4,0,null,159,110],
+fC:[function(a){return a.gC5()===this},"call$1","gRX",2,0,null,409,[]],
+t:[function(a,b){return},"call$1","gIA",2,0,null,42,[]],
+hk:[function(a,b){return P.L2(this,null,this,a,b)},"call$2","gE2",4,0,null,152,[],153,[]],
+c6:[function(a,b){return P.UA(this,null,this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,[],177,[]],
+Gr:[function(a){return P.T8(this,null,this,a)},"call$1","gcP",2,0,null,110,[]],
+FI:[function(a,b){return P.V7(this,null,this,a,b)},"call$2","gJl",4,0,null,110,[],165,[]],
+mg:[function(a,b,c){return P.Qx(this,null,this,a,b,c)},"call$3","gpU",6,0,null,110,[],54,[],55,[]],
+Al:[function(a){return a},"call$1","gFh",2,0,null,110,[]],
+cR:[function(a){return a},"call$1","gXp",2,0,null,110,[]],
+O8:[function(a){return a},"call$1","gaj",2,0,null,110,[]],
+wr:[function(a){P.Tk(this,null,this,a)},"call$1","grb",2,0,null,110,[]],
+uN:[function(a,b){return P.h8(this,null,this,a,b)},"call$2","gZq",4,0,null,159,[],110,[]],
 Ch:[function(a,b){H.qw(b)
-return},"call$1","gJS",2,0,null,173]}}],["dart.collection","dart:collection",,P,{
-"":"",
-Ou:[function(a,b){return J.de(a,b)},"call$2","iv",4,0,179,123,180],
-T9:[function(a){return J.v1(a)},"call$1","py",2,0,181,123],
+return},"call$1","gJS",2,0,null,173,[]]}}],["dart.collection","dart:collection",,P,{
+"^":"",
+Ou:[function(a,b){return J.de(a,b)},"call$2","iv",4,0,179,123,[],180,[]],
+T9:[function(a){return J.v1(a)},"call$1","py",2,0,181,123,[]],
 Py:function(a,b,c,d,e){var z
 if(a==null){z=new P.k6(0,null,null,null,null)
 z.$builtinTypeInfo=[d,e]
@@ -13284,7 +13565,7 @@
 try{P.Vr(a,z)}finally{$.xb().Rz(0,a)}y=P.p9("(")
 y.We(z,", ")
 y.KF(")")
-return y.vM},"call$1","Zw",2,0,null,109],
+return y.vM},"call$1","Zw",2,0,null,109,[]],
 Vr:[function(a,b){var z,y,x,w,v,u,t,s,r,q
 z=a.gA(a)
 y=0
@@ -13317,7 +13598,7 @@
 if(q==null){y+=5
 q="..."}}if(q!=null)b.push(q)
 b.push(u)
-b.push(v)},"call$2","zE",4,0,null,109,182],
+b.push(v)},"call$2","zE",4,0,null,109,[],182,[]],
 L5:function(a,b,c,d,e){if(b==null){if(a==null)return H.VM(new P.YB(0,null,null,null,null,null,0),[d,e])
 b=P.py()}else{if(P.J2()===b&&P.N3()===a)return H.VM(new P.ey(0,null,null,null,null,null,0),[d,e])
 if(a==null)a=P.iv()}return P.Ex(a,b,c,d,e)},
@@ -13332,9 +13613,9 @@
 J.kH(a,new P.ZQ(z,y))
 y.KF("}")}finally{z=$.tw()
 if(0>=z.length)return H.e(z,0)
-z.pop()}return y.gvM()},"call$1","DH",2,0,null,183],
+z.pop()}return y.gvM()},"call$1","DH",2,0,null,183,[]],
 k6:{
-"":"a;X5,vv,OX,OB,aw",
+"^":"a;X5,vv,OX,OB,wV",
 gB:function(a){return this.X5},
 gl0:function(a){return this.X5===0},
 gor:function(a){return this.X5!==0},
@@ -13345,11 +13626,11 @@
 return z==null?!1:z[a]!=null}else if(typeof a==="number"&&(a&0x3ffffff)===a){y=this.OX
 return y==null?!1:y[a]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42],
+return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42,[]],
 di:[function(a){var z=this.Ig()
 z.toString
-return H.Ck(z,new P.ce(this,a))},"call$1","gmc",2,0,null,23],
-FV:[function(a,b){J.kH(b,new P.DJ(this))},"call$1","gDY",2,0,null,104],
+return H.Ck(z,new P.ce(this,a))},"call$1","gmc",2,0,null,23,[]],
+FV:[function(a,b){J.kH(b,new P.DJ(this))},"call$1","gDY",2,0,null,104,[]],
 t:[function(a,b){var z,y,x,w,v,u,t
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null)y=null
@@ -13361,41 +13642,23 @@
 if(v==null)return
 u=v[this.nm(b)]
 t=this.aH(u,b)
-return t<0?null:u[t+1]}},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){var z,y,x,w,v,u,t,s
+return t<0?null:u[t+1]}},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
-if(z==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.vv=y
-z=y}if(z[b]==null){this.X5=this.X5+1
-this.aw=null}if(c==null)z[b]=z
-else z[b]=c}else if(typeof b==="number"&&(b&0x3ffffff)===b){x=this.OX
-if(x==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OX=y
-x=y}if(x[b]==null){this.X5=this.X5+1
-this.aw=null}if(c==null)x[b]=x
-else x[b]=c}else{w=this.OB
-if(w==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OB=y
-w=y}v=this.nm(b)
-u=w[v]
-if(u==null){t=[b,c]
-if(t==null)w[v]=w
-else w[v]=t
+if(z==null){z=P.a0()
+this.vv=z}this.dg(z,b,c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
+if(y==null){y=P.a0()
+this.OX=y}this.dg(y,b,c)}else{x=this.OB
+if(x==null){x=P.a0()
+this.OB=x}w=this.nm(b)
+v=x[w]
+if(v==null){P.cW(x,w,[b,c])
 this.X5=this.X5+1
-this.aw=null}else{s=this.aH(u,b)
-if(s>=0)u[s+1]=c
-else{u.push(b,c)
+this.wV=null}else{u=this.aH(v,b)
+if(u>=0)v[u+1]=c
+else{v.push(b,c)
 this.X5=this.X5+1
-this.aw=null}}}},"call$2","gj3",4,0,null,42,23],
+this.wV=null}}}},"call$2","gj3",4,0,null,42,[],23,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13405,9 +13668,9 @@
 x=this.aH(y,b)
 if(x<0)return
 this.X5=this.X5-1
-this.aw=null
-return y.splice(x,2)[1]}},"call$1","gRI",2,0,null,42],
-V1:[function(a){if(this.X5>0){this.aw=null
+this.wV=null
+return y.splice(x,2)[1]}},"call$1","gRI",2,0,null,42,[]],
+V1:[function(a){if(this.X5>0){this.wV=null
 this.OB=null
 this.OX=null
 this.vv=null
@@ -13416,9 +13679,9 @@
 z=this.Ig()
 for(y=z.length,x=0;x<y;++x){w=z[x]
 b.call$2(w,this.t(0,w))
-if(z!==this.aw)throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,378],
+if(z!==this.wV)throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
 Ig:[function(){var z,y,x,w,v,u,t,s,r,q,p,o
-z=this.aw
+z=this.wV
 if(z!=null)return z
 y=Array(this.X5)
 y.fixed$length=init
@@ -13434,98 +13697,104 @@
 v=w.length
 for(t=0;t<v;++t){q=r[w[t]]
 p=q.length
-for(o=0;o<p;o+=2){y[u]=q[o];++u}}}this.aw=y
+for(o=0;o<p;o+=2){y[u]=q[o];++u}}}this.wV=y
 return y},"call$0","gtL",0,0,null],
+dg:[function(a,b,c){if(a[b]==null){this.X5=this.X5+1
+this.wV=null}P.cW(a,b,c)},"call$3","gLa",6,0,null,178,[],42,[],23,[]],
 Nv:[function(a,b){var z
 if(a!=null&&a[b]!=null){z=P.vL(a,b)
 delete a[b]
 this.X5=this.X5-1
-this.aw=null
-return z}else return},"call$2","got",4,0,null,178,42],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+this.wV=null
+return z}else return},"call$2","got",4,0,null,178,[],42,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2)if(J.de(a[y],b))return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 $isZ0:true,
 static:{vL:[function(a,b){var z=a[b]
-return z===a?null:z},"call$2","ME",4,0,null,178,42]}},
+return z===a?null:z},"call$2","ME",4,0,null,178,[],42,[]],cW:[function(a,b,c){if(c==null)a[b]=a
+else a[b]=c},"call$3","Nk",6,0,null,178,[],42,[],23,[]],a0:[function(){var z=Object.create(null)
+P.cW(z,"<non-identifier-key>",z)
+delete z["<non-identifier-key>"]
+return z},"call$0","Vd",0,0,null]}},
 oi:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 ce:{
-"":"Tp:229;a,b",
-call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 DJ:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"vP",args:[a,b]}},this.a,"k6")}},
 PL:{
-"":"k6;X5,vv,OX,OB,aw",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"k6;X5,vv,OX,OB,wV",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2){x=a[y]
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,42]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],42,[]]},
 Fq:{
-"":"k6;m6,Q6,ac,X5,vv,OX,OB,aw",
+"^":"k6;m6,Q6,ac,X5,vv,OX,OB,wV",
 C2:function(a,b){return this.m6.call$2(a,b)},
 H5:function(a){return this.Q6.call$1(a)},
 Ef:function(a){return this.ac.call$1(a)},
 t:[function(a,b){if(this.Ef(b)!==!0)return
-return P.k6.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42],
+return P.k6.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42,[]],
 x4:[function(a){if(this.Ef(a)!==!0)return!1
-return P.k6.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42],
+return P.k6.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42,[]],
 Rz:[function(a,b){if(this.Ef(b)!==!0)return
-return P.k6.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42],
-nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+return P.k6.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42,[]],
+nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2)if(this.C2(a[y],b)===!0)return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 static:{MP:function(a,b,c,d,e){var z=new P.jG(d)
 return H.VM(new P.Fq(a,b,z,0,null,null,null,null),[d,e])}}},
 jG:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 fG:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.X5},
 gl0:function(a){return this.Fb.X5===0},
 gA:function(a){var z=this.Fb
 z=new P.EQ(z,z.Ig(),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
-tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124],
+tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z,y,x,w
 z=this.Fb
 y=z.Ig()
 for(x=y.length,w=0;w<x;++w){b.call$1(y[w])
-if(y!==z.aw)throw H.b(P.a4(z))}},"call$1","gjw",2,0,null,110],
+if(y!==z.wV)throw H.b(P.a4(z))}},"call$1","gjw",2,0,null,110,[]],
 $isyN:true},
 EQ:{
-"":"a;Fb,aw,zi,fD",
+"^":"a;Fb,wV,zi,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
-z=this.aw
+z=this.wV
 y=this.zi
 x=this.Fb
-if(z!==x.aw)throw H.b(P.a4(x))
+if(z!==x.wV)throw H.b(P.a4(x))
 else if(y>=z.length){this.fD=null
 return!1}else{this.fD=z[y]
 this.zi=y+1
-return!0}},"call$0","guK",0,0,null]},
+return!0}},"call$0","gqy",0,0,null]},
 YB:{
-"":"a;X5,vv,OX,OB,H9,lX,zN",
+"^":"a;X5,vv,OX,OB,H9,lX,zN",
 gB:function(a){return this.X5},
 gl0:function(a){return this.X5===0},
 gor:function(a){return this.X5!==0},
@@ -13538,9 +13807,9 @@
 if(y==null)return!1
 return y[a]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42],
-di:[function(a){return H.VM(new P.i5(this),[H.Kp(this,0)]).Vr(0,new P.ou(this,a))},"call$1","gmc",2,0,null,23],
-FV:[function(a,b){J.kH(b,new P.S9(this))},"call$1","gDY",2,0,null,104],
+return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return H.VM(new P.i5(this),[H.Kp(this,0)]).Vr(0,new P.ou(this,a))},"call$1","gmc",2,0,null,23,[]],
+FV:[function(a,b){J.kH(b,new P.S9(this))},"call$1","gDY",2,0,null,104,[]],
 t:[function(a,b){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null)return
@@ -13553,38 +13822,25 @@
 v=w[this.nm(b)]
 u=this.aH(v,b)
 if(u<0)return
-return v[u].gS4()}},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){var z,y,x,w,v,u,t,s
+return v[u].gS4()}},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
-if(z==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.vv=y
-z=y}x=z[b]
-if(x==null)z[b]=this.pE(b,c)
-else x.sS4(c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){w=this.OX
-if(w==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OX=y
-w=y}x=w[b]
-if(x==null)w[b]=this.pE(b,c)
-else x.sS4(c)}else{v=this.OB
-if(v==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OB=y
-v=y}u=this.nm(b)
-t=v[u]
-if(t==null)v[u]=[this.pE(b,c)]
-else{s=this.aH(t,b)
-if(s>=0)t[s].sS4(c)
-else t.push(this.pE(b,c))}}},"call$2","gj3",4,0,null,42,23],
+if(z==null){z=P.Qs()
+this.vv=z}this.dg(z,b,c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
+if(y==null){y=P.Qs()
+this.OX=y}this.dg(y,b,c)}else{x=this.OB
+if(x==null){x=P.Qs()
+this.OB=x}w=this.nm(b)
+v=x[w]
+if(v==null)x[w]=[this.pE(b,c)]
+else{u=this.aH(v,b)
+if(u>=0)v[u].sS4(c)
+else v.push(this.pE(b,c))}}},"call$2","gj3",4,0,null,42,[],23,[]],
 to:[function(a,b){var z
 if(this.x4(a))return this.t(0,a)
 z=b.call$0()
 this.u(0,a,z)
-return z},"call$2","gMs",4,0,null,42,417],
+return z},"call$2","gMs",4,0,null,42,[],413,[]],
 Rz:[function(a,b){var z,y,x,w
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13595,7 +13851,7 @@
 if(x<0)return
 w=y.splice(x,1)[0]
 this.Vb(w)
-return w.gS4()}},"call$1","gRI",2,0,null,42],
+return w.gS4()}},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){if(this.X5>0){this.lX=null
 this.H9=null
 this.OB=null
@@ -13608,14 +13864,17 @@
 y=this.zN
 for(;z!=null;){b.call$2(z.gkh(),z.gS4())
 if(y!==this.zN)throw H.b(P.a4(this))
-z=z.gDG()}},"call$1","gjw",2,0,null,378],
+z=z.gDG()}},"call$1","gjw",2,0,null,371,[]],
+dg:[function(a,b,c){var z=a[b]
+if(z==null)a[b]=this.pE(b,c)
+else z.sS4(c)},"call$3","gLa",6,0,null,178,[],42,[],23,[]],
 Nv:[function(a,b){var z
 if(a==null)return
 z=a[b]
 if(z==null)return
 this.Vb(z)
 delete a[b]
-return z.gS4()},"call$2","got",4,0,null,178,42],
+return z.gS4()},"call$2","got",4,0,null,178,[],42,[]],
 pE:[function(a,b){var z,y
 z=new P.db(a,b,null,null)
 if(this.H9==null){this.lX=z
@@ -13624,7 +13883,7 @@
 y.sDG(z)
 this.lX=z}this.X5=this.X5+1
 this.zN=this.zN+1&67108863
-return z},"call$2","gTM",4,0,null,42,23],
+return z},"call$2","gTM",4,0,null,42,[],23,[]],
 Vb:[function(a){var z,y
 z=a.gzQ()
 y=a.gDG()
@@ -13633,65 +13892,69 @@
 if(y==null)this.lX=z
 else y.szQ(z)
 this.X5=this.X5-1
-this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,418],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,414,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y].gkh(),b))return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 $isFo:true,
-$isZ0:true},
+$isZ0:true,
+static:{Qs:[function(){var z=Object.create(null)
+z["<non-identifier-key>"]=z
+delete z["<non-identifier-key>"]
+return z},"call$0","Bs",0,0,null]}},
 a1:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 ou:{
-"":"Tp:229;a,b",
-call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 S9:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"oK",args:[a,b]}},this.a,"YB")}},
 ey:{
-"":"YB;X5,vv,OX,OB,H9,lX,zN",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"YB;X5,vv,OX,OB,H9,lX,zN",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y){x=a[y].gkh()
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,42]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],42,[]]},
 xd:{
-"":"YB;m6,Q6,ac,X5,vv,OX,OB,H9,lX,zN",
+"^":"YB;m6,Q6,ac,X5,vv,OX,OB,H9,lX,zN",
 C2:function(a,b){return this.m6.call$2(a,b)},
 H5:function(a){return this.Q6.call$1(a)},
 Ef:function(a){return this.ac.call$1(a)},
 t:[function(a,b){if(this.Ef(b)!==!0)return
-return P.YB.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42],
+return P.YB.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42,[]],
 x4:[function(a){if(this.Ef(a)!==!0)return!1
-return P.YB.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42],
+return P.YB.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42,[]],
 Rz:[function(a,b){if(this.Ef(b)!==!0)return
-return P.YB.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42],
-nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+return P.YB.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42,[]],
+nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(this.C2(a[y].gkh(),b)===!0)return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 static:{Ex:function(a,b,c,d,e){var z=new P.v6(d)
 return H.VM(new P.xd(a,b,z,0,null,null,null,null,null,0),[d,e])}}},
 v6:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 db:{
-"":"a;kh<,S4@,DG@,zQ@"},
+"^":"a;kh<,S4@,DG@,zQ@"},
 i5:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.X5},
 gl0:function(a){return this.Fb.X5===0},
 gA:function(a){var z,y
@@ -13700,17 +13963,17 @@
 y.$builtinTypeInfo=this.$builtinTypeInfo
 y.zq=z.H9
 return y},
-tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124],
+tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z,y,x
 z=this.Fb
 y=z.H9
 x=z.zN
 for(;y!=null;){b.call$1(y.gkh())
 if(x!==z.zN)throw H.b(P.a4(z))
-y=y.gDG()}},"call$1","gjw",2,0,null,110],
+y=y.gDG()}},"call$1","gjw",2,0,null,110,[]],
 $isyN:true},
 N6:{
-"":"a;Fb,zN,zq,fD",
+"^":"a;Fb,zN,zq,fD",
 gl:function(){return this.fD},
 G:[function(){var z=this.Fb
 if(this.zN!==z.zN)throw H.b(P.a4(z))
@@ -13718,9 +13981,9 @@
 if(z==null){this.fD=null
 return!1}else{this.fD=z.gkh()
 this.zq=this.zq.gDG()
-return!0}}},"call$0","guK",0,0,null]},
+return!0}}},"call$0","gqy",0,0,null]},
 Rr:{
-"":"lN;",
+"^":"lN;",
 gA:function(a){var z=new P.oz(this,this.Zl(),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
@@ -13732,7 +13995,7 @@
 return z==null?!1:z[b]!=null}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
 return y==null?!1:y[b]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6],
+return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6,[]],
 Zt:[function(a){var z,y,x,w
 if(!(typeof a==="string"&&a!=="__proto__"))z=typeof a==="number"&&(a&0x3ffffff)===a
 else z=!0
@@ -13742,7 +14005,7 @@
 x=y[this.nm(a)]
 w=this.aH(x,a)
 if(w<0)return
-return J.UQ(x,w)},"call$1","gQB",2,0,null,6],
+return J.UQ(x,w)},"call$1","gQB",2,0,null,6,[]],
 h:[function(a,b){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null){y=Object.create(null)
@@ -13765,9 +14028,9 @@
 else{if(this.aH(u,b)>=0)return!1
 u.push(b)}this.X5=this.X5+1
 this.DM=null
-return!0}},"call$1","ght",2,0,null,124],
+return!0}},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,419],
+for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,415,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13779,7 +14042,7 @@
 this.X5=this.X5-1
 this.DM=null
 y.splice(x,1)
-return!0}},"call$1","gRI",2,0,null,6],
+return!0}},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){if(this.X5>0){this.DM=null
 this.OB=null
 this.OX=null
@@ -13808,30 +14071,30 @@
 a[b]=0
 this.X5=this.X5+1
 this.DM=null
-return!0},"call$2","gLa",4,0,null,178,124],
+return!0},"call$2","gLa",4,0,null,178,[],124,[]],
 Nv:[function(a,b){if(a!=null&&a[b]!=null){delete a[b]
 this.X5=this.X5-1
 this.DM=null
-return!0}else return!1},"call$2","got",4,0,null,178,124],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124],
+return!0}else return!1},"call$2","got",4,0,null,178,[],124,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y],b))return y
-return-1},"call$2","gSP",4,0,null,415,124],
+return-1},"call$2","gSP",4,0,null,411,[],124,[]],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 YO:{
-"":"Rr;X5,vv,OX,OB,DM",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"Rr;X5,vv,OX,OB,DM",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y){x=a[y]
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,124]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],124,[]]},
 oz:{
-"":"a;O2,DM,zi,fD",
+"^":"a;O2,DM,zi,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
 z=this.DM
@@ -13841,9 +14104,9 @@
 else if(y>=z.length){this.fD=null
 return!1}else{this.fD=z[y]
 this.zi=y+1
-return!0}},"call$0","guK",0,0,null]},
+return!0}},"call$0","gqy",0,0,null]},
 b6:{
-"":"lN;X5,vv,OX,OB,H9,lX,zN",
+"^":"lN;X5,vv,OX,OB,H9,lX,zN",
 gA:function(a){var z=H.VM(new P.zQ(this,this.zN,null,null),[null])
 z.zq=z.O2.H9
 return z},
@@ -13857,7 +14120,7 @@
 if(y==null)return!1
 return y[b]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6],
+return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6,[]],
 Zt:[function(a){var z,y,x,w
 if(!(typeof a==="string"&&a!=="__proto__"))z=typeof a==="number"&&(a&0x3ffffff)===a
 else z=!0
@@ -13867,13 +14130,13 @@
 x=y[this.nm(a)]
 w=this.aH(x,a)
 if(w<0)return
-return J.UQ(x,w).gGc()}},"call$1","gQB",2,0,null,6],
+return J.UQ(x,w).gGc()}},"call$1","gQB",2,0,null,6,[]],
 aN:[function(a,b){var z,y
 z=this.H9
 y=this.zN
 for(;z!=null;){b.call$1(z.gGc())
 if(y!==this.zN)throw H.b(P.a4(this))
-z=z.gDG()}},"call$1","gjw",2,0,null,378],
+z=z.gDG()}},"call$1","gjw",2,0,null,371,[]],
 grZ:function(a){var z=this.lX
 if(z==null)throw H.b(new P.lj("No elements"))
 return z.gGc()},
@@ -13897,9 +14160,9 @@
 u=w[v]
 if(u==null)w[v]=[this.xf(b)]
 else{if(this.aH(u,b)>=0)return!1
-u.push(this.xf(b))}return!0}},"call$1","ght",2,0,null,124],
+u.push(this.xf(b))}return!0}},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,419],
+for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,415,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13909,7 +14172,7 @@
 x=this.aH(y,b)
 if(x<0)return!1
 this.Vb(y.splice(x,1)[0])
-return!0}},"call$1","gRI",2,0,null,6],
+return!0}},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){if(this.X5>0){this.lX=null
 this.H9=null
 this.OB=null
@@ -13919,14 +14182,14 @@
 this.zN=this.zN+1&67108863}},"call$0","gyP",0,0,null],
 cA:[function(a,b){if(a[b]!=null)return!1
 a[b]=this.xf(b)
-return!0},"call$2","gLa",4,0,null,178,124],
+return!0},"call$2","gLa",4,0,null,178,[],124,[]],
 Nv:[function(a,b){var z
 if(a==null)return!1
 z=a[b]
 if(z==null)return!1
 this.Vb(z)
 delete a[b]
-return!0},"call$2","got",4,0,null,178,124],
+return!0},"call$2","got",4,0,null,178,[],124,[]],
 xf:[function(a){var z,y
 z=new P.ef(a,null,null)
 if(this.H9==null){this.lX=z
@@ -13935,7 +14198,7 @@
 y.sDG(z)
 this.lX=z}this.X5=this.X5+1
 this.zN=this.zN+1&67108863
-return z},"call$1","gTM",2,0,null,124],
+return z},"call$1","gTM",2,0,null,124,[]],
 Vb:[function(a){var z,y
 z=a.gzQ()
 y=a.gDG()
@@ -13944,20 +14207,20 @@
 if(y==null)this.lX=z
 else y.szQ(z)
 this.X5=this.X5-1
-this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,418],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124],
+this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,414,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y].gGc(),b))return y
-return-1},"call$2","gSP",4,0,null,415,124],
+return-1},"call$2","gSP",4,0,null,411,[],124,[]],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 ef:{
-"":"a;Gc<,DG@,zQ@"},
+"^":"a;Gc<,DG@,zQ@"},
 zQ:{
-"":"a;O2,zN,zq,fD",
+"^":"a;O2,zN,zq,fD",
 gl:function(){return this.fD},
 G:[function(){var z=this.O2
 if(this.zN!==z.zN)throw H.b(P.a4(z))
@@ -13965,13 +14228,13 @@
 if(z==null){this.fD=null
 return!1}else{this.fD=z.gGc()
 this.zq=this.zq.gDG()
-return!0}}},"call$0","guK",0,0,null]},
+return!0}}},"call$0","gqy",0,0,null]},
 Yp:{
-"":"Iy;G4",
+"^":"w2Y;G4",
 gB:function(a){return J.q8(this.G4)},
-t:[function(a,b){return J.i4(this.G4,b)},"call$1","gIA",2,0,null,47]},
+t:[function(a,b){return J.i4(this.G4,b)},"call$1","gIA",2,0,null,47,[]]},
 lN:{
-"":"mW;",
+"^":"mW;",
 tt:[function(a,b){var z,y,x,w,v
 if(b){z=H.VM([],[H.Kp(this,0)])
 C.Nm.sB(z,this.gB(this))}else{y=Array(this.gB(this))
@@ -13979,20 +14242,20 @@
 z=H.VM(y,[H.Kp(this,0)])}for(y=this.gA(this),x=0;y.G();x=v){w=y.gl()
 v=x+1
 if(x>=z.length)return H.e(z,x)
-z[x]=w}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=w}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 bu:[function(a){return H.mx(this,"{","}")},"call$0","gXo",0,0,null],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 mW:{
-"":"a;",
-ez:[function(a,b){return H.K1(this,b,H.ip(this,"mW",0),null)},"call$1","gIr",2,0,null,110],
-ev:[function(a,b){return H.VM(new H.U5(this,b),[H.ip(this,"mW",0)])},"call$1","gIR",2,0,null,110],
+"^":"a;",
+ez:[function(a,b){return H.K1(this,b,H.ip(this,"mW",0),null)},"call$1","gIr",2,0,null,110,[]],
+ev:[function(a,b){return H.VM(new H.U5(this,b),[H.ip(this,"mW",0)])},"call$1","gIR",2,0,null,110,[]],
 tg:[function(a,b){var z
 for(z=this.gA(this);z.G();)if(J.de(z.gl(),b))return!0
-return!1},"call$1","gdj",2,0,null,124],
+return!1},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z
-for(z=this.gA(this);z.G();)b.call$1(z.gl())},"call$1","gjw",2,0,null,110],
+for(z=this.gA(this);z.G();)b.call$1(z.gl())},"call$1","gjw",2,0,null,110,[]],
 zV:[function(a,b){var z,y,x
 z=this.gA(this)
 if(!z.G())return""
@@ -14002,21 +14265,18 @@
 else{y.KF(H.d(z.gl()))
 for(;z.G();){y.vM=y.vM+b
 x=H.d(z.gl())
-y.vM=y.vM+x}}return y.vM},"call$1","gnr",0,2,null,334,335],
+y.vM=y.vM+x}}return y.vM},"call$1","gnr",0,2,null,328,329,[]],
 Vr:[function(a,b){var z
 for(z=this.gA(this);z.G();)if(b.call$1(z.gl())===!0)return!0
-return!1},"call$1","gG2",2,0,null,110],
-tt:[function(a,b){return P.F(this,b,H.ip(this,"mW",0))},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+return!1},"call$1","gG2",2,0,null,110,[]],
+tt:[function(a,b){return P.F(this,b,H.ip(this,"mW",0))},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 gB:function(a){var z,y
 z=this.gA(this)
 for(y=0;z.G();)++y
 return y},
 gl0:function(a){return!this.gA(this).G()},
 gor:function(a){return this.gl0(this)!==!0},
-eR:[function(a,b){return H.ke(this,b,H.ip(this,"mW",0))},"call$1","gVQ",2,0,null,292],
-gtH:function(a){var z=this.gA(this)
-if(!z.G())throw H.b(new P.lj("No elements"))
-return z.gl()},
+eR:[function(a,b){return H.ke(this,b,H.ip(this,"mW",0))},"call$1","gZo",2,0,null,287,[]],
 grZ:function(a){var z,y
 z=this.gA(this)
 if(!z.G())throw H.b(new P.lj("No elements"))
@@ -14025,72 +14285,60 @@
 return y},
 qA:[function(a,b,c){var z,y
 for(z=this.gA(this);z.G();){y=z.gl()
-if(b.call$1(y)===!0)return y}throw H.b(new P.lj("No matching element"))},function(a,b){return this.qA(a,b,null)},"XG","call$2$orElse",null,"gyo",2,3,null,77,379,420],
+if(b.call$1(y)===!0)return y}throw H.b(new P.lj("No matching element"))},function(a,b){return this.qA(a,b,null)},"XG","call$2$orElse",null,"gyo",2,3,null,77,372,[],416,[]],
 Zv:[function(a,b){var z,y,x,w
 if(typeof b!=="number"||Math.floor(b)!==b||b<0)throw H.b(P.N(b))
 for(z=this.gA(this),y=b;z.G();){x=z.gl()
 w=J.x(y)
 if(w.n(y,0))return x
-y=w.W(y,1)}throw H.b(P.N(b))},"call$1","goY",2,0,null,47],
+y=w.W(y,1)}throw H.b(P.N(b))},"call$1","goY",2,0,null,47,[]],
 bu:[function(a){return P.FO(this)},"call$0","gXo",0,0,null],
 $iscX:true,
 $ascX:null},
 ar:{
-"":"a+lD;",
+"^":"a+lD;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 lD:{
-"":"a;",
+"^":"a;",
 gA:function(a){return H.VM(new H.a7(a,this.gB(a),0,null),[H.ip(a,"lD",0)])},
-Zv:[function(a,b){return this.t(a,b)},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.t(a,b)},"call$1","goY",2,0,null,47,[]],
 aN:[function(a,b){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){b.call$1(this.t(a,y))
-if(z!==this.gB(a))throw H.b(P.a4(a))}},"call$1","gjw",2,0,null,378],
+if(z!==this.gB(a))throw H.b(P.a4(a))}},"call$1","gjw",2,0,null,371,[]],
 gl0:function(a){return J.de(this.gB(a),0)},
 gor:function(a){return!this.gl0(a)},
 grZ:function(a){if(J.de(this.gB(a),0))throw H.b(new P.lj("No elements"))
 return this.t(a,J.xH(this.gB(a),1))},
-tg:[function(a,b){var z,y
+tg:[function(a,b){var z,y,x,w
 z=this.gB(a)
-if(typeof z!=="number")return H.s(z)
-y=0
-for(;y<z;++y){if(J.de(this.t(a,y),b))return!0
-if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gdj",2,0,null,124],
+y=J.x(z)
+x=0
+while(!0){w=this.gB(a)
+if(typeof w!=="number")return H.s(w)
+if(!(x<w))break
+if(J.de(this.t(a,x),b))return!0
+if(!y.n(z,this.gB(a)))throw H.b(P.a4(a));++x}return!1},"call$1","gdj",2,0,null,124,[]],
 Vr:[function(a,b){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(b.call$1(this.t(a,y))===!0)return!0
-if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gG2",2,0,null,379],
-zV:[function(a,b){var z,y,x,w,v,u
-z=this.gB(a)
-if(b.length!==0){y=J.x(z)
-if(y.n(z,0))return""
-x=H.d(this.t(a,0))
-if(!y.n(z,this.gB(a)))throw H.b(P.a4(a))
-w=P.p9(x)
-if(typeof z!=="number")return H.s(z)
-v=1
-for(;v<z;++v){w.vM=w.vM+b
-u=this.t(a,v)
-u=typeof u==="string"?u:H.d(u)
-w.vM=w.vM+u
-if(z!==this.gB(a))throw H.b(P.a4(a))}return w.vM}else{w=P.p9("")
-if(typeof z!=="number")return H.s(z)
-v=0
-for(;v<z;++v){u=this.t(a,v)
-u=typeof u==="string"?u:H.d(u)
-w.vM=w.vM+u
-if(z!==this.gB(a))throw H.b(P.a4(a))}return w.vM}},"call$1","gnr",0,2,null,334,335],
-ev:[function(a,b){return H.VM(new H.U5(a,b),[H.ip(a,"lD",0)])},"call$1","gIR",2,0,null,379],
-ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110],
-eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gVQ",2,0,null,122],
+if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gG2",2,0,null,372,[]],
+zV:[function(a,b){var z
+if(J.de(this.gB(a),0))return""
+z=P.p9("")
+z.We(a,b)
+return z.vM},"call$1","gnr",0,2,null,328,329,[]],
+ev:[function(a,b){return H.VM(new H.U5(a,b),[H.ip(a,"lD",0)])},"call$1","gIR",2,0,null,372,[]],
+ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
+eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gZo",2,0,null,122,[]],
 tt:[function(a,b){var z,y,x
 if(b){z=H.VM([],[H.ip(a,"lD",0)])
 C.Nm.sB(z,this.gB(a))}else{y=this.gB(a)
@@ -14103,15 +14351,15 @@
 if(!(x<y))break
 y=this.t(a,x)
 if(x>=z.length)return H.e(z,x)
-z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 h:[function(a,b){var z=this.gB(a)
 this.sB(a,J.WB(z,1))
-this.u(a,z,b)},"call$1","ght",2,0,null,124],
+this.u(a,z,b)},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z,y,x
 for(z=J.GP(b);z.G();){y=z.gl()
 x=this.gB(a)
 this.sB(a,J.WB(x,1))
-this.u(a,x,y)}},"call$1","gDY",2,0,null,109],
+this.u(a,x,y)}},"call$1","gDY",2,0,null,109,[]],
 Rz:[function(a,b){var z,y
 z=0
 while(!0){y=this.gB(a)
@@ -14119,13 +14367,13 @@
 if(!(z<y))break
 if(J.de(this.t(a,z),b)){this.YW(a,z,J.xH(this.gB(a),1),a,z+1)
 this.sB(a,J.xH(this.gB(a),1))
-return!0}++z}return!1},"call$1","gRI",2,0,null,124],
+return!0}++z}return!1},"call$1","gRI",2,0,null,124,[]],
 V1:[function(a){this.sB(a,0)},"call$0","gyP",0,0,null],
-So:[function(a,b){H.ZE(a,0,J.xH(this.gB(a),1),b)},"call$1","gH7",0,2,null,77,128],
+GT:[function(a,b){H.ZE(a,0,J.xH(this.gB(a),1),b)},"call$1","gH7",0,2,null,77,128,[]],
 pZ:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.D(b,this.gB(a)))throw H.b(P.TE(b,0,this.gB(a)))
 z=J.Wx(c)
-if(z.C(c,b)||z.D(c,this.gB(a)))throw H.b(P.TE(c,b,this.gB(a)))},"call$2","gbI",4,0,null,115,116],
+if(z.C(c,b)||z.D(c,this.gB(a)))throw H.b(P.TE(c,b,this.gB(a)))},"call$2","gbI",4,0,null,115,[],116,[]],
 D6:[function(a,b,c){var z,y,x,w
 if(c==null)c=this.gB(a)
 this.pZ(a,b,c)
@@ -14136,25 +14384,26 @@
 x=0
 for(;x<z;++x){w=this.t(a,b+x)
 if(x>=y.length)return H.e(y,x)
-y[x]=w}return y},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+y[x]=w}return y},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
 Mu:[function(a,b,c){this.pZ(a,b,c)
-return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,116],
+return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,[],116,[]],
 YW:[function(a,b,c,d,e){var z,y,x,w
-z=this.gB(a)
+if(b>=0){z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
-z=b>z
+z=b>z}else z=!0
 if(z)H.vh(P.TE(b,0,this.gB(a)))
 z=J.Wx(c)
 if(z.C(c,b)||z.D(c,this.gB(a)))H.vh(P.TE(c,b,this.gB(a)))
 y=z.W(c,b)
 if(J.de(y,0))return
+if(e<0)throw H.b(new P.AT(e))
 if(typeof y!=="number")return H.s(y)
 z=J.U6(d)
 x=z.gB(d)
 if(typeof x!=="number")return H.s(x)
 if(e+y>x)throw H.b(new P.lj("Not enough elements"))
 if(e<b)for(w=y-1;w>=0;--w)this.u(a,b+w,z.t(d,e+w))
-else for(w=0;w<y;++w)this.u(a,b+w,z.t(d,e+w))},"call$4","gam",6,2,null,336,115,116,109,117],
+else for(w=0;w<y;++w)this.u(a,b+w,z.t(d,e+w))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 XU:[function(a,b,c){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
@@ -14163,11 +14412,24 @@
 while(!0){z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 if(!(y<z))break
-if(J.de(this.t(a,y),b))return y;++y}return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,124,80],
+if(J.de(this.t(a,y),b))return y;++y}return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],80,[]],
 Pk:[function(a,b,c){var z,y
 c=J.xH(this.gB(a),1)
 for(z=c;y=J.Wx(z),y.F(z,0);z=y.W(z,1))if(J.de(this.t(a,z),b))return z
-return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,124,80],
+return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],80,[]],
+xe:[function(a,b,c){var z
+if(b>=0){z=this.gB(a)
+if(typeof z!=="number")return H.s(z)
+z=b>z}else z=!0
+if(z)throw H.b(P.TE(b,0,this.gB(a)))
+if(b===this.gB(a)){this.h(a,c)
+return}this.sB(a,J.WB(this.gB(a),1))
+this.YW(a,b+1,this.gB(a),a,b)
+this.u(a,b,c)},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){var z=this.t(a,b)
+this.YW(a,b,J.xH(this.gB(a),1),a,b+1)
+this.sB(a,J.xH(this.gB(a),1))
+return z},"call$1","gNM",2,0,null,47,[]],
 bu:[function(a){var z
 if($.xb().tg(0,a))return"[...]"
 z=P.p9("")
@@ -14181,34 +14443,34 @@
 $iscX:true,
 $ascX:null},
 ZQ:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.a
 if(!z.a)this.b.KF(", ")
 z.a=!1
 z=this.b
 z.KF(a)
 z.KF(": ")
-z.KF(b)},"call$2",null,4,0,null,421,277,"call"],
+z.KF(b)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 Sw:{
-"":"mW;v5,av,HV,qT",
-gA:function(a){var z=new P.o0(this,this.HV,this.qT,this.av,null)
+"^":"mW;v5,av,eZ,qT",
+gA:function(a){var z=new P.o0(this,this.eZ,this.qT,this.av,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 aN:[function(a,b){var z,y,x
 z=this.qT
-for(y=this.av;y!==this.HV;y=(y+1&this.v5.length-1)>>>0){x=this.v5
+for(y=this.av;y!==this.eZ;y=(y+1&this.v5.length-1)>>>0){x=this.v5
 if(y<0||y>=x.length)return H.e(x,y)
 b.call$1(x[y])
-if(z!==this.qT)H.vh(P.a4(this))}},"call$1","gjw",2,0,null,378],
-gl0:function(a){return this.av===this.HV},
-gB:function(a){return J.KV(J.xH(this.HV,this.av),this.v5.length-1)},
+if(z!==this.qT)H.vh(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
+gl0:function(a){return this.av===this.eZ},
+gB:function(a){return J.mQ(J.xH(this.eZ,this.av),this.v5.length-1)},
 grZ:function(a){var z,y
 z=this.av
-y=this.HV
+y=this.eZ
 if(z===y)throw H.b(new P.lj("No elements"))
 z=this.v5
-y=J.KV(J.xH(y,1),this.v5.length-1)
+y=J.mQ(J.xH(y,1),this.v5.length-1)
 if(y>=z.length)return H.e(z,y)
 return z[y]},
 Zv:[function(a,b){var z,y,x
@@ -14220,14 +14482,14 @@
 x=z.length
 y=(y+b&x-1)>>>0
 if(y<0||y>=x)return H.e(z,y)
-return z[y]},"call$1","goY",2,0,null,47],
+return z[y]},"call$1","goY",2,0,null,47,[]],
 tt:[function(a,b){var z,y
 if(b){z=H.VM([],[H.Kp(this,0)])
 C.Nm.sB(z,this.gB(this))}else{y=Array(this.gB(this))
 y.fixed$length=init
 z=H.VM(y,[H.Kp(this,0)])}this.e4(z)
-return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
-h:[function(a,b){this.NZ(0,b)},"call$1","ght",2,0,null,124],
+return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
+h:[function(a,b){this.NZ(0,b)},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z,y,x,w,v,u,t,s,r
 z=J.x(b)
 if(typeof b==="object"&&b!==null&&(b.constructor===Array||!!z.$isList)){y=z.gB(b)
@@ -14241,131 +14503,128 @@
 w=Array(u)
 w.fixed$length=init
 t=H.VM(w,[H.Kp(this,0)])
-this.HV=this.e4(t)
+this.eZ=this.e4(t)
 this.v5=t
 this.av=0
-H.qG(t,x,z,b,0)
-this.HV=J.WB(this.HV,y)}else{z=this.HV
+H.Og(t,x,z,b,0)
+this.eZ=J.WB(this.eZ,y)}else{z=this.eZ
 if(typeof z!=="number")return H.s(z)
 s=v-z
-if(y<s){H.qG(w,z,z+y,b,0)
-this.HV=J.WB(this.HV,y)}else{r=y-s
-H.qG(w,z,z+s,b,0)
+if(y<s){H.Og(w,z,z+y,b,0)
+this.eZ=J.WB(this.eZ,y)}else{r=y-s
+H.Og(w,z,z+s,b,0)
 z=this.v5
-H.qG(z,0,r,b,s)
-this.HV=r}}this.qT=this.qT+1}else for(z=z.gA(b);z.G();)this.NZ(0,z.gl())},"call$1","gDY",2,0,null,422],
+H.Og(z,0,r,b,s)
+this.eZ=r}}this.qT=this.qT+1}else for(z=z.gA(b);z.G();)this.NZ(0,z.gl())},"call$1","gDY",2,0,null,418,[]],
 Rz:[function(a,b){var z,y
-for(z=this.av;z!==this.HV;z=(z+1&this.v5.length-1)>>>0){y=this.v5
+for(z=this.av;z!==this.eZ;z=(z+1&this.v5.length-1)>>>0){y=this.v5
 if(z<0||z>=y.length)return H.e(y,z)
 if(J.de(y[z],b)){this.bB(z)
 this.qT=this.qT+1
-return!0}}return!1},"call$1","gRI",2,0,null,6],
+return!0}}return!1},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){var z,y,x,w,v
 z=this.av
-y=this.HV
+y=this.eZ
 if(z!==y){for(x=this.v5,w=x.length,v=w-1;z!==y;z=(z+1&v)>>>0){if(z<0||z>=w)return H.e(x,z)
-x[z]=null}this.HV=0
+x[z]=null}this.eZ=0
 this.av=0
 this.qT=this.qT+1}},"call$0","gyP",0,0,null],
 bu:[function(a){return H.mx(this,"{","}")},"call$0","gXo",0,0,null],
-Ux:[function(){var z,y,x,w
-z=this.av
-if(z===this.HV)throw H.b(P.w("No elements"))
-this.qT=this.qT+1
-y=this.v5
-x=y.length
-if(z>=x)return H.e(y,z)
-w=y[z]
-this.av=(z+1&x-1)>>>0
-return w},"call$0","gdm",0,0,null],
-NZ:[function(a,b){var z,y,x,w
+NZ:[function(a,b){var z,y
 z=this.v5
-y=this.HV
+y=this.eZ
 if(y>>>0!==y||y>=z.length)return H.e(z,y)
 z[y]=b
 y=(y+1&this.v5.length-1)>>>0
-this.HV=y
-if(this.av===y){x=Array(this.v5.length*2)
-x.fixed$length=init
-x.$builtinTypeInfo=[H.Kp(this,0)]
-z=this.v5
-y=this.av
-w=z.length-y
-H.qG(x,0,w,z,y)
-z=this.av
-y=this.v5
-H.qG(x,w,w+z,y,0)
-this.av=0
-this.HV=this.v5.length
-this.v5=x}this.qT=this.qT+1},"call$1","gXk",2,0,null,124],
+this.eZ=y
+if(this.av===y)this.VW()
+this.qT=this.qT+1},"call$1","gXk",2,0,null,124,[]],
 bB:[function(a){var z,y,x,w,v,u,t,s
 z=this.v5.length-1
-if((a-this.av&z)>>>0<J.KV(J.xH(this.HV,a),z)){for(y=this.av,x=this.v5,w=x.length,v=a;v!==y;v=u){u=(v-1&z)>>>0
+if((a-this.av&z)>>>0<J.mQ(J.xH(this.eZ,a),z)){for(y=this.av,x=this.v5,w=x.length,v=a;v!==y;v=u){u=(v-1&z)>>>0
 if(u<0||u>=w)return H.e(x,u)
 t=x[u]
 if(v<0||v>=w)return H.e(x,v)
 x[v]=t}if(y>=w)return H.e(x,y)
 x[y]=null
 this.av=(y+1&z)>>>0
-return(a+1&z)>>>0}else{y=J.KV(J.xH(this.HV,1),z)
-this.HV=y
+return(a+1&z)>>>0}else{y=J.mQ(J.xH(this.eZ,1),z)
+this.eZ=y
 for(x=this.v5,w=x.length,v=a;v!==y;v=s){s=(v+1&z)>>>0
 if(s<0||s>=w)return H.e(x,s)
 t=x[s]
 if(v<0||v>=w)return H.e(x,v)
 x[v]=t}if(y>=w)return H.e(x,y)
 x[y]=null
-return a}},"call$1","gzv",2,0,null,423],
+return a}},"call$1","gzv",2,0,null,419,[]],
+VW:[function(){var z,y,x,w
+z=Array(this.v5.length*2)
+z.fixed$length=init
+y=H.VM(z,[H.Kp(this,0)])
+z=this.v5
+x=this.av
+w=z.length-x
+H.Og(y,0,w,z,x)
+z=this.av
+x=this.v5
+H.Og(y,w,w+z,x,0)
+this.av=0
+this.eZ=this.v5.length
+this.v5=y},"call$0","gJm",0,0,null],
 e4:[function(a){var z,y,x,w
 z=this.av
-y=this.HV
+y=this.eZ
 if(typeof y!=="number")return H.s(y)
 if(z<=y){x=y-z
 z=this.v5
 y=this.av
-H.qG(a,0,x,z,y)
+H.Og(a,0,x,z,y)
 return x}else{y=this.v5
 w=y.length-z
-H.qG(a,0,w,y,z)
-z=this.HV
+H.Og(a,0,w,y,z)
+z=this.eZ
 if(typeof z!=="number")return H.s(z)
 y=this.v5
-H.qG(a,w,w+z,y,0)
-return J.WB(this.HV,w)}},"call$1","gLR",2,0,null,74],
-Eo:function(a,b){var z=Array(8)
+H.Og(a,w,w+z,y,0)
+return J.WB(this.eZ,w)}},"call$1","gLR",2,0,null,74,[]],
+Eo:function(a,b){var z
+if(typeof 8!=="number")return H.s(8)
+z=Array(8)
 z.fixed$length=init
 this.v5=H.VM(z,[b])},
 $isyN:true,
 $iscX:true,
 $ascX:null,
-static:{"":"Mo",ua:[function(a){var z
+static:{"^":"Mo",NZ:function(a,b){var z=H.VM(new P.Sw(null,0,0,0),[b])
+z.Eo(a,b)
+return z},ua:[function(a){var z
 if(typeof a!=="number")return a.O()
 a=(a<<2>>>0)-1
 for(;!0;a=z){z=(a&a-1)>>>0
-if(z===0)return a}},"call$1","bD",2,0,null,184]}},
+if(z===0)return a}},"call$1","W5",2,0,null,184,[]]}},
 o0:{
-"":"a;Lz,dP,qT,Dc,fD",
+"^":"a;Lz,pP,qT,Dc,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
 z=this.Lz
 if(this.qT!==z.qT)H.vh(P.a4(z))
 y=this.Dc
-if(y===this.dP){this.fD=null
+if(y===this.pP){this.fD=null
 return!1}z=z.v5
 x=z.length
 if(y>=x)return H.e(z,y)
 this.fD=z[y]
 this.Dc=(y+1&x-1)>>>0
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 qv:{
-"":"a;G3>,Bb>,T8>",
+"^":"a;G3>,Bb<,T8<",
 $isqv:true},
 jp:{
-"":"qv;P*,G3,Bb,T8",
+"^":"qv;P*,G3,Bb,T8",
 r6:function(a,b){return this.P.call$1(b)},
 $asqv:function(a,b){return[a]}},
 vX:{
-"":"a;",
+"^":"a;",
 vh:[function(a){var z,y,x,w,v,u,t,s
 z=this.aY
 if(z==null)return-1
@@ -14400,10 +14659,10 @@
 y.T8=null
 y.Bb=null
 this.bb=this.bb+1
-return v},"call$1","gST",2,0,null,42],
+return v},"call$1","gST",2,0,null,42,[]],
 Xu:[function(a){var z,y
 for(z=a;y=z.T8,y!=null;z=y){z.T8=y.Bb
-y.Bb=z}return z},"call$1","gOv",2,0,null,265],
+y.Bb=z}return z},"call$1","gOv",2,0,null,259,[]],
 bB:[function(a){var z,y,x
 if(this.aY==null)return
 if(!J.de(this.vh(a),0))return
@@ -14415,8 +14674,8 @@
 else{y=this.Xu(y)
 this.aY=y
 y.T8=x}this.qT=this.qT+1
-return z},"call$1","gzv",2,0,null,42],
-K8:[function(a,b){var z,y
+return z},"call$1","gzv",2,0,null,42,[]],
+fS:[function(a,b){var z,y
 this.P6=this.P6+1
 this.qT=this.qT+1
 if(this.aY==null){this.aY=a
@@ -14426,29 +14685,27 @@
 a.T8=y.T8
 y.T8=null}else{a.T8=y
 a.Bb=y.Bb
-y.Bb=null}this.aY=a},"call$2","gSx",4,0,null,265,424]},
+y.Bb=null}this.aY=a},"call$2","gSx",4,0,null,259,[],420,[]]},
 Ba:{
-"":"vX;Cw,ac,aY,iW,P6,qT,bb",
+"^":"vX;Cw,ac,aY,iW,P6,qT,bb",
 wS:function(a,b){return this.Cw.call$2(a,b)},
 Ef:function(a){return this.ac.call$1(a)},
-yV:[function(a,b){return this.wS(a,b)},"call$2","gNA",4,0,null,425,426],
+yV:[function(a,b){return this.wS(a,b)},"call$2","gNA",4,0,null,421,[],422,[]],
 t:[function(a,b){if(b==null)throw H.b(new P.AT(b))
 if(this.Ef(b)!==!0)return
 if(this.aY!=null)if(J.de(this.vh(b),0))return this.aY.P
-return},"call$1","gIA",2,0,null,42],
+return},"call$1","gIA",2,0,null,42,[]],
 Rz:[function(a,b){var z
 if(this.Ef(b)!==!0)return
 z=this.bB(b)
 if(z!=null)return z.P
-return},"call$1","gRI",2,0,null,42],
-u:[function(a,b,c){var z,y
+return},"call$1","gRI",2,0,null,42,[]],
+u:[function(a,b,c){var z
 if(b==null)throw H.b(new P.AT(b))
 z=this.vh(b)
 if(J.de(z,0)){this.aY.P=c
-return}y=new P.jp(c,b,null,null)
-y.$builtinTypeInfo=[null,null]
-this.K8(y,z)},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){J.kH(b,new P.bF(this))},"call$1","gDY",2,0,null,104],
+return}this.fS(H.VM(new P.jp(c,b,null,null),[null,null]),z)},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){J.kH(b,new P.bF(this))},"call$1","gDY",2,0,null,104,[]],
 gl0:function(a){return this.aY==null},
 gor:function(a){return this.aY!=null},
 aN:[function(a,b){var z,y,x
@@ -14457,13 +14714,13 @@
 y.Qf(this,[P.qv,z])
 for(;y.G();){x=y.gl()
 z=J.RE(x)
-b.call$2(z.gG3(x),z.gP(x))}},"call$1","gjw",2,0,null,110],
+b.call$2(z.gG3(x),z.gP(x))}},"call$1","gjw",2,0,null,110,[]],
 gB:function(a){return this.P6},
 V1:[function(a){this.aY=null
 this.P6=0
 this.qT=this.qT+1},"call$0","gyP",0,0,null],
-x4:[function(a){return this.Ef(a)===!0&&J.de(this.vh(a),0)},"call$1","gV9",2,0,null,42],
-di:[function(a){return new P.LD(this,a,this.bb).call$1(this.aY)},"call$1","gmc",2,0,null,23],
+x4:[function(a){return this.Ef(a)===!0&&J.de(this.vh(a),0)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return new P.LD(this,a,this.bb).call$1(this.aY)},"call$1","gmc",2,0,null,23,[]],
 gvc:function(a){return H.VM(new P.OG(this),[H.Kp(this,0)])},
 gUQ:function(a){var z=new P.uM(this)
 z.$builtinTypeInfo=this.$builtinTypeInfo
@@ -14478,32 +14735,32 @@
 y=new P.An(c)
 return H.VM(new P.Ba(z,y,null,H.VM(new P.qv(null,null,null),[c]),0,0,0),[c,d])}}},
 An:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 bF:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"ri",args:[a,b]}},this.a,"Ba")}},
 LD:{
-"":"Tp:427;a,b,c",
+"^":"Tp:423;a,b,c",
 call$1:[function(a){var z,y,x,w
 for(z=this.c,y=this.a,x=this.b;a!=null;){if(J.de(a.P,x))return!0
 if(z!==y.bb)throw H.b(P.a4(y))
 w=a.T8
 if(w!=null&&this.call$1(w)===!0)return!0
-a=a.Bb}return!1},"call$1",null,2,0,null,265,"call"],
+a=a.Bb}return!1},"call$1",null,2,0,null,259,[],"call"],
 $isEH:true},
 S6B:{
-"":"a;",
+"^":"a;",
 gl:function(){var z=this.ya
 if(z==null)return
 return this.Wb(z)},
 WV:[function(a){var z
 for(z=this.Ln;a!=null;){z.push(a)
-a=a.Bb}},"call$1","gBl",2,0,null,265],
+a=a.Bb}},"call$1","gBl",2,0,null,259,[]],
 G:[function(){var z,y,x
 z=this.Dn
 if(this.qT!==z.qT)throw H.b(P.a4(z))
@@ -14517,10 +14774,10 @@
 z=y.pop()
 this.ya=z
 this.WV(z.T8)
-return!0},"call$0","guK",0,0,null],
+return!0},"call$0","gqy",0,0,null],
 Qf:function(a,b){this.WV(a.aY)}},
 OG:{
-"":"mW;Dn",
+"^":"mW;Dn",
 gB:function(a){return this.Dn.P6},
 gl0:function(a){return this.Dn.P6===0},
 gA:function(a){var z,y
@@ -14531,7 +14788,7 @@
 return y},
 $isyN:true},
 uM:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.P6},
 gl0:function(a){return this.Fb.P6===0},
 gA:function(a){var z,y
@@ -14544,33 +14801,33 @@
 $ascX:function(a,b){return[b]},
 $isyN:true},
 DN:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a.G3},"call$1","gBL",2,0,null,265]},
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a.G3},"call$1","gBL",2,0,null,259,[]]},
 ZM:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a.P},"call$1","gBL",2,0,null,265],
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a.P},"call$1","gBL",2,0,null,259,[]],
 $asS6B:function(a,b){return[b]}},
 HW:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a},"call$1","gBL",2,0,null,265],
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a},"call$1","gBL",2,0,null,259,[]],
 $asS6B:function(a){return[[P.qv,a]]}}}],["dart.convert","dart:convert",,P,{
-"":"",
+"^":"",
 VQ:[function(a,b){var z=new P.JC()
-return z.call$2(null,new P.f1(z).call$1(a))},"call$2","os",4,0,null,185,186],
+return z.call$2(null,new P.f1(z).call$1(a))},"call$2","os",4,0,null,185,[],186,[]],
 BS:[function(a,b){var z,y,x,w
 x=a
 if(typeof x!=="string")throw H.b(new P.AT(a))
 z=null
 try{z=JSON.parse(a)}catch(w){x=H.Ru(w)
 y=x
-throw H.b(P.cD(String(y)))}return P.VQ(z,b)},"call$2","pi",4,0,null,27,186],
-tp:[function(a){return a.Lt()},"call$1","BC",2,0,187,6],
+throw H.b(P.cD(String(y)))}return P.VQ(z,b)},"call$2","H44",4,0,null,27,[],186,[]],
+tp:[function(a){return a.Lt()},"call$1","BC",2,0,187,6,[]],
 JC:{
-"":"Tp:349;",
-call$2:[function(a,b){return b},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return b},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 f1:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w,v,u,t
 if(a==null||typeof a!="object")return a
 if(Object.getPrototypeOf(a)===Array.prototype){z=a
@@ -14580,41 +14837,43 @@
 for(y=this.a,x=0;x<w.length;++x){u=w[x]
 v.u(0,u,y.call$2(u,this.call$1(a[u])))}t=a.__proto__
 if(typeof t!=="undefined"&&t!==Object.prototype)v.u(0,"__proto__",y.call$2("__proto__",this.call$1(t)))
-return v},"call$1",null,2,0,null,18,"call"],
+return v},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Uk:{
-"":"a;"},
+"^":"a;"},
 wI:{
-"":"a;"},
+"^":"a;"},
 Zi:{
-"":"Uk;",
+"^":"Uk;",
 $asUk:function(){return[J.O,[J.Q,J.im]]}},
 Ud:{
-"":"Ge;Ct,FN",
+"^":"Ge;Ct,FN",
 bu:[function(a){if(this.FN!=null)return"Converting object to an encodable object failed."
 else return"Converting object did not return an encodable object."},"call$0","gXo",0,0,null],
 static:{ox:function(a,b){return new P.Ud(a,b)}}},
 K8:{
-"":"Ud;Ct,FN",
+"^":"Ud;Ct,FN",
 bu:[function(a){return"Cyclic error in JSON stringify"},"call$0","gXo",0,0,null],
 static:{TP:function(a){return new P.K8(a,null)}}},
 by:{
-"":"Uk;",
-pW:[function(a,b){return P.BS(a,C.A3.N5)},function(a){return this.pW(a,null)},"kV","call$2$reviver",null,"gzL",2,3,null,77,27,186],
-PN:[function(a,b){return P.Vg(a,C.Ap.Xi)},function(a){return this.PN(a,null)},"KP","call$2$toEncodable",null,"gr8",2,3,null,77,23,188],
+"^":"Uk;N5,iY",
+pW:[function(a,b){return P.BS(a,this.gHe().N5)},function(a){return this.pW(a,null)},"kV","call$2$reviver",null,"gzL",2,3,null,77,27,[],186,[]],
+PN:[function(a,b){return P.Vg(a,this.gZE().Xi)},function(a){return this.PN(a,null)},"KP","call$2$toEncodable",null,"gV0",2,3,null,77,23,[],188,[]],
+gZE:function(){return C.Ap},
+gHe:function(){return C.A3},
 $asUk:function(){return[P.a,J.O]}},
-pD:{
-"":"wI;Xi",
+dI:{
+"^":"wI;Xi",
 $aswI:function(){return[P.a,J.O]}},
 Cf:{
-"":"wI;N5",
+"^":"wI;N5",
 $aswI:function(){return[J.O,P.a]}},
 Sh:{
-"":"a;WE,Mw,JN",
+"^":"a;WE,Mw,JN",
 Tt:function(a){return this.WE.call$1(a)},
 WD:[function(a){var z=this.JN
 if(z.tg(0,a))throw H.b(P.TP(a))
-z.h(0,a)},"call$1","gUW",2,0,null,6],
+z.h(0,a)},"call$1","gUW",2,0,null,6,[]],
 rl:[function(a){var z,y,x,w,v
 if(!this.IS(a)){x=a
 w=this.JN
@@ -14624,7 +14883,7 @@
 if(!this.IS(z)){x=P.ox(a,null)
 throw H.b(x)}w.Rz(0,a)}catch(v){x=H.Ru(v)
 y=x
-throw H.b(P.ox(a,y))}}},"call$1","gO5",2,0,null,6],
+throw H.b(P.ox(a,y))}}},"call$1","gO5",2,0,null,6,[]],
 IS:[function(a){var z,y,x,w
 z={}
 if(typeof a==="number"){if(!C.CD.gx8(a))return!1
@@ -14655,12 +14914,12 @@
 y.aN(a,new P.tF(z,this))
 w.KF("}")
 this.JN.Rz(0,a)
-return!0}else return!1}},"call$1","gjQ",2,0,null,6],
-static:{"":"P3,kD,IE,Yz,ij,fg,SW,KQz,MU,ql,NXu,PBv,QVv",Vg:[function(a,b){var z
+return!0}else return!1}},"call$1","gjQ",2,0,null,6,[]],
+static:{"^":"P3,kD,IE,Yz,No,fg,SW,KQz,MU,ql,NXu,CE,QVv",Vg:[function(a,b){var z
 b=P.BC()
 z=P.p9("")
 new P.Sh(b,z,P.yv(null)).rl(a)
-return z.vM},"call$2","Sr",4,0,null,6,188],NY:[function(a,b){var z,y,x,w,v,u,t
+return z.vM},"call$2","ab",4,0,null,6,[],188,[]],NY:[function(a,b){var z,y,x,w,v,u,t
 z=J.U6(b)
 y=z.gB(b)
 x=H.VM([],[J.im])
@@ -14690,9 +14949,9 @@
 x.push(t<10?48+t:87+t)
 break}w=!0}else if(u===34||u===92){x.push(92)
 x.push(u)
-w=!0}else x.push(u)}a.KF(w?P.HM(x):b)},"call$2","qW",4,0,null,189,86]}},
+w=!0}else x.push(u)}a.KF(w?P.HM(x):b)},"call$2","qW",4,0,null,189,[],86,[]]}},
 tF:{
-"":"Tp:428;a,b",
+"^":"Tp:424;a,b",
 call$2:[function(a,b){var z,y,x
 z=this.a
 y=this.b
@@ -14701,14 +14960,14 @@
 x.KF("\"")}P.NY(x,a)
 x.KF("\":")
 y.rl(b)
-z.a=!1},"call$2",null,4,0,null,42,23,"call"],
+z.a=!1},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 z0:{
-"":"Zi;lH",
+"^":"Zi;lH",
 goc:function(a){return"utf-8"},
 gZE:function(){return new P.E3()}},
 E3:{
-"":"wI;",
+"^":"wI;",
 WJ:[function(a){var z,y,x
 z=J.U6(a)
 y=J.p0(z.gB(a),3)
@@ -14716,10 +14975,10 @@
 y=H.VM(Array(y),[J.im])
 x=new P.Rw(0,0,y)
 if(x.fJ(a,0,z.gB(a))!==z.gB(a))x.Lb(z.j(a,J.xH(z.gB(a),1)),0)
-return C.Nm.D6(y,0,x.ZP)},"call$1","gmC",2,0,null,26],
+return C.Nm.D6(y,0,x.ZP)},"call$1","gmC",2,0,null,26,[]],
 $aswI:function(){return[J.O,[J.Q,J.im]]}},
 Rw:{
-"":"a;WF,ZP,EN",
+"^":"a;WF,ZP,EN",
 Lb:[function(a,b){var z,y,x,w,v
 z=this.EN
 y=this.ZP
@@ -14752,7 +15011,7 @@
 this.ZP=y+1
 if(y>=v)return H.e(z,y)
 z[y]=128|a&63
-return!1}},"call$2","gkL",4,0,null,429,430],
+return!1}},"call$2","gkL",4,0,null,425,[],426,[]],
 fJ:[function(a,b,c){var z,y,x,w,v,u,t,s
 if(b!==c&&(J.lE(a,J.xH(c,1))&64512)===55296)c=J.xH(c,1)
 if(typeof c!=="number")return H.s(c)
@@ -14785,82 +15044,11 @@
 z[s]=128|v>>>6&63
 this.ZP=u+1
 if(u>=y)return H.e(z,u)
-z[u]=128|v&63}}return w},"call$3","gkH",6,0,null,340,115,116],
-static:{"":"Ij"}},
-GY:{
-"":"wI;lH",
-WJ:[function(a){var z,y
-z=P.p9("")
-y=new P.jZ(this.lH,z,!0,0,0,0)
-y.ME(a,0,J.q8(a))
-y.fZ()
-return z.vM},"call$1","gmC",2,0,null,431],
-$aswI:function(){return[[J.Q,J.im],J.O]}},
-jZ:{
-"":"a;lH,aS,rU,Ok,TY,VN",
-cO:[function(a){this.fZ()},"call$0","gJK",0,0,null],
-fZ:[function(){if(this.TY>0){if(this.lH!==!0)throw H.b(P.cD("Unfinished UTF-8 octet sequence"))
-this.aS.KF(P.fc(65533))
-this.Ok=0
-this.TY=0
-this.VN=0}},"call$0","gRh",0,0,null],
-ME:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
-z=this.Ok
-y=this.TY
-x=this.VN
-this.Ok=0
-this.TY=0
-this.VN=0
-$loop$0:for(w=this.aS,v=this.lH!==!0,u=J.U6(a),t=b;!0;t=p){$multibyte$2:{if(y>0){do{if(t===c)break $loop$0
-s=u.t(a,t)
-r=J.Wx(s)
-if(r.i(s,192)!==128){if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+r.WZ(s,16)))
-this.rU=!1
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r
-y=0
-break $multibyte$2}else{z=(z<<6|r.i(s,63))>>>0;--y;++t}}while(y>0)
-r=x-1
-if(r<0||r>=4)return H.e(C.Gb,r)
-if(z<=C.Gb[r]){if(v)throw H.b(P.cD("Overlong encoding of 0x"+C.jn.WZ(z,16)))
-z=65533
-y=0
-x=0}if(z>1114111){if(v)throw H.b(P.cD("Character outside valid Unicode range: 0x"+C.jn.WZ(z,16)))
-z=65533}if(!this.rU||z!==65279){q=P.O8(1,z,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}this.rU=!1}}for(;t<c;t=p){p=t+1
-s=u.t(a,t)
-r=J.Wx(s)
-if(r.C(s,0)){if(v)throw H.b(P.cD("Negative UTF-8 code unit: -0x"+C.CD.WZ(r.J(s),16)))
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}else if(r.E(s,127)){this.rU=!1
-q=P.O8(1,s,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}else{if(r.i(s,224)===192){z=r.i(s,31)
-y=1
-x=1
-continue $loop$0}if(r.i(s,240)===224){z=r.i(s,15)
-y=2
-x=2
-continue $loop$0}if(r.i(s,248)===240&&r.C(s,245)){z=r.i(s,7)
-y=3
-x=3
-continue $loop$0}if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+r.WZ(s,16)))
-this.rU=!1
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r
-z=65533
-y=0
-x=0}}break $loop$0}if(y>0){this.Ok=z
-this.TY=y
-this.VN=x}},"call$3","gmC",6,0,null,431,80,125],
-static:{"":"PO"}}}],["dart.core","dart:core",,P,{
-"":"",
-Te:[function(a){return},"call$1","PM",2,0,null,44],
-Wc:[function(a,b){return J.oE(a,b)},"call$2","n4",4,0,190,123,180],
+z[u]=128|v&63}}return w},"call$3","gkH",6,0,null,334,[],115,[],116,[]],
+static:{"^":"n9"}}}],["dart.core","dart:core",,P,{
+"^":"",
+Te:[function(a){return},"call$1","PM",2,0,null,44,[]],
+Wc:[function(a,b){return J.oE(a,b)},"call$2","n4",4,0,190,123,[],180,[]],
 hl:[function(a){var z,y,x,w,v,u
 if(typeof a==="number"||typeof a==="boolean"||null==a)return J.AG(a)
 if(typeof a==="string"){z=new P.Rn("")
@@ -14884,11 +15072,11 @@
 w=z.vM+w
 z.vM=w}}y=w+"\""
 z.vM=y
-return y}return"Instance of '"+H.lh(a)+"'"},"call$1","Zx",2,0,null,6],
+return y}return"Instance of '"+H.lh(a)+"'"},"call$1","Zx",2,0,null,6,[]],
 FM:function(a){return new P.HG(a)},
-ad:[function(a,b){return a==null?b==null:a===b},"call$2","N3",4,0,192,123,180],
-xv:[function(a){return H.CU(a)},"call$1","J2",2,0,193,6],
-QA:[function(a,b,c){return H.BU(a,c,b)},function(a){return P.QA(a,null,null)},null,function(a,b){return P.QA(a,b,null)},null,"call$3$onError$radix","call$1","call$2$onError","ya",2,5,194,77,77,27,156,28],
+ad:[function(a,b){return a==null?b==null:a===b},"call$2","N3",4,0,192,123,[],180,[]],
+xv:[function(a){return H.CU(a)},"call$1","J2",2,0,193,6,[]],
+QA:[function(a,b,c){return H.BU(a,c,b)},function(a){return P.QA(a,null,null)},null,function(a,b){return P.QA(a,b,null)},null,"call$3$onError$radix","call$1","call$2$onError","ya",2,5,194,77,77,27,[],156,[],28,[]],
 O8:function(a,b,c){var z,y,x
 z=J.Qi(a,c)
 if(a!==0&&b!=null)for(y=z.length,x=0;x<y;++x)z[x]=b
@@ -14909,39 +15097,39 @@
 z=H.d(a)
 y=$.oK
 if(y==null)H.qw(z)
-else y.call$1(z)},"call$1","Pl",2,0,null,6],
+else y.call$1(z)},"call$1","Pl",2,0,null,6,[]],
 HM:function(a){return H.eT(a)},
 fc:function(a){return P.HM(P.O8(1,a,J.im))},
 HB:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,a.gfN(a),b)},"call$2",null,4,0,null,129,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,a.gfN(a),b)},"call$2",null,4,0,null,129,[],23,[],"call"],
 $isEH:true},
 CL:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){var z=this.a
 if(z.b>0)z.a.KF(", ")
 z.a.KF(J.GL(a))
 z.a.KF(": ")
 z.a.KF(P.hl(b))
-z.b=z.b+1},"call$2",null,4,0,null,42,23,"call"],
+z.b=z.b+1},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 p4:{
-"":"a;OF",
+"^":"a;OF",
 bu:[function(a){return"Deprecated feature. Will be removed "+this.OF},"call$0","gXo",0,0,null]},
 a2:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return this?"true":"false"},"call$0","gXo",0,0,null],
 $isbool:true},
 fR:{
-"":"a;"},
+"^":"a;"},
 iP:{
-"":"a;y3<,aL",
+"^":"a;y3<,aL",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isiP)return!1
-return this.y3===b.y3&&this.aL===b.aL},"call$1","gUJ",2,0,null,104],
-iM:[function(a,b){return C.CD.iM(this.y3,b.gy3())},"call$1","gYc",2,0,null,104],
+return this.y3===b.y3&&this.aL===b.aL},"call$1","gUJ",2,0,null,104,[]],
+iM:[function(a,b){return C.CD.iM(this.y3,b.gy3())},"call$1","gYc",2,0,null,104,[]],
 giO:function(a){return this.y3},
 bu:[function(a){var z,y,x,w,v,u,t,s,r,q
 z=new P.B5()
@@ -14957,11 +15145,11 @@
 q=new P.Zl().call$1(z)
 if(y)return H.d(w)+"-"+H.d(v)+"-"+H.d(u)+" "+H.d(t)+":"+H.d(s)+":"+H.d(r)+"."+H.d(q)+"Z"
 else return H.d(w)+"-"+H.d(v)+"-"+H.d(u)+" "+H.d(t)+":"+H.d(s)+":"+H.d(r)+"."+H.d(q)},"call$0","gXo",0,0,null],
-h:[function(a,b){return P.Wu(this.y3+b.gVs(),this.aL)},"call$1","ght",2,0,null,159],
+h:[function(a,b){return P.Wu(this.y3+b.gVs(),this.aL)},"call$1","ght",2,0,null,159,[]],
 EK:function(){H.o2(this)},
 RM:function(a,b){if(Math.abs(a)>8640000000000000)throw H.b(new P.AT(a))},
 $isiP:true,
-static:{"":"aV,bI,df,Kw,h2,mo,EQe,Qg,tp1,Gi,k3,cR,E0,mj,lT,Nr,bm,FI,Kz,J7,TO,lme",Gl:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
+static:{"^":"aV,bI,Hq,Kw,h2,pa,EQe,NXt,tp1,Gi,k3,cR,E0,fH,Ne,Nr,bmS,FI,Kz,J7,dM,lme",Gl:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=new H.VR(H.v4("^([+-]?\\d?\\d\\d\\d\\d)-?(\\d\\d)-?(\\d\\d)(?:[ T](\\d\\d)(?::?(\\d\\d)(?::?(\\d\\d)(.\\d{1,6})?)?)?( ?[zZ]| ?\\+00(?::?00)?)?)?$",!1,!0,!1),null,null).ej(a)
 if(z!=null){y=new P.MF()
 x=z.QK
@@ -14984,60 +15172,60 @@
 if(8>=x.length)return H.e(x,8)
 o=x[8]!=null
 n=H.zW(w,v,u,t,s,r,q,o)
-return P.Wu(p?n+1:n,o)}else throw H.b(P.cD(a))},"call$1","lel",2,0,null,191],Wu:function(a,b){var z=new P.iP(a,b)
+return P.Wu(p?n+1:n,o)}else throw H.b(P.cD(a))},"call$1","lel",2,0,null,191,[]],Wu:function(a,b){var z=new P.iP(a,b)
 z.RM(a,b)
 return z}}},
 MF:{
-"":"Tp:433;",
+"^":"Tp:428;",
 call$1:[function(a){if(a==null)return 0
-return H.BU(a,null,null)},"call$1",null,2,0,null,432,"call"],
+return H.BU(a,null,null)},"call$1",null,2,0,null,427,[],"call"],
 $isEH:true},
 Rq:{
-"":"Tp:434;",
+"^":"Tp:429;",
 call$1:[function(a){if(a==null)return 0
-return H.IH(a,null)},"call$1",null,2,0,null,432,"call"],
+return H.IH(a,null)},"call$1",null,2,0,null,427,[],"call"],
 $isEH:true},
 Hn:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){var z,y
 z=Math.abs(a)
 y=a<0?"-":""
 if(z>=1000)return""+a
 if(z>=100)return y+"0"+H.d(z)
 if(z>=10)return y+"00"+H.d(z)
-return y+"000"+H.d(z)},"call$1",null,2,0,null,292,"call"],
+return y+"000"+H.d(z)},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Zl:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=100)return""+a
 if(a>=10)return"0"+a
-return"00"+a},"call$1",null,2,0,null,292,"call"],
+return"00"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 B5:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=10)return""+a
-return"0"+a},"call$1",null,2,0,null,292,"call"],
+return"0"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 a6:{
-"":"a;Fq<",
-g:[function(a,b){return P.k5(0,0,this.Fq+b.gFq(),0,0,0)},"call$1","gF1n",2,0,null,104],
-W:[function(a,b){return P.k5(0,0,this.Fq-b.gFq(),0,0,0)},"call$1","gTG",2,0,null,104],
+"^":"a;Fq<",
+g:[function(a,b){return P.k5(0,0,this.Fq+b.gFq(),0,0,0)},"call$1","gF1n",2,0,null,104,[]],
+W:[function(a,b){return P.k5(0,0,this.Fq-b.gFq(),0,0,0)},"call$1","gTG",2,0,null,104,[]],
 U:[function(a,b){if(typeof b!=="number")return H.s(b)
-return P.k5(0,0,C.CD.yu(C.CD.UD(this.Fq*b)),0,0,0)},"call$1","gEH",2,0,null,435],
+return P.k5(0,0,C.CD.yu(C.CD.UD(this.Fq*b)),0,0,0)},"call$1","gEH",2,0,null,430,[]],
 Z:[function(a,b){if(b===0)throw H.b(P.zl())
-return P.k5(0,0,C.jn.Z(this.Fq,b),0,0,0)},"call$1","gdG",2,0,null,436],
-C:[function(a,b){return this.Fq<b.gFq()},"call$1","gix",2,0,null,104],
-D:[function(a,b){return this.Fq>b.gFq()},"call$1","gh1",2,0,null,104],
-E:[function(a,b){return this.Fq<=b.gFq()},"call$1","gf5",2,0,null,104],
-F:[function(a,b){return this.Fq>=b.gFq()},"call$1","gNH",2,0,null,104],
+return P.k5(0,0,C.jn.Z(this.Fq,b),0,0,0)},"call$1","gdG",2,0,null,431,[]],
+C:[function(a,b){return this.Fq<b.gFq()},"call$1","gix",2,0,null,104,[]],
+D:[function(a,b){return this.Fq>b.gFq()},"call$1","gh1",2,0,null,104,[]],
+E:[function(a,b){return this.Fq<=b.gFq()},"call$1","gf5",2,0,null,104,[]],
+F:[function(a,b){return this.Fq>=b.gFq()},"call$1","gNH",2,0,null,104,[]],
 gVs:function(){return C.jn.cU(this.Fq,1000)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isa6)return!1
-return this.Fq===b.Fq},"call$1","gUJ",2,0,null,104],
+return this.Fq===b.Fq},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return this.Fq&0x1FFFFFFF},
-iM:[function(a,b){return C.jn.iM(this.Fq,b.gFq())},"call$1","gYc",2,0,null,104],
+iM:[function(a,b){return C.jn.iM(this.Fq,b.gFq())},"call$1","gYc",2,0,null,104,[]],
 bu:[function(a){var z,y,x,w,v
 z=new P.DW()
 y=this.Fq
@@ -15047,43 +15235,43 @@
 v=new P.P7().call$1(C.jn.JV(y,1000000))
 return""+C.jn.cU(y,3600000000)+":"+H.d(x)+":"+H.d(w)+"."+H.d(v)},"call$0","gXo",0,0,null],
 $isa6:true,
-static:{"":"Wt,S4d,dk,uU,RD,b2,q9,ll,Do,f4,vd,IJZ,iI,Vk,Nw,yn",k5:function(a,b,c,d,e,f){return new P.a6(a*86400000000+b*3600000000+e*60000000+f*1000000+d*1000+c)}}},
+static:{"^":"Wt,S4d,dk,uU,RD,b2,q9,ll,Do,f4,kTB,IJZ,iI,Vk,Nw,yn",k5:function(a,b,c,d,e,f){return new P.a6(a*86400000000+b*3600000000+e*60000000+f*1000000+d*1000+c)}}},
 P7:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=100000)return""+a
 if(a>=10000)return"0"+a
 if(a>=1000)return"00"+a
 if(a>=100)return"000"+a
 if(a>=10)return"0000"+a
-return"00000"+a},"call$1",null,2,0,null,292,"call"],
+return"00000"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 DW:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=10)return""+a
-return"0"+a},"call$1",null,2,0,null,292,"call"],
+return"0"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Ge:{
-"":"a;",
+"^":"a;",
 gI4:function(){return new H.XO(this.$thrownJsError,null)},
 $isGe:true},
 LK:{
-"":"Ge;",
+"^":"Ge;",
 bu:[function(a){return"Throw of null."},"call$0","gXo",0,0,null]},
 AT:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){var z=this.G1
 if(z!=null)return"Illegal argument(s): "+H.d(z)
 return"Illegal argument(s)"},"call$0","gXo",0,0,null],
 static:{u:function(a){return new P.AT(a)}}},
 bJ:{
-"":"AT;G1",
+"^":"AT;G1",
 bu:[function(a){return"RangeError: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{C3:function(a){return new P.bJ(a)},N:function(a){return new P.bJ("value "+H.d(a))},TE:function(a,b,c){return new P.bJ("value "+H.d(a)+" not in range "+H.d(b)+".."+H.d(c))}}},
 Np:{
-"":"Ge;",
+"^":"Ge;",
 static:{hS:function(){return new P.Np()}}},
 mp:{
-"":"Ge;uF,UP,mP,SA,mZ",
+"^":"Ge;uF,UP,mP,SA,mZ",
 bu:[function(a){var z,y,x,w,v,u,t
 z={}
 z.a=P.p9("")
@@ -15100,92 +15288,92 @@
 $ismp:true,
 static:{lr:function(a,b,c,d,e){return new P.mp(a,b,c,d,e)}}},
 ub:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"Unsupported operation: "+this.G1},"call$0","gXo",0,0,null],
 static:{f:function(a){return new P.ub(a)}}},
 ds:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){var z=this.G1
 return z!=null?"UnimplementedError: "+H.d(z):"UnimplementedError"},"call$0","gXo",0,0,null],
 $isGe:true,
 static:{SY:function(a){return new P.ds(a)}}},
 lj:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"Bad state: "+this.G1},"call$0","gXo",0,0,null],
 static:{w:function(a){return new P.lj(a)}}},
 UV:{
-"":"Ge;YA",
+"^":"Ge;YA",
 bu:[function(a){var z=this.YA
 if(z==null)return"Concurrent modification during iteration."
 return"Concurrent modification during iteration: "+H.d(P.hl(z))+"."},"call$0","gXo",0,0,null],
 static:{a4:function(a){return new P.UV(a)}}},
 VS:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"Stack Overflow"},"call$0","gXo",0,0,null],
 gI4:function(){return},
 $isGe:true},
 t7:{
-"":"Ge;Wo",
+"^":"Ge;Wo",
 bu:[function(a){return"Reading static variable '"+this.Wo+"' during its initialization"},"call$0","gXo",0,0,null],
 static:{Gz:function(a){return new P.t7(a)}}},
 HG:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){var z=this.G1
 if(z==null)return"Exception"
 return"Exception: "+H.d(z)},"call$0","gXo",0,0,null]},
 aE:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"FormatException: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{cD:function(a){return new P.aE(a)}}},
 eV:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"IntegerDivisionByZeroException"},"call$0","gXo",0,0,null],
 static:{zl:function(){return new P.eV()}}},
 kM:{
-"":"a;oc>",
+"^":"a;oc>",
 bu:[function(a){return"Expando:"+this.oc},"call$0","gXo",0,0,null],
 t:[function(a,b){var z=H.of(b,"expando$values")
-return z==null?null:H.of(z,this.Qz())},"call$1","gIA",2,0,null,6],
+return z==null?null:H.of(z,this.Qz())},"call$1","gIA",2,0,null,6,[]],
 u:[function(a,b,c){var z=H.of(b,"expando$values")
 if(z==null){z=new P.a()
-H.aw(b,"expando$values",z)}H.aw(z,this.Qz(),c)},"call$2","gj3",4,0,null,6,23],
+H.aw(b,"expando$values",z)}H.aw(z,this.Qz(),c)},"call$2","gj3",4,0,null,6,[],23,[]],
 Qz:[function(){var z,y
 z=H.of(this,"expando$key")
 if(z==null){y=$.Ss
 $.Ss=y+1
 z="expando$key$"+y
 H.aw(this,"expando$key",z)}return z},"call$0","gwT",0,0,null],
-static:{"":"Xa,rly,Ss"}},
+static:{"^":"bZ,rly,Ss"}},
 EH:{
-"":"a;",
+"^":"a;",
 $isEH:true},
 cX:{
-"":"a;",
+"^":"a;",
 $iscX:true,
 $ascX:null},
 Yl:{
-"":"a;"},
+"^":"a;"},
 Z0:{
-"":"a;",
+"^":"a;",
 $isZ0:true},
 L9:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"null"},"call$0","gXo",0,0,null]},
 a:{
-"":";",
-n:[function(a,b){return this===b},"call$1","gUJ",2,0,null,104],
+"^":";",
+n:[function(a,b){return this===b},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return H.eQ(this)},
 bu:[function(a){return H.a5(this)},"call$0","gXo",0,0,null],
-T:[function(a,b){throw H.b(P.lr(this,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,332],
+T:[function(a,b){throw H.b(P.lr(this,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,326,[]],
 gbx:function(a){return new H.cu(H.dJ(this),null)},
 $isa:true},
 Od:{
-"":"a;",
+"^":"a;",
 $isOd:true},
 MN:{
-"":"a;"},
+"^":"a;"},
 WU:{
-"":"a;Qk,SU,Oq,Wn",
+"^":"a;Qk,SU,Oq,Wn",
 gl:function(){return this.Wn},
 G:[function(){var z,y,x,w,v,u
 z=this.Oq
@@ -15203,14 +15391,14 @@
 this.Wn=65536+((w&1023)<<10>>>0)+(u&1023)
 return!0}}this.Oq=v
 this.Wn=w
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 Rn:{
-"":"a;vM<",
+"^":"a;vM<",
 gB:function(a){return this.vM.length},
 gl0:function(a){return this.vM.length===0},
 gor:function(a){return this.vM.length!==0},
 KF:[function(a){var z=typeof a==="string"?a:H.d(a)
-this.vM=this.vM+z},"call$1","gMG",2,0,null,93],
+this.vM=this.vM+z},"call$1","gMG",2,0,null,93,[]],
 We:[function(a,b){var z,y
 z=J.GP(a)
 if(!z.G())return
@@ -15221,7 +15409,7 @@
 for(;z.G();){this.vM=this.vM+b
 y=z.gl()
 y=typeof y==="string"?y:H.d(y)
-this.vM=this.vM+y}}},"call$2","gS9",2,2,null,334,419,335],
+this.vM=this.vM+y}}},"call$2","gS9",2,2,null,328,415,[],329,[]],
 V1:[function(a){this.vM=""},"call$0","gyP",0,0,null],
 bu:[function(a){return this.vM},"call$0","gXo",0,0,null],
 PD:function(a){if(typeof a==="string")this.vM=a
@@ -15230,13 +15418,17 @@
 z.PD(a)
 return z}}},
 wv:{
-"":"a;",
+"^":"a;",
 $iswv:true},
 uq:{
-"":"a;",
+"^":"a;",
 $isuq:true},
 iD:{
-"":"a;NN,HC,r0,Fi,iV,tP,Ka,ld,yW",
+"^":"a;NN,HC,r0,Fi,ku,tP,Ka,YG,yW",
+gWu:function(){if(J.de(this.gJf(this),""))return""
+var z=P.p9("")
+this.tb(z)
+return z.vM},
 gJf:function(a){var z,y
 z=this.NN
 if(z!=null&&J.co(z,"[")){y=J.U6(z)
@@ -15247,15 +15439,6 @@
 if(y.n(z,"http"))return 80
 if(y.n(z,"https"))return 443}return this.HC},
 Ja:function(a,b){return this.tP.call$1(b)},
-gFj:function(){var z,y
-z=this.ld
-if(z==null){z=J.FN(this.r0)!==!0&&J.lE(this.r0,0)===47
-y=this.r0
-if(z)y=J.ZZ(y,1)
-z=J.x(y)
-z=z.n(y,"")?C.Fv:H.VM(new H.A8(z.Fr(y,"/"),P.t9()),[null,null]).tt(0,!1)
-z=H.VM(new P.Yp(z),[null])
-this.ld=z}return z},
 x6:[function(a,b){var z,y
 z=a==null
 if(z&&!0)return""
@@ -15264,17 +15447,17 @@
 if(!J.de(this.gJf(this),"")||J.de(this.Fi,"file")){z=J.U6(y)
 z=z.gor(y)&&!z.nC(y,"/")}else z=!1
 if(z)return"/"+H.d(y)
-return y},"call$2","gbQ",4,0,null,266,437],
+return y},"call$2","gbQ",4,0,null,260,[],432,[]],
 Ky:[function(a,b){var z=J.x(a)
 if(z.n(a,""))return"/"+H.d(b)
-return z.Nj(a,0,J.WB(z.cn(a,"/"),1))+H.d(b)},"call$2","gAj",4,0,null,438,439],
+return z.Nj(a,0,J.WB(z.cn(a,"/"),1))+H.d(b)},"call$2","gAj",4,0,null,433,[],434,[]],
 uo:[function(a){var z=J.U6(a)
 if(J.z8(z.gB(a),0)&&z.j(a,0)===58)return!0
-return z.u8(a,"/.")!==-1},"call$1","gaO",2,0,null,266],
+return z.u8(a,"/.")!==-1},"call$1","gaO",2,0,null,260,[]],
 SK:[function(a){var z,y,x,w,v
 if(!this.uo(a))return a
 z=[]
-for(y=J.Gn(a,"/"),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=!1;y.G();){w=y.lo
+for(y=J.uH(a,"/"),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=!1;y.G();){w=y.lo
 if(J.de(w,"..")){v=z.length
 if(v!==0)if(v===1){if(0>=v)return H.e(z,0)
 v=!J.de(z[0],"")}else v=!0
@@ -15283,53 +15466,19 @@
 z.pop()}x=!0}else if("."===w)x=!0
 else{z.push(w)
 x=!1}}if(x)z.push("")
-return C.Nm.zV(z,"/")},"call$1","ghK",2,0,null,266],
-mS:[function(a){var z,y,x,w,v,u,t,s
-z=a.Fi
-if(!J.de(z,"")){y=a.iV
-x=a.gJf(a)
-w=a.gtp(a)
-v=this.SK(a.r0)
-u=a.tP}else{if(!J.de(a.gJf(a),"")){y=a.iV
-x=a.gJf(a)
-w=a.gtp(a)
-v=this.SK(a.r0)
-u=a.tP}else{if(J.de(a.r0,"")){v=this.r0
-u=a.tP
-u=!J.de(u,"")?u:this.tP}else{t=J.co(a.r0,"/")
-s=a.r0
-v=t?this.SK(s):this.SK(this.Ky(this.r0,s))
-u=a.tP}y=this.iV
-x=this.gJf(this)
-w=this.gtp(this)}z=this.Fi}return P.R6(a.Ka,x,v,null,w,u,null,z,y)},"call$1","gUw",2,0,null,439],
-Dm:[function(a){var z,y,x
-z=this.Fi
-y=J.x(z)
-if(!y.n(z,"")&&!y.n(z,"file"))throw H.b(P.f("Cannot extract a file path from a "+H.d(z)+" URI"))
-if(!y.n(z,"")&&!y.n(z,"file"))throw H.b(P.f("Cannot extract a file path from a "+H.d(z)+" URI"))
-if(!J.de(this.tP,""))throw H.b(P.f("Cannot extract a file path from a URI with a query component"))
-if(!J.de(this.Ka,""))throw H.b(P.f("Cannot extract a file path from a URI with a fragment component"))
-if(!J.de(this.gJf(this),""))H.vh(P.f("Cannot extract a non-Windows file path from a file URI with an authority"))
-P.i8(this.gFj(),!1)
-x=P.p9("")
-if(this.grj())x.KF("/")
-x.We(this.gFj(),"/")
-z=x.vM
-return z},function(){return this.Dm(null)},"t4","call$1$windows",null,"gK1",0,3,null,77,440],
-grj:function(){var z=this.r0
-if(z==null||J.FN(z)===!0)return!1
-return J.co(this.r0,"/")},
+return C.Nm.zV(z,"/")},"call$1","ghK",2,0,null,260,[]],
+tb:[function(a){var z=this.ku
+if(""!==z){a.KF(z)
+a.KF("@")}z=this.NN
+a.KF(z==null?"null":z)
+if(!J.de(this.HC,0)){a.KF(":")
+a.KF(J.AG(this.HC))}},"call$1","gyL",2,0,null,435,[]],
 bu:[function(a){var z,y
 z=P.p9("")
 y=this.Fi
 if(""!==y){z.KF(y)
 z.KF(":")}if(!J.de(this.gJf(this),"")||J.de(y,"file")){z.KF("//")
-y=this.iV
-if(""!==y){z.KF(y)
-z.KF("@")}y=this.NN
-z.KF(y==null?"null":y)
-if(!J.de(this.HC,0)){z.KF(":")
-z.KF(J.AG(this.HC))}}z.KF(this.r0)
+this.tb(z)}z.KF(this.r0)
 y=this.tP
 if(""!==y){z.KF("?")
 z.KF(y)}y=this.Ka
@@ -15339,16 +15488,16 @@
 if(b==null)return!1
 z=J.RE(b)
 if(typeof b!=="object"||b===null||!z.$isiD)return!1
-return J.de(this.Fi,b.Fi)&&J.de(this.iV,b.iV)&&J.de(this.gJf(this),z.gJf(b))&&J.de(this.gtp(this),z.gtp(b))&&J.de(this.r0,b.r0)&&J.de(this.tP,b.tP)&&J.de(this.Ka,b.Ka)},"call$1","gUJ",2,0,null,104],
+return J.de(this.Fi,b.Fi)&&J.de(this.ku,b.ku)&&J.de(this.gJf(this),z.gJf(b))&&J.de(this.gtp(this),z.gtp(b))&&J.de(this.r0,b.r0)&&J.de(this.tP,b.tP)&&J.de(this.Ka,b.Ka)},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z=new P.XZ()
-return z.call$2(this.Fi,z.call$2(this.iV,z.call$2(this.gJf(this),z.call$2(this.gtp(this),z.call$2(this.r0,z.call$2(this.tP,z.call$2(this.Ka,1)))))))},
+return z.call$2(this.Fi,z.call$2(this.ku,z.call$2(this.gJf(this),z.call$2(this.gtp(this),z.call$2(this.r0,z.call$2(this.tP,z.call$2(this.Ka,1)))))))},
 n3:function(a,b,c,d,e,f,g,h,i){var z=J.x(h)
 if(z.n(h,"http")&&J.de(e,80))this.HC=0
 else if(z.n(h,"https")&&J.de(e,443))this.HC=0
 else this.HC=e
 this.r0=this.x6(c,d)},
 $isiD:true,
-static:{"":"Um,B4,Bx,iR,ti,mv,nR,we,jR,Qq,O2w,ux,vI,SF,Nv,IL,Q5,zk,om,pk,O5,eq,qf,ML,y3,Pk,R1,oe,lL,I9,t2,H5,zst,eK,bf,Sp,nU,uj,Ai,ne",r6:function(a){var z,y,x,w,v,u,t,s
+static:{"^":"Um,KU,Bx,iR,ti,My,nR,jJY,d2,Qq,q7,ux,vI,SF,fd,IL,Q5,zk,om,fC,O5,eq,qf,ML,y3,Pk,R1,qs,lL,I9,t2,H5,wb,eK,ws,Sp,jH,Qd,Ai,ne",r6:function(a){var z,y,x,w,v,u,t,s
 z=a.QK
 if(1>=z.length)return H.e(z,1)
 y=z[1]
@@ -15379,9 +15528,7 @@
 return u},R6:function(a,b,c,d,e,f,g,h,i){var z=P.iy(h)
 z=new P.iD(P.L7(b),null,null,z,i,P.LE(f,g),P.UJ(a),null,null)
 z.n3(a,b,c,d,e,f,g,h,i)
-return z},uo:function(){var z=H.mz()
-if(z!=null)return P.r6($.cO().ej(z))
-throw H.b(P.f("'Uri.base' is not supported"))},i8:[function(a,b){a.aN(a,new P.In(b))},"call$2","Lq",4,0,null,195,196],L7:[function(a){var z,y,x
+return z},L7:[function(a){var z,y,x
 if(a==null||J.FN(a)===!0)return a
 z=J.rY(a)
 if(z.j(a,0)===91){if(z.j(a,J.xH(z.gB(a),1))!==93)throw H.b(P.cD("Missing end `]` to match `[` in host"))
@@ -15391,7 +15538,7 @@
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
 if(z.j(a,y)===58){P.eg(a)
-return"["+H.d(a)+"]"}++y}return a},"call$1","jC",2,0,null,197],iy:[function(a){var z,y,x,w,v,u,t,s
+return"["+H.d(a)+"]"}++y}return a},"call$1","jC",2,0,null,195,[]],iy:[function(a){var z,y,x,w,v,u,t,s
 z=new P.hb()
 y=new P.XX()
 if(a==null)return""
@@ -15406,7 +15553,7 @@
 s=!s}else s=!1
 if(s)throw H.b(new P.AT("Illegal scheme: "+H.d(a)))
 if(z.call$1(t)!==!0){if(y.call$1(t)===!0);else throw H.b(new P.AT("Illegal scheme: "+H.d(a)))
-v=!1}}return v?a:x.hc(a)},"call$1","oL",2,0,null,198],LE:[function(a,b){var z,y,x
+v=!1}}return v?a:x.hc(a)},"call$1","oL",2,0,null,196,[]],LE:[function(a,b){var z,y,x
 z={}
 y=a==null
 if(y&&!0)return""
@@ -15415,8 +15562,8 @@
 x=P.p9("")
 z.a=!0
 C.jN.aN(b,new P.yZ(z,x))
-return x.vM},"call$2","wF",4,0,null,199,200],UJ:[function(a){if(a==null)return""
-return P.Xc(a)},"call$1","p7",2,0,null,201],Xc:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+return x.vM},"call$2","wF",4,0,null,197,[],198,[]],UJ:[function(a){if(a==null)return""
+return P.Xc(a)},"call$1","p7",2,0,null,199,[]],Xc:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z={}
 y=new P.Gs()
 x=new P.Tw()
@@ -15463,14 +15610,14 @@
 r=n}if(z.a!=null&&z.c!==r)s.call$0()
 z=z.a
 if(z==null)return a
-return J.AG(z)},"call$1","ZX",2,0,null,202],n7:[function(a){if(a!=null&&!J.de(a,""))return H.BU(a,null,null)
-else return 0},"call$1","dl",2,0,null,203],K6:[function(a,b){if(a!=null)return a
+return J.AG(z)},"call$1","Sy",2,0,null,200,[]],n7:[function(a){if(a!=null&&!J.de(a,""))return H.BU(a,null,null)
+else return 0},"call$1","dl",2,0,null,201,[]],K6:[function(a,b){if(a!=null)return a
 if(b!=null)return b
-return""},"call$2","xX",4,0,null,204,205],Mt:[function(a){return P.pE(a,C.xM,!1)},"call$1","t9",2,0,206,207],q5:[function(a){var z,y
+return""},"call$2","xX",4,0,null,202,[],203,[]],q5:[function(a){var z,y
 z=new P.Mx()
 y=a.split(".")
 if(y.length!==4)z.call$1("IPv4 address should contain exactly 4 parts")
-return H.VM(new H.A8(y,new P.C9(z)),[null,null]).br(0)},"call$1","cf",2,0,null,197],eg:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
+return H.VM(new H.A8(y,new P.C9(z)),[null,null]).br(0)},"call$1","cf",2,0,null,195,[]],eg:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
 z=new P.kZ()
 y=new P.JT(a,z)
 if(J.u6(J.q8(a),2))z.call$1("address is too short")
@@ -15503,7 +15650,7 @@
 z.call$1("invalid end of IPv6 address.")}}if(u){if(J.q8(x)>7)z.call$1("an address with a wildcard must have less than 7 parts")}else if(J.q8(x)!==8)z.call$1("an address without a wildcard must contain exactly 8 parts")
 s=new H.kV(x,new P.d9(x))
 s.$builtinTypeInfo=[null,null]
-return P.F(s,!0,H.ip(s,"mW",0))},"call$1","kS",2,0,null,197],jW:[function(a,b,c,d){var z,y,x,w,v,u,t,s
+return P.F(s,!0,H.ip(s,"mW",0))},"call$1","y9",2,0,null,195,[]],jW:[function(a,b,c,d){var z,y,x,w,v,u,t,s
 z=new P.rI()
 y=P.p9("")
 x=c.gZE().WJ(b)
@@ -15519,62 +15666,29 @@
 y.vM=y.vM+u}else{s=P.O8(1,37,J.im)
 u=H.eT(s)
 y.vM=y.vM+u
-z.call$2(v,y)}}return y.vM},"call$4$encoding$spaceToPlus","jd",4,5,null,208,209,210,211,212,213],oh:[function(a,b){var z,y,x,w
-for(z=J.rY(a),y=0,x=0;x<2;++x){w=z.j(a,b+x)
-if(48<=w&&w<=57)y=y*16+w-48
-else{w|=32
-if(97<=w&&w<=102)y=y*16+w-87
-else throw H.b(new P.AT("Invalid URL encoding"))}}return y},"call$2","Mm",4,0,null,86,214],pE:[function(a,b,c){var z,y,x,w,v,u,t
-z=J.U6(a)
-y=!0
-x=0
-while(!0){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(!(x<w&&y))break
-v=z.j(a,x)
-y=v!==37&&v!==43;++x}if(y)if(b===C.xM||!1)return a
-else u=z.gZm(a)
-else{u=[]
-x=0
-while(!0){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(!(x<w))break
-v=z.j(a,x)
-if(v>127)throw H.b(new P.AT("Illegal percent encoding in URI"))
-if(v===37){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(x+3>w)throw H.b(new P.AT("Truncated URI"))
-u.push(P.oh(a,x+1))
-x+=2}else if(c&&v===43)u.push(32)
-else u.push(v);++x}}t=b.lH
-return new P.GY(t).WJ(u)},"call$3$encoding$plusToSpace","Ci",2,5,null,208,209,211,212,215]}},
-In:{
-"":"Tp:229;a",
-call$1:[function(a){if(J.kE(a,"/")===!0)if(this.a)throw H.b(new P.AT("Illegal path character "+H.d(a)))
-else throw H.b(P.f("Illegal path character "+H.d(a)))},"call$1",null,2,0,null,441,"call"],
-$isEH:true},
+z.call$2(v,y)}}return y.vM},"call$4$encoding$spaceToPlus","jd",4,5,null,204,205,206,[],207,[],208,[],209,[]]}},
 hb:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=a>>>4
 if(z>=8)return H.e(C.HE,z)
 z=(C.HE[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 XX:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=a>>>4
 if(z>=8)return H.e(C.mK,z)
 z=(C.mK[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 Kd:{
-"":"Tp:229;",
-call$1:[function(a){return P.jW(C.Wd,a,C.xM,!1)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return P.jW(C.Wd,a,C.xM,!1)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 yZ:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.a
 if(!z.a)this.b.KF("&")
 z.a=!1
@@ -15582,47 +15696,47 @@
 z.KF(P.jW(C.kg,a,C.xM,!0))
 b.gl0(b)
 z.KF("=")
-z.KF(P.jW(C.kg,b,C.xM,!0))},"call$2",null,4,0,null,42,23,"call"],
+z.KF(P.jW(C.kg,b,C.xM,!0))},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 Gs:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(!(48<=a&&a<=57))z=65<=a&&a<=70
 else z=!0
-return z},"call$1",null,2,0,null,444,"call"],
+return z},"call$1",null,2,0,null,438,[],"call"],
 $isEH:true},
 pm:{
-"":"Tp:443;",
-call$1:[function(a){return 97<=a&&a<=102},"call$1",null,2,0,null,444,"call"],
+"^":"Tp:437;",
+call$1:[function(a){return 97<=a&&a<=102},"call$1",null,2,0,null,438,[],"call"],
 $isEH:true},
 Tw:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=C.jn.GG(a,4)
 if(z>=8)return H.e(C.kg,z)
 z=(C.kg[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 wm:{
-"":"Tp:445;b,c,d",
+"^":"Tp:439;b,c,d",
 call$1:[function(a){var z,y
 z=this.b
 y=J.lE(z,a)
 if(this.d.call$1(y)===!0)return y-32
 else if(this.c.call$1(y)!==!0)throw H.b(new P.AT("Invalid URI component: "+H.d(z)))
-else return y},"call$1",null,2,0,null,47,"call"],
+else return y},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 FB:{
-"":"Tp:445;e",
+"^":"Tp:439;e",
 call$1:[function(a){var z,y,x,w,v
 for(z=this.e,y=J.rY(z),x=0,w=0;w<2;++w){v=y.j(z,a+w)
 if(48<=v&&v<=57)x=x*16+v-48
 else{v|=32
 if(97<=v&&v<=102)x=x*16+v-97+10
-else throw H.b(new P.AT("Invalid percent-encoding in URI component: "+H.d(z)))}}return x},"call$1",null,2,0,null,47,"call"],
+else throw H.b(new P.AT("Invalid percent-encoding in URI component: "+H.d(z)))}}return x},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 Lk:{
-"":"Tp:107;a,f",
+"^":"Tp:107;a,f",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 y=z.a
@@ -15633,52 +15747,54 @@
 else y.KF(J.Nj(w,x,v))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 XZ:{
-"":"Tp:447;",
-call$2:[function(a,b){return b*31+J.v1(a)&1073741823},"call$2",null,4,0,null,446,245,"call"],
+"^":"Tp:441;",
+call$2:[function(a,b){var z=J.v1(a)
+if(typeof z!=="number")return H.s(z)
+return b*31+z&1073741823},"call$2",null,4,0,null,440,[],240,[],"call"],
 $isEH:true},
 Mx:{
-"":"Tp:174;",
-call$1:[function(a){throw H.b(P.cD("Illegal IPv4 address, "+a))},"call$1",null,2,0,null,19,"call"],
+"^":"Tp:174;",
+call$1:[function(a){throw H.b(P.cD("Illegal IPv4 address, "+a))},"call$1",null,2,0,null,19,[],"call"],
 $isEH:true},
 C9:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y
 z=H.BU(a,null,null)
 y=J.Wx(z)
 if(y.C(z,0)||y.D(z,255))this.a.call$1("each part must be in the range of `0..255`")
-return z},"call$1",null,2,0,null,448,"call"],
+return z},"call$1",null,2,0,null,442,[],"call"],
 $isEH:true},
 kZ:{
-"":"Tp:174;",
-call$1:[function(a){throw H.b(P.cD("Illegal IPv6 address, "+a))},"call$1",null,2,0,null,19,"call"],
+"^":"Tp:174;",
+call$1:[function(a){throw H.b(P.cD("Illegal IPv6 address, "+a))},"call$1",null,2,0,null,19,[],"call"],
 $isEH:true},
 JT:{
-"":"Tp:449;a,b",
+"^":"Tp:443;a,b",
 call$2:[function(a,b){var z,y
 if(J.z8(J.xH(b,a),4))this.b.call$1("an IPv6 part can only contain a maximum of 4 hex digits")
 z=H.BU(J.Nj(this.a,a,b),16,null)
 y=J.Wx(z)
 if(y.C(z,0)||y.D(z,65535))this.b.call$1("each part must be in the range of `0x0..0xFFFF`")
-return z},"call$2",null,4,0,null,115,116,"call"],
+return z},"call$2",null,4,0,null,115,[],116,[],"call"],
 $isEH:true},
 d9:{
-"":"Tp:229;c",
+"^":"Tp:223;c",
 call$1:[function(a){var z=J.x(a)
 if(z.n(a,-1))return P.O8((9-this.c.length)*2,0,null)
-else return[z.m(a,8)&255,z.i(a,255)]},"call$1",null,2,0,null,23,"call"],
+else return[z.m(a,8)&255,z.i(a,255)]},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 rI:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){var z=J.Wx(a)
 b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.m(a,4))))
-b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.i(a,15))))},"call$2",null,4,0,null,450,451,"call"],
+b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.i(a,15))))},"call$2",null,4,0,null,444,[],445,[],"call"],
 $isEH:true}}],["dart.dom.html","dart:html",,W,{
-"":"",
+"^":"",
 UE:[function(a){if(P.F7()===!0)return"webkitTransitionEnd"
 else if(P.dg()===!0)return"oTransitionEnd"
-return"transitionend"},"call$1","pq",2,0,216,18],
-r3:[function(a,b){return document.createElement(a)},"call$2","Oe",4,0,null,94,217],
-It:[function(a,b,c){return W.lt(a,null,null,b,null,null,null,c).ml(new W.Kx())},"call$3$onProgress$withCredentials","xF",2,5,null,77,77,218,219,220],
+return"transitionend"},"call$1","pq",2,0,210,18,[]],
+r3:[function(a,b){return document.createElement(a)},"call$2","Oe",4,0,null,94,[],211,[]],
+It:[function(a,b,c){return W.lt(a,null,null,b,null,null,null,c).ml(new W.Kx())},"call$3$onProgress$withCredentials","xF",2,5,null,77,77,212,[],213,[],214,[]],
 lt:[function(a,b,c,d,e,f,g,h){var z,y,x
 z=W.zU
 y=H.VM(new P.Zf(P.Dt(z)),[z])
@@ -15689,33 +15805,33 @@
 z=C.MD.aM(x)
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(y.gYJ()),z.Sg),[H.Kp(z,0)]).Zz()
 x.send()
-return y.MM},"call$8$method$mimeType$onProgress$requestHeaders$responseType$sendData$withCredentials","Za",2,15,null,77,77,77,77,77,77,77,218,221,222,219,223,224,225,220],
+return y.MM},"call$8$method$mimeType$onProgress$requestHeaders$responseType$sendData$withCredentials","Za",2,15,null,77,77,77,77,77,77,77,212,[],215,[],216,[],213,[],217,[],218,[],219,[],214,[]],
 ED:function(a){var z,y
 z=document.createElement("input",null)
-if(a!=null)try{J.cW(z,a)}catch(y){H.Ru(y)}return z},
+if(a!=null)try{J.Lp(z,a)}catch(y){H.Ru(y)}return z},
 uC:[function(a){var z,y,x
 try{z=a
 y=J.x(z)
 return typeof z==="object"&&z!==null&&!!y.$iscS}catch(x){H.Ru(x)
-return!1}},"call$1","e8",2,0,null,226],
+return!1}},"call$1","iJ",2,0,null,220,[]],
 Pv:[function(a){if(a==null)return
-return W.P1(a)},"call$1","Ie",2,0,null,227],
+return W.P1(a)},"call$1","Ie",2,0,null,221,[]],
 qc:[function(a){var z,y
 if(a==null)return
 if("setInterval" in a){z=W.P1(a)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isD0)return z
-return}else return a},"call$1","Wq",2,0,null,18],
-qr:[function(a){return a},"call$1","Ku",2,0,null,18],
-YT:[function(a,b){return new W.vZ(a,b)},"call$2","AD",4,0,null,228,7],
-GO:[function(a){return J.TD(a)},"call$1","V5",2,0,229,41],
-Yb:[function(a){return J.Vq(a)},"call$1","cn",2,0,229,41],
-Qp:[function(a,b,c,d){return J.qd(a,b,c,d)},"call$4","A6",8,0,230,41,12,231,232],
+return}else return a},"call$1","Wq",2,0,null,18,[]],
+qr:[function(a){return a},"call$1","Ku",2,0,null,18,[]],
+YT:[function(a,b){return new W.vZ(a,b)},"call$2","AD",4,0,null,222,[],7,[]],
+GO:[function(a){return J.TD(a)},"call$1","V5",2,0,223,41,[]],
+Yb:[function(a){return J.Vq(a)},"call$1","cn",2,0,223,41,[]],
+Qp:[function(a,b,c,d){return J.qd(a,b,c,d)},"call$4","A6",8,0,224,41,[],12,[],225,[],226,[]],
 wi:[function(a,b,c,d,e){var z,y,x,w,v,u,t,s,r,q
-z=J.Fb(d)
+z=J.Xr(d)
 if(z==null)throw H.b(new P.AT(d))
 y=z.prototype
-x=J.Dp(d,"created")
+x=J.Nq(d,"created")
 if(x==null)throw H.b(new P.AT(H.d(d)+" has no constructor called 'created'"))
 J.ks(W.r3("article",null))
 w=z.$nativeSuperclassTag
@@ -15729,12 +15845,12 @@
                return invokeCallback(this);
              };
           })(H.tR(W.YT(x,y),1)))}
-t.enteredViewCallback={value: ((function(invokeCallback) {
+t.attachedCallback={value: ((function(invokeCallback) {
              return function() {
                return invokeCallback(this);
              };
           })(H.tR(W.V5(),1)))}
-t.leftViewCallback={value: ((function(invokeCallback) {
+t.detachedCallback={value: ((function(invokeCallback) {
              return function() {
                return invokeCallback(this);
              };
@@ -15749,16 +15865,17 @@
 Object.defineProperty(s, init.dispatchPropertyName, {value: r, enumerable: false, writable: true, configurable: true})
 q={prototype: s}
 if(!v)q.extends=e
-b.register(c,q)},"call$5","uz",10,0,null,89,233,94,11,234],
+b.registerElement(c,q)},"call$5","uz",10,0,null,89,[],227,[],94,[],11,[],228,[]],
 aF:[function(a){if(J.de($.X3,C.NU))return a
-return $.X3.oj(a,!0)},"call$1","Rj",2,0,null,150],
-Iq:[function(a){if(J.de($.X3,C.NU))return a
-return $.X3.PT(a,!0)},"call$1","eE",2,0,null,150],
+if(a==null)return
+return $.X3.oj(a,!0)},"call$1","Rj",2,0,null,148,[]],
+K2:[function(a){if(J.de($.X3,C.NU))return a
+return $.X3.PT(a,!0)},"call$1","dB",2,0,null,148,[]],
 qE:{
-"":"cv;",
-"%":"HTMLAppletElement|HTMLBRElement|HTMLBaseFontElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLHRElement|HTMLHeadElement|HTMLHeadingElement|HTMLHtmlElement|HTMLMarqueeElement|HTMLMenuElement|HTMLModElement|HTMLOptGroupElement|HTMLParagraphElement|HTMLPreElement|HTMLQuoteElement|HTMLShadowElement|HTMLSpanElement|HTMLTableCaptionElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableDataCellElement|HTMLTableElement|HTMLTableHeaderCellElement|HTMLTableRowElement|HTMLTableSectionElement|HTMLTitleElement|HTMLUListElement|HTMLUnknownElement;HTMLElement;Sa|Ao|ir|LP|uL|Vf|G6|Ds|xI|kf|pv|Ps|CN|Vfx|vc|Dsd|i6|tuj|FvP|Vct|Ir|m8|D13|jM|DKl|WZq|mk|pva|NM|pR|cda|hx|u7|waa|E7|V0|St|V4|vj|LU|V6|CX|PF|qT|V10|Xd|V11|F1|XP|NQ|knI|V12|fI|V13|nm|V14|Vu"},
+"^":"cv;",
+"%":"HTMLAppletElement|HTMLBRElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLHRElement|HTMLHeadElement|HTMLHeadingElement|HTMLHtmlElement|HTMLMarqueeElement|HTMLMenuElement|HTMLModElement|HTMLOptGroupElement|HTMLParagraphElement|HTMLPreElement|HTMLQuoteElement|HTMLShadowElement|HTMLSpanElement|HTMLTableCaptionElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableDataCellElement|HTMLTableHeaderCellElement|HTMLTitleElement|HTMLUListElement|HTMLUnknownElement;HTMLElement;jpR|GN|ir|LP|uL|Vf|G6|Ds|xI|Tg|pv|Ps|CN|Vfx|vc|Dsd|i6|tuj|Fv|Vct|E9|m8|D13|Gk|GG|WZq|yb|pva|NM|T5|pR|cda|hx|u7|waa|E7|V0|St|V4|vj|LU|V10|T2|PF|qT|V11|Xd|V12|F1|XP|JG|qe|knI|V13|fI|V14|nm|V15|Vu"},
 SV:{
-"":"Gv;",
+"^":"Gv;",
 $isList:true,
 $asWO:function(){return[W.M5]},
 $isyN:true,
@@ -15766,90 +15883,87 @@
 $ascX:function(){return[W.M5]},
 "%":"EntryArray"},
 Gh:{
-"":"qE;N:target=,t5:type%,cC:hash%,mH:href=",
+"^":"qE;N:target=,t5:type%,cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $isGv:true,
 "%":"HTMLAnchorElement"},
-fY:{
-"":"qE;N:target=,cC:hash%,mH:href=",
+na:{
+"^":"qE;N:target=,cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $isGv:true,
 "%":"HTMLAreaElement"},
 Xk:{
-"":"qE;mH:href=,N:target=",
+"^":"qE;mH:href=,N:target=",
 "%":"HTMLBaseElement"},
 W2:{
-"":"ea;O3:url=",
+"^":"ea;O3:url=",
 "%":"BeforeLoadEvent"},
 Az:{
-"":"Gv;t5:type=",
+"^":"Gv;t5:type=",
 $isAz:true,
 "%":";Blob"},
 QP:{
-"":"qE;",
+"^":"qE;",
 $isD0:true,
 $isGv:true,
 "%":"HTMLBodyElement"},
 QW:{
-"":"qE;MB:form=,oc:name%,t5:type%,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,t5:type%,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLButtonElement"},
-OM:{
-"":"uH;Rn:data=,B:length=",
+nx:{
+"^":"KV;Rn:data=,B:length=",
 $isGv:true,
 "%":"Comment;CharacterData"},
 QQ:{
-"":"ea;tT:code=",
+"^":"ea;tT:code=",
 "%":"CloseEvent"},
-wT:{
-"":"Mf;Rn:data=",
+di:{
+"^":"Mf;Rn:data=",
 "%":"CompositionEvent"},
-oJ:{
-"":"BV;B:length=",
-T2:[function(a,b){var z=a.getPropertyValue(b)
-return z!=null?z:""},"call$1","gVw",2,0,null,63],
-"%":"CSS2Properties|CSSStyleDeclaration|MSStyleCSSProperties"},
-DG:{
-"":"ea;",
+He:{
+"^":"ea;",
 gey:function(a){var z=a._dartDetail
 if(z!=null)return z
 return P.o7(a.detail,!0)},
-$isDG:true,
+$isHe:true,
 "%":"CustomEvent"},
-bY:{
-"":"qE;bG:options=",
+vHT:{
+"^":"qE;bG:options=",
 "%":"HTMLDataListElement"},
 QF:{
-"":"uH;",
+"^":"KV;",
 JP:[function(a){return a.createDocumentFragment()},"call$0","gf8",0,0,null],
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
-ek:[function(a,b,c){return a.importNode(b,c)},"call$2","gPp",2,2,null,77,294,295],
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
+ek:[function(a,b,c){return a.importNode(b,c)},"call$2","gPp",2,2,null,77,259,[],289,[]],
 gi9:function(a){return C.mt.aM(a)},
-gVl:function(a){return C.T1.aM(a)},
+gVl:function(a){return C.pi.aM(a)},
 gLm:function(a){return C.i3.aM(a)},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 $isQF:true,
 "%":"Document|HTMLDocument|SVGDocument"},
-hN:{
-"":"uH;",
-gwd:function(a){if(a._children==null)a._children=H.VM(new P.D7(a,new W.e7(a)),[null])
-return a._children},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+Aj:{
+"^":"KV;",
+gwd:function(a){if(a._docChildren==null)a._docChildren=H.VM(new P.D7(a,new W.e7(a)),[null])
+return a._docChildren},
+swd:function(a,b){var z,y,x
+z=P.F(b,!0,null)
+y=this.gwd(a)
+x=J.w1(y)
+x.V1(y)
+x.FV(y,z)},
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 $isGv:true,
 "%":";DocumentFragment"},
-SL:{
-"":"uH;",
-$isGv:true,
-"%":"DocumentType"},
-rv:{
-"":"Gv;G1:message=,oc:name=",
+cm:{
+"^":"Gv;G1:message=,oc:name=",
 "%":";DOMError"},
 Nh:{
-"":"Gv;G1:message=",
+"^":"Gv;G1:message=",
 goc:function(a){var z=a.name
 if(P.F7()===!0&&z==="SECURITY_ERR")return"SecurityError"
 if(P.F7()===!0&&z==="SYNTAX_ERR")return"SyntaxError"
@@ -15858,16 +15972,21 @@
 $isNh:true,
 "%":"DOMException"},
 cv:{
-"":"uH;xr:className%,jO:id%",
+"^":"KV;xr:className%,jO:id%",
 gQg:function(a){return new W.i7(a)},
 gwd:function(a){return new W.VG(a,a.children)},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+swd:function(a,b){var z,y
+z=P.F(b,!0,null)
+y=this.gwd(a)
+y.V1(0)
+y.FV(0,z)},
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 gDD:function(a){return new W.I4(a)},
 i4:[function(a){},"call$0","gQd",0,0,null],
 xo:[function(a){},"call$0","gbt",0,0,null],
-aC:[function(a,b,c,d){},"call$3","gxR",6,0,null,12,231,232],
+aC:[function(a,b,c,d){},"call$3","gxR",6,0,null,12,[],225,[],226,[]],
 gqn:function(a){return a.localName},
 bu:[function(a){return a.localName},"call$0","gXo",0,0,null],
 WO:[function(a,b){if(!!a.matches)return a.matches(b)
@@ -15875,16 +15994,16 @@
 else if(!!a.mozMatchesSelector)return a.mozMatchesSelector(b)
 else if(!!a.msMatchesSelector)return a.msMatchesSelector(b)
 else if(!!a.oMatchesSelector)return a.oMatchesSelector(b)
-else throw H.b(P.f("Not supported on this platform"))},"call$1","grM",2,0,null,296],
+else throw H.b(P.f("Not supported on this platform"))},"call$1","grM",2,0,null,290,[]],
 bA:[function(a,b){var z=a
 do{if(J.RF(z,b))return!0
 z=z.parentElement}while(z!=null)
-return!1},"call$1","gMn",2,0,null,296],
+return!1},"call$1","gMn",2,0,null,290,[]],
 er:[function(a){return(a.createShadowRoot||a.webkitCreateShadowRoot).call(a)},"call$0","gzd",0,0,null],
 gKE:function(a){return a.shadowRoot||a.webkitShadowRoot},
 gI:function(a){return new W.DM(a,a)},
 gi9:function(a){return C.mt.f0(a)},
-gVl:function(a){return C.T1.f0(a)},
+gVl:function(a){return C.pi.f0(a)},
 gLm:function(a){return C.i3.f0(a)},
 ZL:function(a){},
 $iscv:true,
@@ -15892,161 +16011,159 @@
 $isD0:true,
 "%":";Element"},
 Fs:{
-"":"qE;oc:name%,LA:src=,t5:type%",
+"^":"qE;oc:name%,LA:src=,t5:type%",
 "%":"HTMLEmbedElement"},
 Ty:{
-"":"ea;kc:error=,G1:message=",
+"^":"ea;kc:error=,G1:message=",
 "%":"ErrorEvent"},
 ea:{
-"":"Gv;It:_selector},Xt:bubbles=,t5:type=",
+"^":"Gv;It:_selector},Xt:bubbles=,t5:type=",
 gN:function(a){return W.qc(a.target)},
 $isea:true,
 "%":"AudioProcessingEvent|AutocompleteErrorEvent|BeforeUnloadEvent|CSSFontFaceLoadEvent|DeviceMotionEvent|DeviceOrientationEvent|HashChangeEvent|IDBVersionChangeEvent|MIDIConnectionEvent|MediaKeyNeededEvent|MediaStreamEvent|MediaStreamTrackEvent|MutationEvent|OfflineAudioCompletionEvent|OverflowEvent|PageTransitionEvent|PopStateEvent|RTCDTMFToneChangeEvent|RTCDataChannelEvent|RTCIceCandidateEvent|SecurityPolicyViolationEvent|SpeechInputEvent|SpeechRecognitionEvent|TrackEvent|WebGLContextEvent|WebKitAnimationEvent;Event"},
 D0:{
-"":"Gv;",
+"^":"Gv;",
 gI:function(a){return new W.Jn(a)},
-On:[function(a,b,c,d){return a.addEventListener(b,H.tR(c,1),d)},"call$3","gNe",4,2,null,77,11,298,299],
-Y9:[function(a,b,c,d){return a.removeEventListener(b,H.tR(c,1),d)},"call$3","gcF",4,2,null,77,11,298,299],
+On:[function(a,b,c,d){return a.addEventListener(b,H.tR(c,1),d)},"call$3","gIV",4,2,null,77,11,[],292,[],293,[]],
+Y9:[function(a,b,c,d){return a.removeEventListener(b,H.tR(c,1),d)},"call$3","gcF",4,2,null,77,11,[],292,[],293,[]],
 $isD0:true,
 "%":";EventTarget"},
 as:{
-"":"qE;MB:form=,oc:name%,t5:type=",
+"^":"qE;MB:form=,oc:name%,t5:type=",
 "%":"HTMLFieldSetElement"},
 hH:{
-"":"Az;oc:name=",
+"^":"Az;oc:name=",
 $ishH:true,
 "%":"File"},
-QU:{
-"":"rv;tT:code=",
+Aa:{
+"^":"cm;tT:code=",
 "%":"FileError"},
-Yu:{
-"":"qE;B:length=,bP:method=,oc:name%,N:target=",
+h4:{
+"^":"qE;B:length=,bP:method=,oc:name%,N:target=",
 "%":"HTMLFormElement"},
-Cv:{
-"":"ma;",
+wa:{
+"^":"Gb;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"HTMLCollection|HTMLFormControlsCollection|HTMLOptionsCollection"},
 zU:{
-"":"wa;iC:responseText=,ys:status=,po:statusText=",
-R3:[function(a,b,c,d,e,f){return a.open(b,c,d,f,e)},function(a,b,c,d){return a.open(b,c,d)},"eo","call$5$async$password$user",null,"gqO",4,7,null,77,77,77,221,218,300,301,302],
-wR:[function(a,b){return a.send(b)},"call$1","gX8",0,2,null,77,237],
+"^":"pk;iC:responseText=,ys:status=,po:statusText=",
+R3:[function(a,b,c,d,e,f){return a.open(b,c,d,f,e)},function(a,b,c,d){return a.open(b,c,d)},"eo","call$5$async$password$user",null,"gcY",4,7,null,77,77,77,215,[],212,[],294,[],295,[],296,[]],
+wR:[function(a,b){return a.send(b)},"call$1","gX8",0,2,null,77,231,[]],
 $iszU:true,
 "%":"XMLHttpRequest"},
-wa:{
-"":"D0;",
+pk:{
+"^":"D0;",
 "%":";XMLHttpRequestEventTarget"},
 tX:{
-"":"qE;oc:name%,LA:src=",
+"^":"qE;oc:name%,LA:src=",
 "%":"HTMLIFrameElement"},
 Sg:{
-"":"Gv;Rn:data=",
+"^":"Gv;Rn:data=",
 $isSg:true,
 "%":"ImageData"},
 pA:{
-"":"qE;LA:src=",
-tZ:function(a){return this.complete.call$0()},
-oo:function(a,b){return this.complete.call$1(b)},
+"^":"qE;LA:src=",
+oo:function(a,b){return a.complete.call$1(b)},
 "%":"HTMLImageElement"},
 Mi:{
-"":"qE;Tq:checked%,MB:form=,aK:list=,oc:name%,LA:src=,t5:type%,P:value%",
-RR:function(a,b){return this.accept.call$1(b)},
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;Tq:checked%,MB:form=,aK:list=,oc:name%,LA:src=,t5:type%,P:value%",
+RR:function(a,b){return a.accept.call$1(b)},
+r6:function(a,b){return a.value.call$1(b)},
 $isMi:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true,
+$isKV:true,
 "%":"HTMLInputElement"},
-ttH:{
-"":"qE;MB:form=,oc:name%,t5:type=",
+In:{
+"^":"qE;MB:form=,oc:name%,t5:type=",
 "%":"HTMLKeygenElement"},
 wP:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLLIElement"},
 eP:{
-"":"qE;MB:form=",
+"^":"qE;MB:form=",
 "%":"HTMLLabelElement"},
 mF:{
-"":"qE;MB:form=",
+"^":"qE;MB:form=",
 "%":"HTMLLegendElement"},
 Qj:{
-"":"qE;mH:href=,t5:type%",
+"^":"qE;mH:href=,t5:type%",
 $isQj:true,
 "%":"HTMLLinkElement"},
 cS:{
-"":"Gv;cC:hash%,mH:href=",
+"^":"Gv;cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $iscS:true,
 "%":"Location"},
-M6:{
-"":"qE;oc:name%",
+YI:{
+"^":"qE;oc:name%",
 "%":"HTMLMapElement"},
 El:{
-"":"qE;kc:error=,LA:src=",
-yy:[function(a){return a.pause()},"call$0","gAK",0,0,null],
+"^":"qE;kc:error=,LA:src=",
 "%":"HTMLAudioElement|HTMLMediaElement|HTMLVideoElement"},
 zm:{
-"":"Gv;tT:code=",
+"^":"Gv;tT:code=",
 "%":"MediaError"},
 Y7:{
-"":"Gv;tT:code=",
+"^":"Gv;tT:code=",
 "%":"MediaKeyError"},
 aB:{
-"":"ea;G1:message=",
+"^":"ea;G1:message=",
 "%":"MediaKeyEvent"},
 fJ:{
-"":"ea;G1:message=",
+"^":"ea;G1:message=",
 "%":"MediaKeyMessageEvent"},
 Rv:{
-"":"D0;jO:id=",
+"^":"D0;jO:id=",
 "%":"MediaStream"},
 DD:{
-"":"ea;",
+"^":"ea;",
 gRn:function(a){return P.o7(a.data,!0)},
 $isDD:true,
 "%":"MessageEvent"},
-la:{
-"":"qE;jb:content=,oc:name%",
+EeC:{
+"^":"qE;jb:content=,oc:name%",
 "%":"HTMLMetaElement"},
 Qb:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLMeterElement"},
 Hw:{
-"":"ea;Rn:data=",
+"^":"ea;Rn:data=",
 "%":"MIDIMessageEvent"},
 bn:{
-"":"tH;",
-A8:[function(a,b,c){return a.send(b,c)},function(a,b){return a.send(b)},"wR","call$2",null,"gX8",2,2,null,77,237,303],
+"^":"Imr;",
+LV:[function(a,b,c){return a.send(b,c)},function(a,b){return a.send(b)},"wR","call$2",null,"gX8",2,2,null,77,231,[],297,[]],
 "%":"MIDIOutput"},
-tH:{
-"":"D0;jO:id=,oc:name=,t5:type=",
+Imr:{
+"^":"D0;jO:id=,oc:name=,t5:type=",
 "%":"MIDIInput;MIDIPort"},
-Aj:{
-"":"Mf;",
+Oq:{
+"^":"Mf;",
 nH:[function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){a.initMouseEvent(b,c,d,e,f,g,h,i,j,k,l,m,n,o,W.qr(p))
-return},"call$15","gEx",30,0,null,11,304,305,306,307,308,309,310,311,312,313,314,315,316,317],
-$isAj:true,
+return},"call$15","gEx",30,0,null,11,[],298,[],299,[],300,[],301,[],302,[],303,[],304,[],305,[],306,[],307,[],308,[],309,[],310,[],311,[]],
+$isOq:true,
 "%":"DragEvent|MSPointerEvent|MouseEvent|MouseScrollEvent|MouseWheelEvent|PointerEvent|WheelEvent"},
 H9:{
-"":"Gv;",
+"^":"Gv;",
 jh:[function(a,b,c,d,e,f,g,h,i){var z,y
 z={}
 y=new W.Yg(z)
@@ -16056,155 +16173,167 @@
 y.call$2("subtree",i)
 y.call$2("attributeOldValue",d)
 y.call$2("characterDataOldValue",g)
-a.observe(b,z)},function(a,b,c,d){return this.jh(a,b,null,null,null,null,null,c,d)},"yN","call$8$attributeFilter$attributeOldValue$attributes$characterData$characterDataOldValue$childList$subtree",null,"gTT",2,15,null,77,77,77,77,77,77,77,74,318,319,320,321,322,323,324],
+a.observe(b,z)},function(a,b,c,d){return this.jh(a,b,null,null,null,null,null,c,d)},"yN","call$8$attributeFilter$attributeOldValue$attributes$characterData$characterDataOldValue$childList$subtree",null,"gTT",2,15,null,77,77,77,77,77,77,77,74,[],312,[],313,[],314,[],315,[],316,[],317,[],318,[]],
 "%":"MutationObserver|WebKitMutationObserver"},
 o4:{
-"":"Gv;jL:oldValue=,N:target=,t5:type=",
+"^":"Gv;jL:oldValue=,N:target=,t5:type=",
 "%":"MutationRecord"},
 oU:{
-"":"Gv;",
+"^":"Gv;",
 $isGv:true,
 "%":"Navigator"},
 ih:{
-"":"Gv;G1:message=,oc:name=",
+"^":"Gv;G1:message=,oc:name=",
 "%":"NavigatorUserMediaError"},
-uH:{
-"":"D0;q6:firstChild=,uD:nextSibling=,M0:ownerDocument=,eT:parentElement=,KV:parentNode=,a4:textContent%",
+KV:{
+"^":"D0;q6:firstChild=,uD:nextSibling=,M0:ownerDocument=,eT:parentElement=,KV:parentNode=,a4:textContent%",
 gyT:function(a){return new W.e7(a)},
 wg:[function(a){var z=a.parentNode
 if(z!=null)z.removeChild(a)},"call$0","gRI",0,0,null],
 Tk:[function(a,b){var z,y
 try{z=a.parentNode
-J.ky(z,b,a)}catch(y){H.Ru(y)}return a},"call$1","gdA",2,0,null,325],
+J.ky(z,b,a)}catch(y){H.Ru(y)}return a},"call$1","gdA",2,0,null,319,[]],
 bu:[function(a){var z=a.nodeValue
 return z==null?J.Gv.prototype.bu.call(this,a):z},"call$0","gXo",0,0,null],
-jx:[function(a,b){return a.appendChild(b)},"call$1","gp3",2,0,null,326],
-tg:[function(a,b){return a.contains(b)},"call$1","gdj",2,0,null,104],
-mK:[function(a,b,c){return a.insertBefore(b,c)},"call$2","gHc",4,0,null,326,327],
-dR:[function(a,b,c){return a.replaceChild(b,c)},"call$2","ghn",4,0,null,326,328],
-$isuH:true,
+jx:[function(a,b){return a.appendChild(b)},"call$1","gp3",2,0,null,320,[]],
+tg:[function(a,b){return a.contains(b)},"call$1","gdj",2,0,null,104,[]],
+mK:[function(a,b,c){return a.insertBefore(b,c)},"call$2","gHc",4,0,null,320,[],321,[]],
+dR:[function(a,b,c){return a.replaceChild(b,c)},"call$2","ghn",4,0,null,320,[],322,[]],
+$isKV:true,
 "%":"Entity|Notation;Node"},
 yk:{
-"":"ecX;",
+"^":"ecX;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"NodeList|RadioNodeList"},
 KY:{
-"":"qE;t5:type%",
+"^":"qE;t5:type%",
 "%":"HTMLOListElement"},
 G7:{
-"":"qE;Rn:data=,MB:form=,oc:name%,t5:type%",
+"^":"qE;Rn:data=,MB:form=,oc:name%,t5:type%",
 "%":"HTMLObjectElement"},
 Ql:{
-"":"qE;MB:form=,vH:index=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,vH:index=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 $isQl:true,
 "%":"HTMLOptionElement"},
 Xp:{
-"":"qE;MB:form=,oc:name%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLOutputElement"},
 HD:{
-"":"qE;oc:name%,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;oc:name%,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLParamElement"},
 jg:{
-"":"Gv;tT:code=,G1:message=",
+"^":"Gv;tT:code=,G1:message=",
 "%":"PositionError"},
 nC:{
-"":"OM;N:target=",
+"^":"nx;N:target=",
 "%":"ProcessingInstruction"},
 KR:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLProgressElement"},
 ew:{
-"":"ea;",
+"^":"ea;",
 $isew:true,
 "%":"XMLHttpRequestProgressEvent;ProgressEvent"},
 LY:{
-"":"ew;O3:url=",
+"^":"ew;O3:url=",
 "%":"ResourceProgressEvent"},
 j2:{
-"":"qE;LA:src=,t5:type%",
+"^":"qE;LA:src=,t5:type%",
 $isj2:true,
 "%":"HTMLScriptElement"},
 lp:{
-"":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 gbG:function(a){var z=W.vD(a.querySelectorAll("option"),null)
 z=z.ev(z,new W.kI())
 return H.VM(new P.Yp(P.F(z,!0,H.ip(z,"mW",0))),[null])},
 $islp:true,
 "%":"HTMLSelectElement"},
 I0:{
-"":"hN;pQ:applyAuthorStyles=",
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
+"^":"Aj;pQ:applyAuthorStyles=",
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
 $isI0:true,
 "%":"ShadowRoot"},
 QR:{
-"":"qE;LA:src=,t5:type%",
+"^":"qE;LA:src=,t5:type%",
 "%":"HTMLSourceElement"},
-Hd:{
-"":"ea;kc:error=,G1:message=",
+zD9:{
+"^":"ea;kc:error=,G1:message=",
 "%":"SpeechRecognitionError"},
 G5:{
-"":"ea;oc:name=",
+"^":"ea;oc:name=",
 "%":"SpeechSynthesisEvent"},
-wb:{
-"":"ea;G3:key=,zZ:newValue=,jL:oldValue=,O3:url=",
+bk:{
+"^":"ea;G3:key=,zZ:newValue=,jL:oldValue=,O3:url=",
 "%":"StorageEvent"},
 fq:{
-"":"qE;t5:type%",
+"^":"qE;t5:type%",
 "%":"HTMLStyleElement"},
+Tb:{
+"^":"qE;",
+gWT:function(a){return H.VM(new W.Of(a.rows),[W.tV])},
+"%":"HTMLTableElement"},
+tV:{
+"^":"qE;",
+$istV:true,
+"%":"HTMLTableRowElement"},
+BT:{
+"^":"qE;",
+gWT:function(a){return H.VM(new W.Of(a.rows),[W.tV])},
+"%":"HTMLTableSectionElement"},
 yY:{
-"":"qE;jb:content=",
+"^":"qE;jb:content=",
 $isyY:true,
 "%":"HTMLTemplateElement"},
 kJ:{
-"":"OM;",
+"^":"nx;",
 $iskJ:true,
 "%":"CDATASection|Text"},
 AE:{
-"":"qE;MB:form=,oc:name%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,WT:rows%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 $isAE:true,
 "%":"HTMLTextAreaElement"},
 xV:{
-"":"Mf;Rn:data=",
+"^":"Mf;Rn:data=",
 "%":"TextEvent"},
 RH:{
-"":"qE;fY:kind%,LA:src=",
+"^":"qE;fY:kind%,LA:src=",
 "%":"HTMLTrackElement"},
 OJ:{
-"":"ea;",
+"^":"ea;",
 $isOJ:true,
 "%":"TransitionEvent|WebKitTransitionEvent"},
 Mf:{
-"":"ea;",
+"^":"ea;",
 "%":"FocusEvent|KeyboardEvent|SVGZoomEvent|TouchEvent;UIEvent"},
 u9:{
-"":"D0;oc:name%,ys:status=",
+"^":"D0;oc:name%,ys:status=",
 gmW:function(a){var z=a.location
 if(W.uC(z)===!0)return z
 if(null==a._location_wrapper)a._location_wrapper=new W.Dk(z)
 return a._location_wrapper},
-oB:[function(a,b){return a.requestAnimationFrame(H.tR(b,1))},"call$1","gfl",2,0,null,150],
+oB:[function(a,b){return a.requestAnimationFrame(H.tR(b,1))},"call$1","gfl",2,0,null,148,[]],
 hr:[function(a){if(!!(a.requestAnimationFrame&&a.cancelAnimationFrame))return
   (function($this) {
    var vendors = ['ms', 'moz', 'webkit', 'o'];
@@ -16225,88 +16354,97 @@
 geT:function(a){return W.Pv(a.parent)},
 cO:[function(a){return a.close()},"call$0","gJK",0,0,null],
 xc:[function(a,b,c,d){a.postMessage(P.bL(b),c)
-return},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,329,330],
+return},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,[],323,[],324,[]],
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 gi9:function(a){return C.mt.aM(a)},
-gVl:function(a){return C.T1.aM(a)},
+gVl:function(a){return C.pi.aM(a)},
 gLm:function(a){return C.i3.aM(a)},
 $isu9:true,
 $isGv:true,
 $isD0:true,
 "%":"DOMWindow|Window"},
 Bn:{
-"":"uH;oc:name=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"KV;oc:name=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"Attr"},
+hq:{
+"^":"KV;",
+$isGv:true,
+"%":"DocumentType"},
 Nf:{
-"":"qE;",
+"^":"qE;",
 $isD0:true,
 $isGv:true,
 "%":"HTMLFrameSetElement"},
 QV:{
-"":"w1p;",
+"^":"w1p;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"MozNamedAttrMap|NamedNodeMap"},
 QZ:{
-"":"a;",
-Wt:[function(a,b){return typeof console!="undefined"?console.error(b):null},"call$1","gkc",2,0,452,165],
-To:[function(a){return typeof console!="undefined"?console.info(a):null},"call$1","gqa",2,0,null,165],
-De:[function(a,b){return typeof console!="undefined"?console.profile(b):null},"call$1","gB1",2,0,174,453],
-uj:[function(a){return typeof console!="undefined"?console.time(a):null},"call$1","gFl",2,0,174,453],
-WL:[function(a,b){return typeof console!="undefined"?console.trace(b):null},"call$1","gtN",2,0,452,165],
-static:{"":"wk"}},
-BV:{
-"":"Gv+E1;"},
-E1:{
-"":"a;",
-gyP:function(a){return this.T2(a,"clear")},
-V1:function(a){return this.gyP(a).call$0()},
-gjb:function(a){return this.T2(a,"content")},
-gBb:function(a){return this.T2(a,"left")},
-gT8:function(a){return this.T2(a,"right")},
-gLA:function(a){return this.T2(a,"src")}},
+"^":"a;",
+HH:[function(a){return typeof console!="undefined"?console.count(a):null},"call$1","gOu",2,0,446,165,[]],
+Wt:[function(a,b){return typeof console!="undefined"?console.error(b):null},"call$1","gkc",2,0,446,165,[]],
+To:[function(a){return typeof console!="undefined"?console.info(a):null},"call$1","gqa",2,0,null,165,[]],
+De:[function(a,b){return typeof console!="undefined"?console.profile(b):null},"call$1","gB1",2,0,174,447,[]],
+uj:[function(a){return typeof console!="undefined"?console.time(a):null},"call$1","gFl",2,0,174,447,[]],
+WL:[function(a,b){return typeof console!="undefined"?console.trace(b):null},"call$1","gtN",2,0,446,165,[]],
+static:{"^":"wk"}},
 VG:{
-"":"ar;MW,vG",
-tg:[function(a,b){return J.kE(this.vG,b)},"call$1","gdj",2,0,null,124],
+"^":"ar;MW,vG",
+tg:[function(a,b){return J.kE(this.vG,b)},"call$1","gdj",2,0,null,124,[]],
 gl0:function(a){return this.MW.firstElementChild==null},
 gB:function(a){return this.vG.length},
 t:[function(a,b){var z=this.vG
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=this.vG
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-this.MW.replaceChild(c,z[b])},"call$2","gj3",4,0,null,47,23],
+this.MW.replaceChild(c,z[b])},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize element lists"))},
 h:[function(a,b){this.MW.appendChild(b)
-return b},"call$1","ght",2,0,null,23],
+return b},"call$1","ght",2,0,null,23,[]],
 gA:function(a){var z=this.br(this)
 return H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])},
 FV:[function(a,b){var z,y
 z=J.x(b)
-for(z=J.GP(typeof b==="object"&&b!==null&&!!z.$ise7?P.F(b,!0,null):b),y=this.MW;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
-So:[function(a,b){throw H.b(P.f("Cannot sort element lists"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.SY(null))},"call$4","gam",6,2,null,336,115,116,109,117],
+for(z=J.GP(typeof b==="object"&&b!==null&&!!z.$ise7?P.F(b,!0,null):b),y=this.MW;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort element lists"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.SY(null))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 Rz:[function(a,b){var z=J.x(b)
 if(typeof b==="object"&&b!==null&&!!z.$iscv){z=this.MW
 if(b.parentNode===z){z.removeChild(b)
-return!0}}return!1},"call$1","gRI",2,0,null,6],
+return!0}}return!1},"call$1","gRI",2,0,null,6,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.vG.length)throw H.b(P.TE(b,0,this.vG.length))
+z=this.vG
+y=z.length
+x=this.MW
+if(b===y)x.appendChild(c)
+else{if(b<0||b>=y)return H.e(z,b)
+x.insertBefore(c,z[b])}},"call$2","gQG",4,0,null,47,[],124,[]],
 V1:[function(a){this.MW.textContent=""},"call$0","gyP",0,0,null],
+KI:[function(a,b){var z,y
+z=this.vG
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+this.MW.removeChild(y)
+return y},"call$1","gNM",2,0,null,47,[]],
 grZ:function(a){var z=this.MW.lastElementChild
 if(z==null)throw H.b(new P.lj("No elements"))
 return z},
@@ -16314,18 +16452,18 @@
 $asWO:function(){return[W.cv]},
 $ascX:function(){return[W.cv]}},
 wz:{
-"":"ar;Sn,Sc",
+"^":"ar;Sn,Sc",
 gB:function(a){return this.Sn.length},
 t:[function(a,b){var z=this.Sn
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot modify list"))},"call$2","gj3",4,0,null,47,23],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot modify list"))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot modify list"))},
-So:[function(a,b){throw H.b(P.f("Cannot sort list"))},"call$1","gH7",0,2,null,77,128],
+GT:[function(a,b){throw H.b(P.f("Cannot sort list"))},"call$1","gH7",0,2,null,77,128,[]],
 grZ:function(a){return C.t5.grZ(this.Sn)},
 gDD:function(a){return W.or(this.Sc)},
 gi9:function(a){return C.mt.vo(this)},
-gVl:function(a){return C.T1.vo(this)},
+gVl:function(a){return C.pi.vo(this)},
 gLm:function(a){return C.i3.vo(this)},
 nJ:function(a,b){var z=C.t5.ev(this.Sn,new W.B1())
 this.Sc=P.F(z,!0,H.ip(z,"mW",0))},
@@ -16338,62 +16476,47 @@
 z.nJ(a,b)
 return z}}},
 B1:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,18,"call"],
+return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 M5:{
-"":"Gv;"},
+"^":"Gv;"},
 Jn:{
-"":"a;WK<",
-t:[function(a,b){var z=new W.RO(this.gWK(),b,!1)
-z.$builtinTypeInfo=[null]
-return z},"call$1","gIA",2,0,null,11]},
+"^":"a;WK<",
+t:[function(a,b){return H.VM(new W.RO(this.gWK(),b,!1),[null])},"call$1","gIA",2,0,null,11,[]]},
 DM:{
-"":"Jn;WK:YO<,WK",
-t:[function(a,b){var z,y,x
+"^":"Jn;WK:YO<,WK",
+t:[function(a,b){var z,y
 z=$.Vp()
 y=J.rY(b)
-if(z.gvc(z).Fb.x4(y.hc(b))){x=$.PN
-if(x==null){x=$.L4
-if(x==null){x=window.navigator.userAgent
-x.toString
-x.length
-x=H.m2(x,"Opera",0)
-$.L4=x}if(x!==!0){x=window.navigator.userAgent
-x.toString
-x.length
-x=H.m2(x,"WebKit",0)}else x=!1
-$.PN=x}if(x===!0){z=new W.eu(this.YO,z.t(0,y.hc(b)),!1)
-z.$builtinTypeInfo=[null]
-return z}}z=new W.eu(this.YO,b,!1)
-z.$builtinTypeInfo=[null]
-return z},"call$1","gIA",2,0,null,11],
-static:{"":"fD"}},
+if(z.gvc(z).Fb.x4(y.hc(b)))if(P.F7()===!0)return H.VM(new W.eu(this.YO,z.t(0,y.hc(b)),!1),[null])
+return H.VM(new W.eu(this.YO,b,!1),[null])},"call$1","gIA",2,0,null,11,[]],
+static:{"^":"fD"}},
 RAp:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
-ma:{
-"":"RAp+Gm;",
+$ascX:function(){return[W.KV]}},
+Gb:{
+"^":"RAp+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 Kx:{
-"":"Tp:229;",
-call$1:[function(a){return J.EC(a)},"call$1",null,2,0,null,454,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.EC(a)},"call$1",null,2,0,null,448,[],"call"],
 $isEH:true},
 iO:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.setRequestHeader(a,b)},"call$2",null,4,0,null,455,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.setRequestHeader(a,b)},"call$2",null,4,0,null,449,[],23,[],"call"],
 $isEH:true},
 bU:{
-"":"Tp:229;b,c",
+"^":"Tp:223;b,c",
 call$1:[function(a){var z,y,x
 z=this.c
 y=z.status
@@ -16402,91 +16525,106 @@
 x=this.b
 if(y){y=x.MM
 if(y.Gv!==0)H.vh(new P.lj("Future already completed"))
-y.OH(z)}else x.pm(a)},"call$1",null,2,0,null,18,"call"],
+y.OH(z)}else x.pm(a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Yg:{
-"":"Tp:349;a",
-call$2:[function(a,b){if(b!=null)this.a[a]=b},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){if(b!=null)this.a[a]=b},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 e7:{
-"":"ar;NL",
+"^":"ar;NL",
 grZ:function(a){var z=this.NL.lastChild
 if(z==null)throw H.b(new P.lj("No elements"))
 return z},
-h:[function(a,b){this.NL.appendChild(b)},"call$1","ght",2,0,null,23],
+h:[function(a,b){this.NL.appendChild(b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y,x,w
 z=J.w1(b)
 if(typeof b==="object"&&b!==null&&!!z.$ise7){z=b.NL
 y=this.NL
 if(z!==y)for(x=z.childNodes.length,w=0;w<x;++w)y.appendChild(z.firstChild)
-return}for(z=z.gA(b),y=this.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
+return}for(z=z.gA(b),y=this.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.NL.childNodes.length)throw H.b(P.TE(b,0,this.NL.childNodes.length))
+z=this.NL
+y=z.childNodes
+x=y.length
+if(b===x)z.appendChild(c)
+else{if(b<0||b>=x)return H.e(y,b)
+z.insertBefore(c,y[b])}},"call$2","gQG",4,0,null,47,[],259,[]],
+KI:[function(a,b){var z,y,x
+z=this.NL
+y=z.childNodes
+if(b<0||b>=y.length)return H.e(y,b)
+x=y[b]
+z.removeChild(x)
+return x},"call$1","gNM",2,0,null,47,[]],
 Rz:[function(a,b){var z=J.x(b)
-if(typeof b!=="object"||b===null||!z.$isuH)return!1
+if(typeof b!=="object"||b===null||!z.$isKV)return!1
 z=this.NL
 if(z!==b.parentNode)return!1
 z.removeChild(b)
-return!0},"call$1","gRI",2,0,null,6],
+return!0},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){this.NL.textContent=""},"call$0","gyP",0,0,null],
 u:[function(a,b,c){var z,y
 z=this.NL
 y=z.childNodes
 if(b>>>0!==b||b>=y.length)return H.e(y,b)
-z.replaceChild(c,y[b])},"call$2","gj3",4,0,null,47,23],
+z.replaceChild(c,y[b])},"call$2","gj3",4,0,null,47,[],23,[]],
 gA:function(a){return C.t5.gA(this.NL.childNodes)},
-So:[function(a,b){throw H.b(P.f("Cannot sort Node list"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on Node list"))},"call$4","gam",6,2,null,336,115,116,109,117],
+GT:[function(a,b){throw H.b(P.f("Cannot sort Node list"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on Node list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 gB:function(a){return this.NL.childNodes.length},
 sB:function(a,b){throw H.b(P.f("Cannot set length on immutable List."))},
 t:[function(a,b){var z=this.NL.childNodes
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 $ise7:true,
-$asar:function(){return[W.uH]},
-$asWO:function(){return[W.uH]},
-$ascX:function(){return[W.uH]}},
+$asar:function(){return[W.KV]},
+$asWO:function(){return[W.KV]},
+$ascX:function(){return[W.KV]}},
 nNL:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 ecX:{
-"":"nNL+Gm;",
+"^":"nNL+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 kI:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isQl},"call$1",null,2,0,null,18,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isQl},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 yoo:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 w1p:{
-"":"yoo+Gm;",
+"^":"yoo+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 tJ:{
-"":"a;",
-FV:[function(a,b){J.kH(b,new W.Zc(this))},"call$1","gDY",2,0,null,104],
+"^":"a;",
+FV:[function(a,b){J.kH(b,new W.Zc(this))},"call$1","gDY",2,0,null,104,[]],
 di:[function(a){var z
-for(z=this.gUQ(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G(););return!1},"call$1","gmc",2,0,null,23],
+for(z=this.gUQ(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G(););return!1},"call$1","gmc",2,0,null,23,[]],
 V1:[function(a){var z
 for(z=this.gvc(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)this.Rz(0,z.lo)},"call$0","gyP",0,0,null],
 aN:[function(a,b){var z,y
 for(z=this.gvc(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();){y=z.lo
-b.call$2(y,this.t(0,y))}},"call$1","gjw",2,0,null,110],
+b.call$2(y,this.t(0,y))}},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){var z,y,x,w
 z=this.MW.attributes
 y=H.VM([],[J.O])
@@ -16504,93 +16642,98 @@
 $isZ0:true,
 $asZ0:function(){return[J.O,J.O]}},
 Zc:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,421,277,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 i7:{
-"":"tJ;MW",
-x4:[function(a){return this.MW.hasAttribute(a)},"call$1","gV9",2,0,null,42],
-t:[function(a,b){return this.MW.getAttribute(b)},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){this.MW.setAttribute(b,c)},"call$2","gj3",4,0,null,42,23],
+"^":"tJ;MW",
+x4:[function(a){return this.MW.hasAttribute(a)},"call$1","gV9",2,0,null,42,[]],
+t:[function(a,b){return this.MW.getAttribute(b)},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){this.MW.setAttribute(b,c)},"call$2","gj3",4,0,null,42,[],23,[]],
 Rz:[function(a,b){var z,y
 z=this.MW
 y=z.getAttribute(b)
 z.removeAttribute(b)
-return y},"call$1","gRI",2,0,null,42],
+return y},"call$1","gRI",2,0,null,42,[]],
 gB:function(a){return this.gvc(this).length},
-FJ:[function(a){return a.namespaceURI==null},"call$1","giG",2,0,null,265]},
+FJ:[function(a){return a.namespaceURI==null},"call$1","giG",2,0,null,259,[]]},
 nF:{
-"":"Ay;QX,Kd",
+"^":"As;QX,Kd",
 lF:[function(){var z=P.Ls(null,null,null,J.O)
 this.Kd.aN(0,new W.Si(z))
 return z},"call$0","gt8",0,0,null],
 p5:[function(a){var z,y
 z=C.Nm.zV(P.F(a,!0,null)," ")
-for(y=this.QX,y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();)J.Pw(y.lo,z)},"call$1","gVH",2,0,null,86],
-OS:[function(a){this.Kd.aN(0,new W.vf(a))},"call$1","gFd",2,0,null,110],
-Rz:[function(a,b){return this.xz(new W.Fc(b))},"call$1","gRI",2,0,null,23],
-xz:[function(a){return this.Kd.es(0,!1,new W.hD(a))},"call$1","gVz",2,0,null,110],
+for(y=this.QX,y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();)J.Pw(y.lo,z)},"call$1","gVH",2,0,null,86,[]],
+OS:[function(a){this.Kd.aN(0,new W.vf(a))},"call$1","gFd",2,0,null,110,[]],
+O4:[function(a,b){return this.xz(new W.Iw(a,b))},function(a){return this.O4(a,null)},"qU","call$2",null,"gMk",2,2,null,77,23,[],450,[]],
+Rz:[function(a,b){return this.xz(new W.Fc(b))},"call$1","gRI",2,0,null,23,[]],
+xz:[function(a){return this.Kd.es(0,!1,new W.hD(a))},"call$1","gVz",2,0,null,110,[]],
 yJ:function(a){this.Kd=H.VM(new H.A8(P.F(this.QX,!0,null),new W.FK()),[null,null])},
 static:{or:function(a){var z=new W.nF(a,null)
 z.yJ(a)
 return z}}},
 FK:{
-"":"Tp:229;",
-call$1:[function(a){return new W.I4(a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new W.I4(a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Si:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.FV(0,a.lF())},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.FV(0,a.lF())},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 vf:{
-"":"Tp:229;a",
-call$1:[function(a){return a.OS(this.a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.OS(this.a)},"call$1",null,2,0,null,18,[],"call"],
+$isEH:true},
+Iw:{
+"^":"Tp:223;a,b",
+call$1:[function(a){return a.O4(this.a,this.b)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Fc:{
-"":"Tp:229;a",
-call$1:[function(a){return J.V1(a,this.a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.V1(a,this.a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 hD:{
-"":"Tp:349;a",
-call$2:[function(a,b){return this.a.call$1(b)===!0||a===!0},"call$2",null,4,0,null,456,124,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){return this.a.call$1(b)===!0||a===!0},"call$2",null,4,0,null,451,[],124,[],"call"],
 $isEH:true},
 I4:{
-"":"Ay;MW",
+"^":"As;MW",
 lF:[function(){var z,y,x
 z=P.Ls(null,null,null,J.O)
 for(y=J.uf(this.MW).split(" "),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();){x=J.rr(y.lo)
 if(x.length!==0)z.h(0,x)}return z},"call$0","gt8",0,0,null],
 p5:[function(a){P.F(a,!0,null)
-J.Pw(this.MW,a.zV(0," "))},"call$1","gVH",2,0,null,86]},
+J.Pw(this.MW,a.zV(0," "))},"call$1","gVH",2,0,null,86,[]]},
 e0:{
-"":"a;Ph",
-zc:[function(a,b){return H.VM(new W.RO(a,this.Ph,b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,209,18,299],
-Qm:[function(a,b){return H.VM(new W.eu(a,this.Ph,b),[null])},function(a){return this.Qm(a,!1)},"f0","call$2$useCapture",null,"gAW",2,3,null,209,18,299],
-jl:[function(a,b){return H.VM(new W.pu(a,b,this.Ph),[null])},function(a){return this.jl(a,!1)},"vo","call$2$useCapture",null,"gcJ",2,3,null,209,18,299]},
+"^":"a;Ph",
+zc:[function(a,b){return H.VM(new W.RO(a,this.Ph,b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,205,18,[],293,[]],
+Qm:[function(a,b){return H.VM(new W.eu(a,this.Ph,b),[null])},function(a){return this.Qm(a,!1)},"f0","call$2$useCapture",null,"gAW",2,3,null,205,18,[],293,[]],
+jl:[function(a,b){return H.VM(new W.pu(a,b,this.Ph),[null])},function(a){return this.jl(a,!1)},"vo","call$2$useCapture",null,"gcJ",2,3,null,205,18,[],293,[]]},
 RO:{
-"":"qh;uv,Ph,Sg",
+"^":"qh;uv,Ph,Sg",
 KR:[function(a,b,c,d){var z=new W.Ov(0,this.uv,this.Ph,W.aF(a),this.Sg)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 z.Zz()
-return z},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156]},
+return z},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]]},
 eu:{
-"":"RO;uv,Ph,Sg",
+"^":"RO;uv,Ph,Sg",
 WO:[function(a,b){var z=H.VM(new P.nO(new W.ie(b),this),[H.ip(this,"qh",0)])
-return H.VM(new P.t3(new W.Ea(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,457],
+return H.VM(new P.t3(new W.Ea(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,452,[]],
 $isqh:true},
 ie:{
-"":"Tp:229;a",
-call$1:[function(a){return J.eI(J.l2(a),this.a)},"call$1",null,2,0,null,405,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.NQ(J.l2(a),this.a)},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 Ea:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){J.og(a,this.b)
-return a},"call$1",null,2,0,null,18,"call"],
+return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 pu:{
-"":"qh;DI,Sg,Ph",
+"^":"qh;DI,Sg,Ph",
 WO:[function(a,b){var z=H.VM(new P.nO(new W.i2(b),this),[H.ip(this,"qh",0)])
-return H.VM(new P.t3(new W.b0(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,457],
+return H.VM(new P.t3(new W.b0(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,452,[]],
 KR:[function(a,b,c,d){var z,y,x,w,v
 z=H.VM(new W.qO(null,P.L5(null,null,null,[P.qh,null],[P.MO,null])),[null])
 z.KS(null)
@@ -16598,26 +16741,28 @@
 v.$builtinTypeInfo=[null]
 z.h(0,v)}y=z.aV
 y.toString
-return H.VM(new P.Ik(y),[H.Kp(y,0)]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
+return H.VM(new P.Ik(y),[H.Kp(y,0)]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
 $isqh:true},
 i2:{
-"":"Tp:229;a",
-call$1:[function(a){return J.eI(J.l2(a),this.a)},"call$1",null,2,0,null,405,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.NQ(J.l2(a),this.a)},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 b0:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){J.og(a,this.b)
-return a},"call$1",null,2,0,null,18,"call"],
+return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Ov:{
-"":"MO;VP,uv,Ph,u7,Sg",
+"^":"MO;VP,uv,Ph,u7,Sg",
 ed:[function(){if(this.uv==null)return
 this.Ns()
 this.uv=null
-this.u7=null},"call$0","gZS",0,0,null],
+this.u7=null
+return},"call$0","gZS",0,0,null],
 nB:[function(a,b){if(this.uv==null)return
 this.VP=this.VP+1
-this.Ns()},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,404],
+this.Ns()},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,399,[]],
+gRW:function(){return this.VP>0},
 QE:[function(){if(this.uv==null||this.VP<=0)return
 this.VP=this.VP-1
 this.Zz()},"call$0","gDQ",0,0,null],
@@ -16626,42 +16771,68 @@
 Ns:[function(){var z=this.u7
 if(z!=null)J.GJ(this.uv,this.Ph,z,this.Sg)},"call$0","gEv",0,0,null]},
 qO:{
-"":"a;aV,eM",
+"^":"a;aV,eM",
 h:[function(a,b){var z,y
 z=this.eM
 if(z.x4(b))return
 y=this.aV
-z.u(0,b,b.zC(y.ght(y),new W.RX(this,b),this.aV.gXB()))},"call$1","ght",2,0,null,458],
+z.u(0,b,b.zC(y.ght(y),new W.RX(this,b),this.aV.gXB()))},"call$1","ght",2,0,null,453,[]],
 Rz:[function(a,b){var z=this.eM.Rz(0,b)
-if(z!=null)z.ed()},"call$1","gRI",2,0,null,458],
+if(z!=null)z.ed()},"call$1","gRI",2,0,null,453,[]],
 cO:[function(a){var z,y
 for(z=this.eM,y=z.gUQ(z),y=H.VM(new H.MH(null,J.GP(y.l6),y.T6),[H.Kp(y,0),H.Kp(y,1)]);y.G();)y.lo.ed()
 z.V1(0)
 this.aV.cO(0)},"call$0","gJK",0,0,107],
 KS:function(a){this.aV=P.bK(this.gJK(this),null,!0,a)}},
 RX:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.Rz(0,this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-hP:{
-"":"a;Vy",
-cN:function(a){return this.Vy.call$1(a)},
-zc:[function(a,b){return H.VM(new W.RO(a,this.cN(a),b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,209,18,299]},
+bO:{
+"^":"a;xY",
+cN:function(a){return this.xY.call$1(a)},
+zc:[function(a,b){return H.VM(new W.RO(a,this.cN(a),b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,205,18,[],293,[]]},
 Gm:{
-"":"a;",
+"^":"a;",
 gA:function(a){return H.VM(new W.W9(a,this.gB(a),-1,null),[H.ip(a,"Gm",0)])},
-h:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","gDY",2,0,null,109],
-So:[function(a,b){throw H.b(P.f("Cannot sort immutable List."))},"call$1","gH7",0,2,null,77,128],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gRI",2,0,null,6],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on immutable List."))},"call$4","gam",6,2,null,336,115,116,109,117],
+h:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","ght",2,0,null,23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","gDY",2,0,null,109,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort immutable List."))},"call$1","gH7",0,2,null,77,128,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to immutable List."))},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gNM",2,0,null,454,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gRI",2,0,null,6,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on immutable List."))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
+Of:{
+"^":"ar;xa",
+gA:function(a){return H.VM(new W.Qg(J.GP(this.xa)),[null])},
+gB:function(a){return this.xa.length},
+h:[function(a,b){J.bi(this.xa,b)},"call$1","ght",2,0,null,124,[]],
+Rz:[function(a,b){return J.V1(this.xa,b)},"call$1","gRI",2,0,null,124,[]],
+V1:[function(a){J.U2(this.xa)},"call$0","gyP",0,0,null],
+t:[function(a,b){var z=this.xa
+if(b>>>0!==b||b>=z.length)return H.e(z,b)
+return z[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){var z=this.xa
+if(b>>>0!==b||b>=z.length)return H.e(z,b)
+z[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+sB:function(a,b){J.wg(this.xa,b)},
+GT:[function(a,b){J.LH(this.xa,b)},"call$1","gH7",0,2,null,77,128,[]],
+XU:[function(a,b,c){return J.hf(this.xa,b,c)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],115,[]],
+Pk:[function(a,b,c){return J.ff(this.xa,b,c)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],115,[]],
+xe:[function(a,b,c){return J.Nv(this.xa,b,c)},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){return J.tH(this.xa,b)},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){J.VZ(this.xa,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]]},
+Qg:{
+"^":"a;je",
+G:[function(){return this.je.G()},"call$0","gqy",0,0,null],
+gl:function(){return this.je.QZ}},
 W9:{
-"":"a;nj,vN,Nq,QZ",
+"^":"a;nj,vN,Nq,QZ",
 G:[function(){var z,y
 z=this.Nq+1
 y=this.vN
@@ -16669,278 +16840,295 @@
 this.Nq=z
 return!0}this.QZ=null
 this.Nq=y
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.QZ}},
 vZ:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=H.Va(this.b)
 Object.defineProperty(a, init.dispatchPropertyName, {value: z, enumerable: false, writable: true, configurable: true})
-return this.a(a)},"call$1",null,2,0,null,41,"call"],
+a.constructor=a.__proto__.constructor
+return this.a(a)},"call$1",null,2,0,null,41,[],"call"],
 $isEH:true},
 dW:{
-"":"a;Ui",
+"^":"a;Ui",
 geT:function(a){return W.P1(this.Ui.parent)},
 cO:[function(a){return this.Ui.close()},"call$0","gJK",0,0,null],
-xc:[function(a,b,c,d){this.Ui.postMessage(b,c)},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,329,330],
+xc:[function(a,b,c,d){this.Ui.postMessage(b,c)},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,[],323,[],324,[]],
+gI:function(a){return H.vh(P.SY(null))},
+On:[function(a,b,c,d){return H.vh(P.SY(null))},"call$3","gIV",4,2,null,77,11,[],292,[],293,[]],
+Y9:[function(a,b,c,d){return H.vh(P.SY(null))},"call$3","gcF",4,2,null,77,11,[],292,[],293,[]],
 $isD0:true,
 $isGv:true,
 static:{P1:[function(a){if(a===window)return a
-else return new W.dW(a)},"call$1","lG",2,0,null,235]}},
+else return new W.dW(a)},"call$1","lG",2,0,null,229,[]]}},
 Dk:{
-"":"a;WK",
+"^":"a;WK",
 gcC:function(a){return this.WK.hash},
 scC:function(a,b){this.WK.hash=b},
 gmH:function(a){return this.WK.href},
 bu:[function(a){return this.WK.toString()},"call$0","gXo",0,0,null],
 $iscS:true,
 $isGv:true}}],["dart.dom.indexed_db","dart:indexed_db",,P,{
-"":"",
+"^":"",
 hF:{
-"":"Gv;",
+"^":"Gv;",
 $ishF:true,
 "%":"IDBKeyRange"}}],["dart.dom.svg","dart:svg",,P,{
-"":"",
+"^":"",
 Dh:{
-"":"zp;N:target=,mH:href=",
+"^":"zp;N:target=,mH:href=",
 $isGv:true,
 "%":"SVGAElement"},
 ZJ:{
-"":"Eo;mH:href=",
+"^":"Eo;mH:href=",
 $isGv:true,
 "%":"SVGAltGlyphElement"},
 ui:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGAnimateColorElement|SVGAnimateElement|SVGAnimateMotionElement|SVGAnimateTransformElement|SVGAnimationElement|SVGSetElement"},
-vO:{
-"":"zp;",
+mk:{
+"^":"d0;",
 $isGv:true,
 "%":"SVGCircleElement"},
 DQ:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGClipPathElement"},
 Sm:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGDefsElement"},
 es:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGEllipseElement"},
 eG:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEBlendElement"},
 lv:{
-"":"GN;t5:type=,UQ:values=",
+"^":"d5;t5:type=,UQ:values=",
 $isGv:true,
 "%":"SVGFEColorMatrixElement"},
 pf:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEComponentTransferElement"},
 NV:{
-"":"GN;kp:operator=",
+"^":"d5;kp:operator=",
 $isGv:true,
 "%":"SVGFECompositeElement"},
 W1:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEConvolveMatrixElement"},
-HC:{
-"":"GN;",
+mCz:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDiffuseLightingElement"},
 kK:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDisplacementMapElement"},
 bb:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEFloodElement"},
 tk:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEGaussianBlurElement"},
 me:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGFEImageElement"},
-bO:{
-"":"GN;",
+oB:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEMergeElement"},
 EI:{
-"":"GN;kp:operator=",
+"^":"d5;kp:operator=",
 $isGv:true,
 "%":"SVGFEMorphologyElement"},
 MI:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEOffsetElement"},
-zt:{
-"":"GN;",
+um:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFESpecularLightingElement"},
 kL:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFETileElement"},
 Fu:{
-"":"GN;t5:type=",
+"^":"d5;t5:type=",
 $isGv:true,
 "%":"SVGFETurbulenceElement"},
-OE:{
-"":"GN;mH:href=",
+QN:{
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGFilterElement"},
 N9:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGForeignObjectElement"},
 BA:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGGElement"},
+d0:{
+"^":"zp;",
+"%":";SVGGeometryElement"},
 zp:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":";SVGGraphicsElement"},
 br:{
-"":"zp;mH:href=",
+"^":"zp;mH:href=",
 $isGv:true,
 "%":"SVGImageElement"},
 PIw:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGLineElement"},
 Jq:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMarkerElement"},
 Yd:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMaskElement"},
 lZ:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPathElement"},
 Gr:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGPatternElement"},
 XE:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPolygonElement"},
 GH:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPolylineElement"},
 NJ:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGRectElement"},
 Ue:{
-"":"GN;t5:type%,mH:href=",
+"^":"d5;t5:type%,mH:href=",
 $isGv:true,
 "%":"SVGScriptElement"},
-Lu:{
-"":"GN;t5:type%",
+Lx:{
+"^":"d5;t5:type%",
 "%":"SVGStyleElement"},
-GN:{
-"":"cv;",
+d5:{
+"^":"cv;",
 gDD:function(a){if(a._cssClassSet==null)a._cssClassSet=new P.O7(a)
 return a._cssClassSet},
 gwd:function(a){return H.VM(new P.D7(a,new W.e7(a)),[W.cv])},
+swd:function(a,b){var z=H.VM(new P.D7(a,new W.e7(a)),[W.cv])
+z.h2.NL.textContent=""
+z.FV(0,b)},
 gi9:function(a){return C.mt.f0(a)},
-gVl:function(a){return C.T1.f0(a)},
+gVl:function(a){return C.pi.f0(a)},
 gLm:function(a){return C.i3.f0(a)},
 $isD0:true,
 $isGv:true,
 "%":"SVGAltGlyphDefElement|SVGAltGlyphItemElement|SVGComponentTransferFunctionElement|SVGDescElement|SVGFEDistantLightElement|SVGFEFuncAElement|SVGFEFuncBElement|SVGFEFuncGElement|SVGFEFuncRElement|SVGFEMergeNodeElement|SVGFEPointLightElement|SVGFESpotLightElement|SVGFontElement|SVGFontFaceElement|SVGFontFaceFormatElement|SVGFontFaceNameElement|SVGFontFaceSrcElement|SVGFontFaceUriElement|SVGGlyphElement|SVGHKernElement|SVGMetadataElement|SVGMissingGlyphElement|SVGStopElement|SVGTitleElement|SVGVKernElement;SVGElement"},
 hy:{
-"":"zp;",
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
+"^":"zp;",
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
 $ishy:true,
 $isGv:true,
 "%":"SVGSVGElement"},
 mq:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGSwitchElement"},
 Ke:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGSymbolElement"},
 Xe:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":";SVGTextContentElement"},
 Rk4:{
-"":"Xe;bP:method=,mH:href=",
+"^":"Xe;bP:method=,mH:href=",
 $isGv:true,
 "%":"SVGTextPathElement"},
 Eo:{
-"":"Xe;",
+"^":"Xe;",
 "%":"SVGTSpanElement|SVGTextElement;SVGTextPositioningElement"},
 pyk:{
-"":"zp;mH:href=",
+"^":"zp;mH:href=",
 $isGv:true,
 "%":"SVGUseElement"},
 ZD:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGViewElement"},
 wD:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGGradientElement|SVGLinearGradientElement|SVGRadialGradientElement"},
-zI:{
-"":"GN;",
+mj:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGCursorElement"},
 cB:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDropShadowElement"},
 nb:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGGlyphRefElement"},
 xt:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMPathElement"},
 O7:{
-"":"Ay;LO",
+"^":"As;LO",
 lF:[function(){var z,y,x,w
 z=this.LO.getAttribute("class")
 y=P.Ls(null,null,null,J.O)
 if(z==null)return y
 for(x=z.split(" "),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){w=J.rr(x.lo)
 if(w.length!==0)y.h(0,w)}return y},"call$0","gt8",0,0,null],
-p5:[function(a){this.LO.setAttribute("class",a.zV(0," "))},"call$1","gVH",2,0,null,86]}}],["dart.dom.web_sql","dart:web_sql",,P,{
-"":"",
+p5:[function(a){this.LO.setAttribute("class",a.zV(0," "))},"call$1","gVH",2,0,null,86,[]]}}],["dart.dom.web_sql","dart:web_sql",,P,{
+"^":"",
 TM:{
-"":"Gv;tT:code=,G1:message=",
-"%":"SQLError"}}],["dart.js","dart:js",,P,{
-"":"",
-xZ:[function(a,b){return function(_call, f, captureThis) {return function() {return _call(f, captureThis, this, Array.prototype.slice.apply(arguments));}}(P.R4, a, b)},"call$2$captureThis","Kc",2,3,null,209,110,236],
+"^":"Gv;tT:code=,G1:message=",
+"%":"SQLError"}}],["dart.isolate","dart:isolate",,P,{
+"^":"",
+IU:{
+"^":"a;",
+$isIU:true,
+static:{Jz:function(){return new H.ku((Math.random()*0x100000000>>>0)+(Math.random()*0x100000000>>>0)*4294967296)}}}}],["dart.js","dart:js",,P,{
+"^":"",
+xZ:[function(a,b){return function(_call, f, captureThis) {return function() {return _call(f, captureThis, this, Array.prototype.slice.apply(arguments));}}(P.R4, a, b)},"call$2$captureThis","Kc",2,3,null,205,110,[],230,[]],
 R4:[function(a,b,c,d){var z
 if(b===!0){z=[c]
 C.Nm.FV(z,d)
-d=z}return P.wY(H.Ek(a,P.F(J.C0(d,P.Xl()),!0,null),P.Te(null)))},"call$4","qH",8,0,null,150,236,161,82],
+d=z}return P.wY(H.Ek(a,P.F(J.C0(d,P.Xl()),!0,null),P.Te(null)))},"call$4","qH",8,0,null,148,[],230,[],161,[],82,[]],
 Dm:[function(a,b,c){var z
 if(Object.isExtensible(a))try{Object.defineProperty(a, b, { value: c})
-return!0}catch(z){H.Ru(z)}return!1},"call$3","bE",6,0,null,91,12,23],
+return!0}catch(z){H.Ru(z)}return!1},"call$3","bE",6,0,null,91,[],12,[],23,[]],
+Om:[function(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]
+return},"call$2","Cb",4,0,null,91,[],12,[]],
 wY:[function(a){var z
 if(a==null)return
 else{if(typeof a!=="string")if(typeof a!=="number")if(typeof a!=="boolean"){z=J.x(a)
-z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isuH||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!0
+z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isKV||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!0
 else z=!0
 else z=!0
 if(z)return a
@@ -16948,36 +17136,36 @@
 if(typeof a==="object"&&a!==null&&!!z.$isiP)return H.o2(a)
 else if(typeof a==="object"&&a!==null&&!!z.$isE4)return a.eh
 else if(typeof a==="object"&&a!==null&&!!z.$isEH)return P.hE(a,"$dart_jsFunction",new P.DV())
-else return P.hE(a,"_$dart_jsObject",new P.Hp())}}},"call$1","En",2,0,229,91],
-hE:[function(a,b,c){var z=a[b]
+else return P.hE(a,"_$dart_jsObject",new P.Hp())}}},"call$1","En",2,0,223,91,[]],
+hE:[function(a,b,c){var z=P.Om(a,b)
 if(z==null){z=c.call$1(a)
-P.Dm(a,b,z)}return z},"call$3","nB",6,0,null,91,63,238],
+P.Dm(a,b,z)}return z},"call$3","nB",6,0,null,91,[],63,[],232,[]],
 dU:[function(a){var z
 if(a==null||typeof a=="string"||typeof a=="number"||typeof a=="boolean")return a
 else{if(a instanceof Object){z=J.x(a)
-z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isuH||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!1
+z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isKV||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!1
 if(z)return a
 else if(a instanceof Date)return P.Wu(a.getMilliseconds(),!1)
 else if(a.constructor===DartObject)return a.o
-else return P.ND(a)}},"call$1","Xl",2,0,187,91],
-ND:[function(a){if(typeof a=="function")return P.iQ(a,"_$dart_dartClosure",new P.Nz())
-else if(a instanceof Array)return P.iQ(a,"_$dart_dartObject",new P.Jd())
-else return P.iQ(a,"_$dart_dartObject",new P.QS())},"call$1","ln",2,0,null,91],
-iQ:[function(a,b,c){var z=a[b]
+else return P.ND(a)}},"call$1","Xl",2,0,187,91,[]],
+ND:[function(a){if(typeof a=="function")return P.iQ(a,$.Dp(),new P.Nz())
+else if(a instanceof Array)return P.iQ(a,$.Iq(),new P.Jd())
+else return P.iQ(a,$.Iq(),new P.QS())},"call$1","ln",2,0,null,91,[]],
+iQ:[function(a,b,c){var z=P.Om(a,b)
 if(z==null||!(a instanceof Object)){z=c.call$1(a)
-P.Dm(a,b,z)}return z},"call$3","yF",6,0,null,91,63,238],
+P.Dm(a,b,z)}return z},"call$3","yF",6,0,null,91,[],63,[],232,[]],
 E4:{
-"":"a;eh",
+"^":"a;eh",
 t:[function(a,b){if(typeof b!=="string"&&typeof b!=="number")throw H.b(new P.AT("property is not a String or num"))
-return P.dU(this.eh[b])},"call$1","gIA",2,0,null,66],
+return P.dU(this.eh[b])},"call$1","gIA",2,0,null,66,[]],
 u:[function(a,b,c){if(typeof b!=="string"&&typeof b!=="number")throw H.b(new P.AT("property is not a String or num"))
-this.eh[b]=P.wY(c)},"call$2","gj3",4,0,null,66,23],
+this.eh[b]=P.wY(c)},"call$2","gj3",4,0,null,66,[],23,[]],
 giO:function(a){return 0},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isE4&&this.eh===b.eh},"call$1","gUJ",2,0,null,104],
-Bm:[function(a){return a in this.eh},"call$1","gVOe",2,0,null,66],
+return typeof b==="object"&&b!==null&&!!z.$isE4&&this.eh===b.eh},"call$1","gUJ",2,0,null,104,[]],
+Bm:[function(a){return a in this.eh},"call$1","gVOe",2,0,null,66,[]],
 bu:[function(a){var z,y
 try{z=String(this.eh)
 return z}catch(y){H.Ru(y)
@@ -16985,7 +17173,7 @@
 V7:[function(a,b){var z,y
 z=this.eh
 y=b==null?null:P.F(J.C0(b,P.En()),!0,null)
-return P.dU(z[a].apply(z,y))},function(a){return this.V7(a,null)},"nQ","call$2",null,"gah",2,2,null,77,221,258],
+return P.dU(z[a].apply(z,y))},function(a){return this.V7(a,null)},"nQ","call$2",null,"gah",2,2,null,77,215,[],263,[]],
 $isE4:true,
 static:{uw:function(a,b){var z,y,x
 z=P.wY(a)
@@ -16995,9 +17183,9 @@
 C.Nm.FV(y,H.VM(new H.A8(b,P.En()),[null,null]))
 x=z.bind.apply(z,y)
 String(x)
-return P.ND(new x())},jT:function(a){return P.ND(P.M0(a))},M0:[function(a){return new P.Xb(P.UD(null,null)).call$1(a)},"call$1","Gf",2,0,null,237]}},
-Xb:{
-"":"Tp:229;a",
+return P.ND(new x())},jT:function(a){return P.ND(P.M0(a))},M0:[function(a){return new P.Gn(P.UD(null,null)).call$1(a)},"call$1","Ij",2,0,null,231,[]]}},
+Gn:{
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w,v
 z=this.a
 if(z.x4(a))return z.t(0,a)
@@ -17008,74 +17196,89 @@
 x[w]=this.call$1(y.t(a,w))}return x}else if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!y.$iscX)){v=[]
 z.u(0,a,v)
 C.Nm.FV(v,y.ez(a,this))
-return v}else return P.wY(a)},"call$1",null,2,0,null,91,"call"],
+return v}else return P.wY(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 r7:{
-"":"E4;eh"},
+"^":"E4;eh"},
 Tz:{
-"":"Wk;eh",
+"^":"Wk;eh",
+fz:[function(a,b){var z
+if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
+if(typeof z!=="number")return H.s(z)
+z=b>=z}else z=!0
+else z=!1
+if(z)throw H.b(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))},"call$1","gvs",2,0,null,47,[]],
 t:[function(a,b){var z
 if(typeof b==="number"&&b===C.CD.yu(b)){if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
 if(typeof z!=="number")return H.s(z)
 z=b>=z}else z=!0
 else z=!1
-if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}return P.E4.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,47],
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}return P.E4.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z
 if(typeof b==="number"&&b===C.CD.yu(b)){if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
 if(typeof z!=="number")return H.s(z)
 z=b>=z}else z=!0
 else z=!1
-if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}P.E4.prototype.u.call(this,this,b,c)},"call$2","gj3",4,0,null,47,23],
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}P.E4.prototype.u.call(this,this,b,c)},"call$2","gj3",4,0,null,47,[],23,[]],
 gB:function(a){return P.E4.prototype.t.call(this,this,"length")},
 sB:function(a,b){P.E4.prototype.u.call(this,this,"length",b)},
-h:[function(a,b){this.V7("push",[b])},"call$1","ght",2,0,null,23],
-FV:[function(a,b){this.V7("push",b instanceof Array?b:P.F(b,!0,null))},"call$1","gDY",2,0,null,109],
-YW:[function(a,b,c,d,e){var z,y,x
-z=P.E4.prototype.t.call(this,this,"length")
+h:[function(a,b){this.V7("push",[b])},"call$1","ght",2,0,null,23,[]],
+FV:[function(a,b){this.V7("push",b instanceof Array?b:P.F(b,!0,null))},"call$1","gDY",2,0,null,109,[]],
+xe:[function(a,b,c){var z
+if(b>=0){z=J.WB(P.E4.prototype.t.call(this,this,"length"),1)
 if(typeof z!=="number")return H.s(z)
-z=b>z
+z=b>=z}else z=!0
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))
+this.V7("splice",[b,0,c])},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){this.fz(0,b)
+return J.UQ(this.V7("splice",[b,1]),0)},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){var z,y,x
+if(b>=0){z=P.E4.prototype.t.call(this,this,"length")
+if(typeof z!=="number")return H.s(z)
+z=b>z}else z=!0
 if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))
 z=J.Wx(c)
 if(z.C(c,b)||z.D(c,P.E4.prototype.t.call(this,this,"length")))H.vh(P.TE(c,b,P.E4.prototype.t.call(this,this,"length")))
 y=z.W(c,b)
 if(J.de(y,0))return
+if(e<0)throw H.b(new P.AT(e))
 x=[b,y]
 z=new H.nH(d,e,null)
 z.$builtinTypeInfo=[null]
 if(e<0)H.vh(P.N(e))
 C.Nm.FV(x,z.qZ(0,y))
-this.V7("splice",x)},"call$4","gam",6,2,null,336,115,116,109,117],
-So:[function(a,b){this.V7("sort",[b])},"call$1","gH7",0,2,null,77,128]},
+this.V7("splice",x)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+GT:[function(a,b){this.V7("sort",[b])},"call$1","gH7",0,2,null,77,128,[]]},
 Wk:{
-"":"E4+lD;",
+"^":"E4+lD;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 DV:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=P.xZ(a,!1)
-P.Dm(z,"_$dart_dartClosure",a)
-return z},"call$1",null,2,0,null,91,"call"],
+P.Dm(z,$.Dp(),a)
+return z},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Hp:{
-"":"Tp:229;",
-call$1:[function(a){return new DartObject(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new DartObject(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Nz:{
-"":"Tp:229;",
-call$1:[function(a){return new P.r7(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new P.r7(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Jd:{
-"":"Tp:229;",
-call$1:[function(a){return H.VM(new P.Tz(a),[null])},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return H.VM(new P.Tz(a),[null])},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 QS:{
-"":"Tp:229;",
-call$1:[function(a){return new P.E4(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new P.E4(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true}}],["dart.math","dart:math",,P,{
-"":"",
+"^":"",
 J:[function(a,b){var z
 if(typeof a!=="number")throw H.b(new P.AT(a))
 if(typeof b!=="number")throw H.b(new P.AT(b))
@@ -17085,289 +17288,360 @@
 if(a===0)z=b===0?1/b<0:b<0
 else z=!1
 if(z||isNaN(b))return b
-return a}return a},"call$2","yT",4,0,null,123,180],
+return a}return a},"call$2","yT",4,0,null,123,[],180,[]],
 y:[function(a,b){if(typeof a!=="number")throw H.b(new P.AT(a))
 if(typeof b!=="number")throw H.b(new P.AT(b))
 if(a>b)return a
 if(a<b)return b
 if(typeof b==="number"){if(typeof a==="number")if(a===0)return a+b
-if(C.YI.gG0(b))return b
+if(C.ON.gG0(b))return b
 return a}if(b===0&&C.CD.gzP(a))return b
-return a},"call$2","Yr",4,0,null,123,180]}],["dart.mirrors","dart:mirrors",,P,{
-"":"",
+return a},"call$2","Yr",4,0,null,123,[],180,[]]}],["dart.mirrors","dart:mirrors",,P,{
+"^":"",
 re:[function(a){var z,y
 z=J.x(a)
 if(typeof a!=="object"||a===null||!z.$isuq||z.n(a,C.HH))throw H.b(new P.AT(H.d(a)+" does not denote a class"))
 y=P.o1(a)
 z=J.x(y)
 if(typeof y!=="object"||y===null||!z.$isMs)throw H.b(new P.AT(H.d(a)+" does not denote a class"))
-return y.gJi()},"call$1","vG",2,0,null,42],
+return y.gJi()},"call$1","vG",2,0,null,42,[]],
 o1:[function(a){if(J.de(a,C.HH)){$.Cm().toString
-return $.Cr()}return H.jO(a.gLU())},"call$1","o9",2,0,null,42],
+return $.P8()}return H.jO(a.gLU())},"call$1","o9",2,0,null,42,[]],
 ej:{
-"":"a;",
+"^":"a;",
 $isej:true},
 NL:{
-"":"a;",
+"^":"a;",
 $isNL:true,
 $isej:true},
 vr:{
-"":"a;",
+"^":"a;",
 $isvr:true,
 $isej:true},
 D4:{
-"":"a;",
+"^":"a;",
 $isD4:true,
 $isej:true,
 $isNL:true},
 X9:{
-"":"a;",
+"^":"a;",
 $isX9:true,
 $isNL:true,
 $isej:true},
 Ms:{
-"":"a;",
+"^":"a;",
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-tg:{
-"":"X9;",
-$istg:true},
+ac:{
+"^":"X9;",
+$isac:true},
 RS:{
-"":"a;",
+"^":"a;",
 $isRS:true,
 $isNL:true,
 $isej:true},
 RY:{
-"":"a;",
+"^":"a;",
 $isRY:true,
 $isNL:true,
 $isej:true},
 Ys:{
-"":"a;",
+"^":"a;",
 $isYs:true,
 $isRY:true,
 $isNL:true,
 $isej:true},
 WS4:{
-"":"a;EE,m2,nV,V3"}}],["dart.pkg.collection.wrappers","package:collection/wrappers.dart",,Q,{
-"":"",
+"^":"a;ew,yz,nV,V3"}}],["dart.pkg.collection.wrappers","package:collection/wrappers.dart",,Q,{
+"^":"",
 ah:[function(){throw H.b(P.f("Cannot modify an unmodifiable Map"))},"call$0","A9",0,0,null],
-A2:{
-"":"U4;EV"},
+Gj:{
+"^":"U4;EV"},
 U4:{
-"":"Nx+B8q;",
+"^":"Nx+B8q;",
 $isZ0:true},
 B8q:{
-"":"a;",
-u:[function(a,b,c){return Q.ah()},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){return Q.ah()},"call$1","gDY",2,0,null,104],
-Rz:[function(a,b){Q.ah()},"call$1","gRI",2,0,null,42],
+"^":"a;",
+u:[function(a,b,c){return Q.ah()},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){return Q.ah()},"call$1","gDY",2,0,null,104,[]],
+Rz:[function(a,b){Q.ah()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return Q.ah()},"call$0","gyP",0,0,null],
 $isZ0:true},
 Nx:{
-"":"a;",
-t:[function(a,b){return this.EV.t(0,b)},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){this.EV.u(0,b,c)},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){this.EV.FV(0,b)},"call$1","gDY",2,0,null,104],
+"^":"a;",
+t:[function(a,b){return this.EV.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){this.EV.u(0,b,c)},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){this.EV.FV(0,b)},"call$1","gDY",2,0,null,104,[]],
 V1:[function(a){this.EV.V1(0)},"call$0","gyP",0,0,null],
-x4:[function(a){return this.EV.x4(a)},"call$1","gV9",2,0,null,42],
-di:[function(a){return this.EV.di(a)},"call$1","gmc",2,0,null,23],
-aN:[function(a,b){this.EV.aN(0,b)},"call$1","gjw",2,0,null,110],
+x4:[function(a){return this.EV.x4(a)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return this.EV.di(a)},"call$1","gmc",2,0,null,23,[]],
+aN:[function(a,b){this.EV.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 gl0:function(a){return this.EV.X5===0},
 gor:function(a){return this.EV.X5!==0},
 gvc:function(a){var z=this.EV
 return H.VM(new P.i5(z),[H.Kp(z,0)])},
 gB:function(a){return this.EV.X5},
-Rz:[function(a,b){return this.EV.Rz(0,b)},"call$1","gRI",2,0,null,42],
+Rz:[function(a,b){return this.EV.Rz(0,b)},"call$1","gRI",2,0,null,42,[]],
 gUQ:function(a){var z=this.EV
 return z.gUQ(z)},
-$isZ0:true}}],["dart.typed_data","dart:typed_data",,P,{
-"":"",
-q3:function(a){a.toString
+$isZ0:true}}],["dart.typed_data.implementation","dart:_native_typed_data",,H,{
+"^":"",
+UI:function(a){a.toString
 return a},
-l6:function(a){a.toString
+bu:function(a){a.toString
 return a},
-am:function(a){a.toString
+aR:function(a){a.toString
 return a},
-I2:{
-"":"Gv;",
-$isI2:true,
+WZ:{
+"^":"Gv;",
+gbx:function(a){return C.PT},
+$isWZ:true,
 "%":"ArrayBuffer"},
-HY:{
-"":"Gv;",
-aq:[function(a,b,c){var z=J.Wx(b)
+rn:{
+"^":"Gv;",
+J2:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.F(b,c))throw H.b(P.TE(b,0,c))
-else throw H.b(new P.AT("Invalid list index "+H.d(b)))},"call$2","gDq",4,0,null,47,331],
-iA:[function(a,b,c){if(b>>>0!=b||J.J5(b,c))this.aq(a,b,c)},"call$2","gur",4,0,null,47,331],
-Im:[function(a,b,c,d){var z=d+1
-this.iA(a,b,z)
+else throw H.b(new P.AT("Invalid list index "+H.d(b)))},"call$2","gYE",4,0,null,47,[],325,[]],
+XL:[function(a,b,c){if(b>>>0!=b||J.J5(b,c))this.J2(a,b,c)},"call$2","gDR",4,0,null,47,[],325,[]],
+PZ:[function(a,b,c,d){var z=d+1
+this.XL(a,b,z)
 if(c==null)return d
-this.iA(a,c,z)
+this.XL(a,c,z)
 if(typeof c!=="number")return H.s(c)
 if(b>c)throw H.b(P.TE(b,0,c))
-return c},"call$3","gEU",6,0,null,115,116,331],
+return c},"call$3","gyD",6,0,null,115,[],116,[],325,[]],
+$isrn:true,
 $isHY:true,
-"%":"DataView;ArrayBufferView;ue|Y8|Bk|GG|C0A|RAK|iY"},
-Nn:{
-"":"GG;",
+"%":";ArrayBufferView;LZ|Ob|Ip|Dg|Nb|nA|Pg"},
+df:{
+"^":"rn;",
+gbx:function(a){return C.T1},
+$isHY:true,
+"%":"DataView"},
+Hg:{
+"^":"Dg;",
+gbx:function(a){return C.hN},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Float32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Float32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.GW]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.GW]},
+$isHY:true,
 "%":"Float32Array"},
-Un:{
-"":"GG;",
+L3:{
+"^":"Dg;",
+gbx:function(a){return C.lk},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Float64Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Float64Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.GW]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.GW]},
+$isHY:true,
 "%":"Float64Array"},
-rF:{
-"":"iY;",
+xj:{
+"^":"Pg;",
+gbx:function(a){return C.jV},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int16Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int16Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int16Array"},
-Sb:{
-"":"iY;",
+dE:{
+"^":"Pg;",
+gbx:function(a){return C.Im},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int32Array"},
-UZ:{
-"":"iY;",
+Eb:{
+"^":"Pg;",
+gbx:function(a){return C.la},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int8Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int8Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int8Array"},
-yc:{
-"":"iY;",
+dT:{
+"^":"Pg;",
+gbx:function(a){return C.iN},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint16Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint16Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Uint16Array"},
-Aw:{
-"":"iY;",
+N2:{
+"^":"Pg;",
+gbx:function(a){return C.Vh},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Uint32Array"},
-jx:{
-"":"iY;",
+eE:{
+"^":"Pg;",
+gbx:function(a){return C.nG},
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint8ClampedArray(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint8ClampedArray(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"CanvasPixelArray|Uint8ClampedArray"},
-F0:{
-"":"iY;",
+V6:{
+"^":"Pg;",
+gbx:function(a){return C.eY},
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint8Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint8Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":";Uint8Array"},
-ue:{
-"":"HY;",
+LZ:{
+"^":"rn;",
 gB:function(a){return a.length},
-wY:[function(a,b,c,d,e){var z,y,x
+oZ:[function(a,b,c,d,e){var z,y,x
 z=a.length+1
-this.iA(a,b,z)
-this.iA(a,c,z)
+this.XL(a,b,z)
+this.XL(a,c,z)
 if(typeof c!=="number")return H.s(c)
 if(b>c)throw H.b(P.TE(b,0,c))
 y=c-b
+if(e<0)throw H.b(new P.AT(e))
 x=d.length
 if(x-e<y)throw H.b(new P.lj("Not enough elements"))
 if(e!==0||x!==y)d=d.subarray(e,e+y)
-a.set(d,b)},"call$4","gzB",8,0,null,115,116,27,117],
+a.set(d,b)},"call$4","gP7",8,0,null,115,[],116,[],27,[],117,[]],
 $isXj:true},
-GG:{
-"":"Bk;",
+Dg:{
+"^":"Ip;",
 YW:[function(a,b,c,d,e){var z=J.x(d)
-if(!!z.$isGG){this.wY(a,b,c,d,e)
-return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,336,115,116,109,117],
-$isGG:true,
+if(!!z.$isDg){this.oZ(a,b,c,d,e)
+return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+$isDg:true,
 $isList:true,
 $asWO:function(){return[J.GW]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.GW]}},
-Y8:{
-"":"ue+lD;",
+Ob:{
+"^":"LZ+lD;",
 $isList:true,
 $asWO:function(){return[J.GW]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.GW]}},
-Bk:{
-"":"Y8+SU7;"},
-iY:{
-"":"RAK;",
+Ip:{
+"^":"Ob+SU7;"},
+Pg:{
+"^":"nA;",
 YW:[function(a,b,c,d,e){var z=J.x(d)
-if(!!z.$isiY){this.wY(a,b,c,d,e)
-return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,336,115,116,109,117],
-$isiY:true,
+if(!!z.$isPg){this.oZ(a,b,c,d,e)
+return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+$isPg:true,
 $isList:true,
 $asWO:function(){return[J.im]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.im]}},
-C0A:{
-"":"ue+lD;",
+Nb:{
+"^":"LZ+lD;",
 $isList:true,
 $asWO:function(){return[J.im]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.im]}},
-RAK:{
-"":"C0A+SU7;"}}],["dart2js._js_primitives","dart:_js_primitives",,H,{
-"":"",
+nA:{
+"^":"Nb+SU7;"}}],["dart2js._js_primitives","dart:_js_primitives",,H,{
+"^":"",
 qw:[function(a){if(typeof dartPrint=="function"){dartPrint(a)
 return}if(typeof console=="object"&&typeof console.log=="function"){console.log(a)
 return}if(typeof window=="object")return
 if(typeof print=="function"){print(a)
-return}throw "Unable to print message: " + String(a)},"call$1","XU",2,0,null,26]}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{
-"":"",
-FvP:{
-"":["tuj;m0%-459,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gNI:[function(a){return a.m0},null,null,1,0,460,"instruction",359,360],
-sNI:[function(a,b){a.m0=this.ct(a,C.eJ,a.m0,b)},null,null,3,0,461,23,"instruction",359],
+return}throw "Unable to print message: " + String(a)},"call$1","XU",2,0,null,26,[]]}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{
+"^":"",
+Fv:{
+"^":["tuj;F8%-455,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNI:[function(a){return a.F8},null,null,1,0,456,"instruction",351,352],
+sNI:[function(a,b){a.F8=this.ct(a,C.eJ,a.F8,b)},null,null,3,0,457,23,[],"instruction",351],
 "@":function(){return[C.Vy]},
 static:{AH:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17377,19 +17651,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.Tl.ZL(a)
-C.Tl.oX(a)
-return a},null,null,0,0,108,"new DisassemblyEntryElement$created" /* new DisassemblyEntryElement$created:0:0 */]}},
-"+DisassemblyEntryElement":[462],
+a.X0=w
+C.er.ZL(a)
+C.er.G6(a)
+return a},null,null,0,0,108,"new DisassemblyEntryElement$created"]}},
+"+DisassemblyEntryElement":[458],
 tuj:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["error_view_element","package:observatory/src/observatory_elements/error_view.dart",,F,{
-"":"",
-Ir:{
-"":["Vct;Py%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gkc:[function(a){return a.Py},null,null,1,0,358,"error",359,360],
-skc:[function(a,b){a.Py=this.ct(a,C.YU,a.Py,b)},null,null,3,0,361,23,"error",359],
+"^":"",
+E9:{
+"^":["Vct;Py%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gkc:[function(a){return a.Py},null,null,1,0,350,"error",351,352],
+skc:[function(a,b){a.Py=this.ct(a,C.YU,a.Py,b)},null,null,3,0,353,23,[],"error",351],
 "@":function(){return[C.uW]},
 static:{TW:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17399,17 +17673,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.OD.ZL(a)
-C.OD.oX(a)
-return a},null,null,0,0,108,"new ErrorViewElement$created" /* new ErrorViewElement$created:0:0 */]}},
-"+ErrorViewElement":[463],
+C.OD.G6(a)
+return a},null,null,0,0,108,"new ErrorViewElement$created"]}},
+"+ErrorViewElement":[459],
 Vct:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["field_ref_element","package:observatory/src/observatory_elements/field_ref.dart",,D,{
-"":"",
+"^":"",
 m8:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.E6]},
 static:{Tt:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17418,18 +17692,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.MC.ZL(a)
-C.MC.oX(a)
-return a},null,null,0,0,108,"new FieldRefElement$created" /* new FieldRefElement$created:0:0 */]}},
-"+FieldRefElement":[364]}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{
-"":"",
-jM:{
-"":["D13;vt%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gt0:[function(a){return a.vt},null,null,1,0,358,"field",359,360],
-st0:[function(a,b){a.vt=this.ct(a,C.WQ,a.vt,b)},null,null,3,0,361,23,"field",359],
+C.MC.G6(a)
+return a},null,null,0,0,108,"new FieldRefElement$created"]}},
+"+FieldRefElement":[357]}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{
+"^":"",
+Gk:{
+"^":["D13;vt%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gt0:[function(a){return a.vt},null,null,1,0,350,"field",351,352],
+st0:[function(a,b){a.vt=this.ct(a,C.WQ,a.vt,b)},null,null,3,0,353,23,[],"field",351],
 "@":function(){return[C.Tq]},
 static:{cY:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17439,17 +17714,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.LT.ZL(a)
-C.LT.oX(a)
-return a},null,null,0,0,108,"new FieldViewElement$created" /* new FieldViewElement$created:0:0 */]}},
-"+FieldViewElement":[464],
+C.LT.G6(a)
+return a},null,null,0,0,108,"new FieldViewElement$created"]}},
+"+FieldViewElement":[460],
 D13:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["function_ref_element","package:observatory/src/observatory_elements/function_ref.dart",,U,{
-"":"",
-DKl:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":"",
+GG:{
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.YQ]},
 static:{v9:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17458,18 +17733,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Xo.ZL(a)
-C.Xo.oX(a)
-return a},null,null,0,0,108,"new FunctionRefElement$created" /* new FunctionRefElement$created:0:0 */]}},
-"+FunctionRefElement":[364]}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{
-"":"",
-mk:{
-"":["WZq;Z8%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gMj:[function(a){return a.Z8},null,null,1,0,358,"function",359,360],
-sMj:[function(a,b){a.Z8=this.ct(a,C.nf,a.Z8,b)},null,null,3,0,361,23,"function",359],
+C.Xo.G6(a)
+return a},null,null,0,0,108,"new FunctionRefElement$created"]}},
+"+FunctionRefElement":[357]}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{
+"^":"",
+yb:{
+"^":["WZq;Z8%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gMj:[function(a){return a.Z8},null,null,1,0,350,"function",351,352],
+sMj:[function(a,b){a.Z8=this.ct(a,C.nf,a.Z8,b)},null,null,3,0,353,23,[],"function",351],
 "@":function(){return[C.nu]},
 static:{N0:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17479,19 +17755,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.PJ.ZL(a)
-C.PJ.oX(a)
-return a},null,null,0,0,108,"new FunctionViewElement$created" /* new FunctionViewElement$created:0:0 */]}},
-"+FunctionViewElement":[465],
+a.X0=w
+C.Yu.ZL(a)
+C.Yu.G6(a)
+return a},null,null,0,0,108,"new FunctionViewElement$created"]}},
+"+FunctionViewElement":[461],
 WZq:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["heap_profile_element","package:observatory/src/observatory_elements/heap_profile.dart",,K,{
-"":"",
+"^":"",
 NM:{
-"":["pva;GQ%-77,J0%-77,Oc%-77,CO%-77,e6%-77,an%-77,Ol%-355,X3%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gB1:[function(a){return a.Ol},null,null,1,0,358,"profile",359,360],
-sB1:[function(a,b){a.Ol=this.ct(a,C.vb,a.Ol,b)},null,null,3,0,361,23,"profile",359],
+"^":["pva;GQ%-77,J0%-77,Oc%-77,CO%-77,e6%-77,an%-77,Ol%-347,X3%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gB1:[function(a){return a.Ol},null,null,1,0,350,"profile",351,352],
+sB1:[function(a,b){a.Ol=this.ct(a,C.vb,a.Ol,b)},null,null,3,0,353,23,[],"profile",351],
 i4:[function(a){var z,y
 Z.uL.prototype.i4.call(this,a)
 z=(a.shadowRoot||a.webkitShadowRoot).querySelector("#table")
@@ -17499,8 +17775,8 @@
 y.YZ=P.uw(J.UQ($.NR,"Table"),[z])
 a.an=y
 y.bG.u(0,"allowHtml",!0)
-J.kW(J.Wy(a.an),"sortColumn",1)
-J.kW(J.Wy(a.an),"sortAscending",!1)
+J.kW(J.wc(a.an),"sortColumn",1)
+J.kW(J.wc(a.an),"sortAscending",!1)
 y=(a.shadowRoot||a.webkitShadowRoot).querySelector("#newPieChart")
 z=new L.qu(null,P.L5(null,null,null,null,null))
 z.YZ=P.uw(J.UQ($.NR,"PieChart"),[y])
@@ -17549,33 +17825,33 @@
 case 6:return J.UQ(J.UQ(b,"old"),5)
 case 7:return J.UQ(J.UQ(b,"old"),1)
 case 8:return J.UQ(J.UQ(b,"old"),3)
-default:}},"call$2","gJ2",4,0,466,277,47,"_columnValue"],
+default:}return},"call$2","gGm",4,0,462,272,[],47,[],"_columnValue"],
 Ub:[function(a,b,c,d){var z,y
 z=a.hm.gZ6().R6()
 if(a.hm.gnI().AQ(z)==null){N.Jx("").To("No isolate found.")
 return}y="/"+z+"/allocationprofile"
-a.hm.glw().fB(y).ml(new K.bd(a)).OA(new K.LS())},"call$3","gFz",6,0,376,18,307,74,"refreshData"],
+a.hm.gDF().fB(y).ml(new K.bd(a)).OA(new K.LS())},"call$3","gFz",6,0,369,18,[],301,[],74,[],"refreshData"],
 pM:[function(a,b){this.hZ(a)
 this.ct(a,C.Aq,[],this.gOd(a))
 this.ct(a,C.ST,[],this.goN(a))
-this.ct(a,C.WG,[],this.gBo(a))},"call$1","gaz",2,0,152,231,"profileChanged"],
+this.ct(a,C.WG,[],this.gBo(a))},"call$1","gaz",2,0,150,225,[],"profileChanged"],
 ps:[function(a,b){var z,y,x
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
 x=J.UQ(J.UQ(z,"heaps"),y)
 z=J.U6(x)
-return C.CD.yM(J.FW(J.p0(z.t(x,"time"),1000),z.t(x,"collections")),2)+" ms"},"call$1","gOd",2,0,467,468,"formattedAverage",372],
+return C.CD.yM(J.FW(J.p0(z.t(x,"time"),1000),z.t(x,"collections")),2)+" ms"},"call$1","gOd",2,0,463,464,[],"formattedAverage",365],
 NC:[function(a,b){var z,y
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
-return H.d(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"collections"))},"call$1","gBo",2,0,467,468,"formattedCollections",372],
+return H.d(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"collections"))},"call$1","gBo",2,0,463,464,[],"formattedCollections",365],
 Q0:[function(a,b){var z,y
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
-return J.Ez(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"time"),2)+" secs"},"call$1","goN",2,0,467,468,"formattedTotalCollectionTime",372],
+return J.Ez(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"time"),2)+" secs"},"call$1","goN",2,0,463,464,[],"formattedTotalCollectionTime",365],
 Dd:[function(a){var z=new L.Kf(P.uw(J.UQ($.NR,"DataTable"),null))
 a.e6=z
 z.Gl("string","Class")
@@ -17596,7 +17872,7 @@
 z.Gl("string","Type")
 a.Oc.Gl("number","Size")},null,null,0,0,108,"created"],
 "@":function(){return[C.dA]},
-static:{"":"BO<-77,Hg<-77,xK<-77,V1g<-77,jr<-77,d6<-77",op:[function(a){var z,y,x,w
+static:{"^":"BO<-77,Xa<-77,xK<-77,V1g<-77,r1K<-77,d6<-77",op:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -17605,36 +17881,36 @@
 a.X3=!0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Vc.ZL(a)
-C.Vc.oX(a)
+C.Vc.G6(a)
 C.Vc.Dd(a)
-return a},null,null,0,0,108,"new HeapProfileElement$created" /* new HeapProfileElement$created:0:0 */]}},
-"+HeapProfileElement":[469],
+return a},null,null,0,0,108,"new HeapProfileElement$created"]}},
+"+HeapProfileElement":[465],
 pva:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true},
 bd:{
-"":"Tp:361;a-77",
+"^":"Tp:353;a-77",
 call$1:[function(a){var z,y
 z=this.a
 y=J.RE(z)
-y.sOl(z,y.ct(z,C.vb,y.gOl(z),a))},"call$1",null,2,0,361,470,"call"],
+y.sOl(z,y.ct(z,C.vb,y.gOl(z),a))},"call$1",null,2,0,353,466,[],"call"],
 $isEH:true},
-"+HeapProfileElement_refreshData_closure":[471],
+"+HeapProfileElement_refreshData_closure":[467],
 LS:{
-"":"Tp:349;",
-call$2:[function(a,b){N.Jx("").To(H.d(a)+" "+H.d(b))},"call$2",null,4,0,349,18,472,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").To(H.d(a)+" "+H.d(b))},"call$2",null,4,0,341,18,[],468,[],"call"],
 $isEH:true},
-"+HeapProfileElement_refreshData_closure":[471]}],["html_common","dart:html_common",,P,{
-"":"",
+"+HeapProfileElement_refreshData_closure":[467]}],["html_common","dart:html_common",,P,{
+"^":"",
 bL:[function(a){var z,y
 z=[]
 y=new P.Tm(new P.aI([],z),new P.rG(z),new P.yh(z)).call$1(a)
 new P.wO().call$0()
-return y},"call$1","z1",2,0,null,23],
+return y},"call$1","Lq",2,0,null,23,[]],
 o7:[function(a,b){var z=[]
-return new P.xL(b,new P.CA([],z),new P.YL(z),new P.KC(z)).call$1(a)},"call$2$mustCopy","A1",2,3,null,209,6,239],
+return new P.xL(b,new P.CA([],z),new P.YL(z),new P.KC(z)).call$1(a)},"call$2$mustCopy","A1",2,3,null,205,6,[],233,[]],
 dg:function(){var z=$.L4
 if(z==null){z=J.Vw(window.navigator.userAgent,"Opera",0)
 $.L4=z}return z},
@@ -17642,33 +17918,33 @@
 if(z==null){z=P.dg()!==!0&&J.Vw(window.navigator.userAgent,"WebKit",0)
 $.PN=z}return z},
 aI:{
-"":"Tp:181;b,c",
+"^":"Tp:181;b,c",
 call$1:[function(a){var z,y,x
 z=this.b
 y=z.length
 for(x=0;x<y;++x)if(z[x]===a)return x
 z.push(a)
 this.c.push(null)
-return y},"call$1",null,2,0,null,23,"call"],
+return y},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 rG:{
-"":"Tp:390;d",
+"^":"Tp:385;d",
 call$1:[function(a){var z=this.d
 if(a>=z.length)return H.e(z,a)
-return z[a]},"call$1",null,2,0,null,341,"call"],
+return z[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 yh:{
-"":"Tp:473;e",
+"^":"Tp:469;e",
 call$2:[function(a,b){var z=this.e
 if(a>=z.length)return H.e(z,a)
-z[a]=b},"call$2",null,4,0,null,341,21,"call"],
+z[a]=b},"call$2",null,4,0,null,383,[],21,[],"call"],
 $isEH:true},
 wO:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Tm:{
-"":"Tp:229;f,UI,bK",
+"^":"Tp:223;f,UI,bK",
 call$1:[function(a){var z,y,x,w,v,u
 z={}
 if(a==null)return a
@@ -17681,8 +17957,8 @@
 if(typeof a==="object"&&a!==null&&!!y.$ishH)return a
 if(typeof a==="object"&&a!==null&&!!y.$isAz)return a
 if(typeof a==="object"&&a!==null&&!!y.$isSg)return a
-if(typeof a==="object"&&a!==null&&!!y.$isI2)return a
-if(typeof a==="object"&&a!==null&&!!y.$isHY)return a
+if(typeof a==="object"&&a!==null&&!!y.$isWZ)return a
+if(typeof a==="object"&&a!==null&&!!y.$isrn)return a
 if(typeof a==="object"&&a!==null&&!!y.$isZ0){x=this.f.call$1(a)
 w=this.UI.call$1(x)
 z.a=w
@@ -17690,7 +17966,7 @@
 w={}
 z.a=w
 this.bK.call$2(x,w)
-y.aN(a,new P.rz(z,this))
+y.aN(a,new P.q1(z,this))
 return z.a}if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!y.$isList)){v=y.gB(a)
 x=this.f.call$1(a)
 w=this.UI.call$1(x)
@@ -17701,36 +17977,36 @@
 u=0
 for(;u<v;++u){z=this.call$1(y.t(a,u))
 if(u>=w.length)return H.e(w,u)
-w[u]=z}return w}throw H.b(P.SY("structured clone of other type"))},"call$1",null,2,0,null,18,"call"],
+w[u]=z}return w}throw H.b(P.SY("structured clone of other type"))},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
-rz:{
-"":"Tp:349;a,Gq",
-call$2:[function(a,b){this.a.a[a]=this.Gq.call$1(b)},"call$2",null,4,0,null,42,23,"call"],
+q1:{
+"^":"Tp:341;a,Gq",
+call$2:[function(a,b){this.a.a[a]=this.Gq.call$1(b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 CA:{
-"":"Tp:181;a,b",
+"^":"Tp:181;a,b",
 call$1:[function(a){var z,y,x,w
 z=this.a
 y=z.length
 for(x=0;x<y;++x){w=z[x]
 if(w==null?a==null:w===a)return x}z.push(a)
 this.b.push(null)
-return y},"call$1",null,2,0,null,23,"call"],
+return y},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 YL:{
-"":"Tp:390;c",
+"^":"Tp:385;c",
 call$1:[function(a){var z=this.c
 if(a>=z.length)return H.e(z,a)
-return z[a]},"call$1",null,2,0,null,341,"call"],
+return z[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 KC:{
-"":"Tp:473;d",
+"^":"Tp:469;d",
 call$2:[function(a,b){var z=this.d
 if(a>=z.length)return H.e(z,a)
-z[a]=b},"call$2",null,4,0,null,341,21,"call"],
+z[a]=b},"call$2",null,4,0,null,383,[],21,[],"call"],
 $isEH:true},
 xL:{
-"":"Tp:229;e,f,UI,bK",
+"^":"Tp:223;e,f,UI,bK",
 call$1:[function(a){var z,y,x,w,v,u,t
 if(a==null)return a
 if(typeof a==="boolean")return a
@@ -17755,87 +18031,100 @@
 u=J.w1(y)
 t=0
 for(;t<v;++t)u.u(y,t,this.call$1(x.t(a,t)))
-return y}return a},"call$1",null,2,0,null,18,"call"],
+return y}return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
-Ay:{
-"":"a;",
+As:{
+"^":"a;",
 bu:[function(a){return this.lF().zV(0," ")},"call$0","gXo",0,0,null],
+O4:[function(a,b){var z,y
+z=this.lF()
+if(!z.tg(0,a)===!0){z.h(0,a)
+y=!0}else{z.Rz(0,a)
+y=!1}this.p5(z)
+return y},function(a){return this.O4(a,null)},"qU","call$2",null,"gMk",2,2,null,77,23,[],450,[]],
 gA:function(a){var z=this.lF()
 z=H.VM(new P.zQ(z,z.zN,null,null),[null])
 z.zq=z.O2.H9
 return z},
-aN:[function(a,b){this.lF().aN(0,b)},"call$1","gjw",2,0,null,110],
-zV:[function(a,b){return this.lF().zV(0,b)},"call$1","gnr",0,2,null,334,335],
+aN:[function(a,b){this.lF().aN(0,b)},"call$1","gjw",2,0,null,110,[]],
+zV:[function(a,b){return this.lF().zV(0,b)},"call$1","gnr",0,2,null,328,329,[]],
 ez:[function(a,b){var z=this.lF()
-return H.K1(z,b,H.ip(z,"mW",0),null)},"call$1","gIr",2,0,null,110],
+return H.K1(z,b,H.ip(z,"mW",0),null)},"call$1","gIr",2,0,null,110,[]],
 ev:[function(a,b){var z=this.lF()
-return H.VM(new H.U5(z,b),[H.ip(z,"mW",0)])},"call$1","gIR",2,0,null,110],
-Vr:[function(a,b){return this.lF().Vr(0,b)},"call$1","gG2",2,0,null,110],
+return H.VM(new H.U5(z,b),[H.ip(z,"mW",0)])},"call$1","gIR",2,0,null,110,[]],
+Vr:[function(a,b){return this.lF().Vr(0,b)},"call$1","gG2",2,0,null,110,[]],
 gl0:function(a){return this.lF().X5===0},
 gor:function(a){return this.lF().X5!==0},
 gB:function(a){return this.lF().X5},
-tg:[function(a,b){return this.lF().tg(0,b)},"call$1","gdj",2,0,null,23],
-Zt:[function(a){return this.lF().tg(0,a)?a:null},"call$1","gQB",2,0,null,23],
-h:[function(a,b){return this.OS(new P.GE(b))},"call$1","ght",2,0,null,23],
+tg:[function(a,b){return this.lF().tg(0,b)},"call$1","gdj",2,0,null,23,[]],
+Zt:[function(a){return this.lF().tg(0,a)?a:null},"call$1","gQB",2,0,null,23,[]],
+h:[function(a,b){return this.OS(new P.GE(b))},"call$1","ght",2,0,null,23,[]],
 Rz:[function(a,b){var z,y
 if(typeof b!=="string")return!1
 z=this.lF()
 y=z.Rz(0,b)
 this.p5(z)
-return y},"call$1","gRI",2,0,null,23],
-FV:[function(a,b){this.OS(new P.rl(b))},"call$1","gDY",2,0,null,109],
+return y},"call$1","gRI",2,0,null,23,[]],
+FV:[function(a,b){this.OS(new P.rl(b))},"call$1","gDY",2,0,null,109,[]],
 grZ:function(a){var z=this.lF().lX
 if(z==null)H.vh(new P.lj("No elements"))
 return z.gGc()},
-tt:[function(a,b){return this.lF().tt(0,b)},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+tt:[function(a,b){return this.lF().tt(0,b)},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 eR:[function(a,b){var z=this.lF()
-return H.ke(z,b,H.ip(z,"mW",0))},"call$1","gVQ",2,0,null,292],
-Zv:[function(a,b){return this.lF().Zv(0,b)},"call$1","goY",2,0,null,47],
+return H.ke(z,b,H.ip(z,"mW",0))},"call$1","gZo",2,0,null,287,[]],
+Zv:[function(a,b){return this.lF().Zv(0,b)},"call$1","goY",2,0,null,47,[]],
 V1:[function(a){this.OS(new P.uQ())},"call$0","gyP",0,0,null],
 OS:[function(a){var z,y
 z=this.lF()
 y=a.call$1(z)
 this.p5(z)
-return y},"call$1","gFd",2,0,null,110],
+return y},"call$1","gFd",2,0,null,110,[]],
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.O]}},
 GE:{
-"":"Tp:229;a",
-call$1:[function(a){return a.h(0,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.h(0,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 rl:{
-"":"Tp:229;a",
-call$1:[function(a){return a.FV(0,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.FV(0,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 uQ:{
-"":"Tp:229;",
-call$1:[function(a){return a.V1(0)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a.V1(0)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 D7:{
-"":"ar;F1,h2",
+"^":"ar;F1,h2",
 gzT:function(){var z=this.h2
 return P.F(z.ev(z,new P.hT()),!0,W.cv)},
-aN:[function(a,b){H.bQ(this.gzT(),b)},"call$1","gjw",2,0,null,110],
+aN:[function(a,b){H.bQ(this.gzT(),b)},"call$1","gjw",2,0,null,110,[]],
 u:[function(a,b,c){var z=this.gzT()
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-J.ZP(z[b],c)},"call$2","gj3",4,0,null,47,23],
+J.ZP(z[b],c)},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){var z,y
 z=this.gzT().length
 y=J.Wx(b)
 if(y.F(b,z))return
 else if(y.C(b,0))throw H.b(new P.AT("Invalid list length"))
 this.UZ(0,b,z)},
-h:[function(a,b){this.h2.NL.appendChild(b)},"call$1","ght",2,0,null,23],
+h:[function(a,b){this.h2.NL.appendChild(b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y
-for(z=J.GP(b),y=this.h2.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
+for(z=J.GP(b),y=this.h2.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
 tg:[function(a,b){var z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$iscv)return!1
-return b.parentNode===this.F1},"call$1","gdj",2,0,null,102],
-So:[function(a,b){throw H.b(P.f("Cannot sort filtered list"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on filtered list"))},"call$4","gam",6,2,null,336,115,116,109,117],
-UZ:[function(a,b,c){H.bQ(C.Nm.D6(this.gzT(),b,c),new P.GS())},"call$2","gYH",4,0,null,115,116],
+return b.parentNode===this.F1},"call$1","gdj",2,0,null,102,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort filtered list"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on filtered list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+UZ:[function(a,b,c){H.bQ(C.Nm.D6(this.gzT(),b,c),new P.GS())},"call$2","gYH",4,0,null,115,[],116,[]],
 V1:[function(a){this.h2.NL.textContent=""},"call$0","gyP",0,0,null],
+xe:[function(a,b,c){this.h2.xe(0,b,c)},"call$2","gQG",4,0,null,47,[],23,[]],
+KI:[function(a,b){var z,y
+z=this.gzT()
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+J.QC(y)
+return y},"call$1","gNM",2,0,null,47,[]],
 Rz:[function(a,b){var z,y,x
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$iscv)return!1
@@ -17843,50 +18132,77 @@
 if(y>=z.length)return H.e(z,y)
 x=z[y]
 if(x==null?b==null:x===b){J.QC(x)
-return!0}}return!1},"call$1","gRI",2,0,null,124],
+return!0}}return!1},"call$1","gRI",2,0,null,124,[]],
 gB:function(a){return this.gzT().length},
 t:[function(a,b){var z=this.gzT()
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 gA:function(a){var z=this.gzT()
 return H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])}},
 hT:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,292,"call"],
+return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 GS:{
-"":"Tp:229;",
-call$1:[function(a){return J.QC(a)},"call$1",null,2,0,null,288,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.QC(a)},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true}}],["instance_ref_element","package:observatory/src/observatory_elements/instance_ref.dart",,B,{
-"":"",
+"^":"",
 pR:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["T5;qX%-355,AP,fn,tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+goE:[function(a){return a.qX},null,null,1,0,366,"expanded",351,352],
+soE:[function(a,b){a.qX=this.ct(a,C.mr,a.qX,b)},null,null,3,0,367,23,[],"expanded",351],
 goc:[function(a){var z=a.tY
 if(z==null)return Q.xI.prototype.goc.call(this,a)
-return J.UQ(z,"preview")},null,null,1,0,369,"name"],
+return J.UQ(z,"preview")},null,null,1,0,362,"name"],
+AZ:[function(a,b,c,d){if(a.qX===!0){J.kW(a.tY,"fields",null)
+J.kW(a.tY,"elements",null)
+a.qX=this.ct(a,C.mr,a.qX,!1)}else a.hm.gDF().fB(this.gO3(a)).ml(new B.YE(a)).OA(new B.we())},"call$3","ghM",6,0,470,123,[],180,[],278,[],"toggleExpand"],
 "@":function(){return[C.VW]},
-static:{lu:[function(a){var z,y,x,w
+static:{b4:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
+a.qX=!1
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.cp.ZL(a)
-C.cp.oX(a)
-return a},null,null,0,0,108,"new InstanceRefElement$created" /* new InstanceRefElement$created:0:0 */]}},
-"+InstanceRefElement":[364]}],["instance_view_element","package:observatory/src/observatory_elements/instance_view.dart",,Z,{
-"":"",
+C.cp.G6(a)
+return a},null,null,0,0,108,"new InstanceRefElement$created"]}},
+"+InstanceRefElement":[471],
+T5:{
+"^":"xI+Pi;",
+$isd3:true},
+YE:{
+"^":"Tp:223;a-77",
+call$1:[function(a){var z,y,x
+z=this.a
+y=J.RE(z)
+x=J.U6(a)
+J.kW(y.gtY(z),"fields",x.t(a,"fields"))
+J.kW(y.gtY(z),"elements",x.t(a,"elements"))
+J.kW(y.gtY(z),"length",x.t(a,"length"))
+y.sqX(z,y.ct(z,C.mr,y.gqX(z),!0))},"call$1",null,2,0,223,144,[],"call"],
+$isEH:true},
+"+InstanceRefElement_toggleExpand_closure":[467],
+we:{
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while expanding instance-ref: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,341,18,[],472,[],"call"],
+$isEH:true},
+"+InstanceRefElement_toggleExpand_closure":[467]}],["instance_view_element","package:observatory/src/observatory_elements/instance_view.dart",,Z,{
+"^":"",
 hx:{
-"":["cda;Xh%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gQr:[function(a){return a.Xh},null,null,1,0,358,"instance",359,360],
-sQr:[function(a,b){a.Xh=this.ct(a,C.fn,a.Xh,b)},null,null,3,0,361,23,"instance",359],
+"^":["cda;Xh%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gQr:[function(a){return a.Xh},null,null,1,0,350,"instance",351,352],
+sQr:[function(a,b){a.Xh=this.ct(a,C.fn,a.Xh,b)},null,null,3,0,353,23,[],"instance",351],
 "@":function(){return[C.be]},
-static:{Co:[function(a){var z,y,x,w
+static:{HC:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -17894,19 +18210,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.yK.ZL(a)
-C.yK.oX(a)
-return a},null,null,0,0,108,"new InstanceViewElement$created" /* new InstanceViewElement$created:0:0 */]}},
-"+InstanceViewElement":[474],
+C.yK.G6(a)
+return a},null,null,0,0,108,"new InstanceViewElement$created"]}},
+"+InstanceViewElement":[473],
 cda:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["isolate_list_element","package:observatory/src/observatory_elements/isolate_list.dart",,L,{
-"":"",
+"^":"",
 u7:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-Ak:[function(a,b,c,d){J.kH(a.hm.gnI().gi2(),new L.fW())},"call$3","gBq",6,0,376,18,307,74,"refresh"],
-"@":function(){return[C.jF]},
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+Ak:[function(a,b,c,d){J.kH(a.hm.gnI().gi2(),new L.fW())},"call$3","gBq",6,0,369,18,[],301,[],74,[],"refresh"],
+"@":function(){return[C.jFV]},
 static:{Cu:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -17915,109 +18231,145 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.b9.ZL(a)
-C.b9.oX(a)
-return a},null,null,0,0,108,"new IsolateListElement$created" /* new IsolateListElement$created:0:0 */]}},
-"+IsolateListElement":[475],
+C.b9.G6(a)
+return a},null,null,0,0,108,"new IsolateListElement$created"]}},
+"+IsolateListElement":[474],
 fW:{
-"":"Tp:349;",
-call$2:[function(a,b){J.KM(b)},"call$2",null,4,0,349,241,14,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){J.KM(b)},"call$2",null,4,0,341,236,[],14,[],"call"],
 $isEH:true},
-"+IsolateListElement_refresh_closure":[471]}],["isolate_profile_element","package:observatory/src/observatory_elements/isolate_profile.dart",,X,{
-"":"",
+"+IsolateListElement_refresh_closure":[467]}],["isolate_profile_element","package:observatory/src/observatory_elements/isolate_profile.dart",,X,{
+"^":"",
+qm:{
+"^":["Y2;Aq>,tT>-359,eT,yt-475,wd-476,oH-477,np,AP,fn",null,function(){return[C.mI]},null,function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null],
+C4:[function(a){if(J.z8(J.q8(this.wd),0))return
+H.bQ(this.tT.gVS(),new X.vO(this))},"call$0","gz7",0,0,null],
+o8:[function(){return},"call$0","gDT",0,0,null],
+Af:function(a,b,c){var z,y,x,w,v,u
+z=this.oH
+y=this.tT
+x=this.Aq
+w=J.RE(x)
+v=J.w1(z)
+v.h(z,X.eI(y.gDu(),w.gB1(x).ghV()))
+if(c==null)v.h(z,"")
+else{u=c.tT
+v.h(z,X.eI(u.dJ(y),u.QQ()))}v.h(z,X.eI(y.gfF(),w.gB1(x).ghV()))},
+static:{eI:[function(a,b){return C.CD.yM(100*J.FW(a,b),2)+"%"},"call$2","rC",4,0,null,123,[],234,[]],Tl:function(a,b,c){var z,y
+z=H.VM([],[L.Y2])
+y=c!=null?J.WB(c.yt,1):0
+z=new X.qm(a,b,c,y,z,[],!1,null,null)
+z.Af(a,b,c)
+return z}}},
+vO:{
+"^":"Tp:479;a",
+call$1:[function(a){var z=this.a
+J.bi(z.wd,X.Tl(z.Aq,J.on(a),z))},"call$1",null,2,0,null,478,[],"call"],
+$isEH:true},
 E7:{
-"":["waa;BA%-476,fb=-477,iZ%-477,qY%-477,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gXc:[function(a){return a.BA},null,null,1,0,478,"methodCountSelected",359,372],
-sXc:[function(a,b){a.BA=this.ct(a,C.fQ,a.BA,b)},null,null,3,0,390,23,"methodCountSelected",359],
-gtK:[function(a){return a.iZ},null,null,1,0,479,"topInclusiveCodes",359,372],
-stK:[function(a,b){a.iZ=this.ct(a,C.Yn,a.iZ,b)},null,null,3,0,480,23,"topInclusiveCodes",359],
-gHu:[function(a){return a.qY},null,null,1,0,479,"topExclusiveCodes",359,372],
-sHu:[function(a,b){a.qY=this.ct(a,C.jI,a.qY,b)},null,null,3,0,480,23,"topExclusiveCodes",359],
-i4:[function(a){var z,y
+"^":["waa;BA%-475,fb=-480,qY%-480,qO=-77,Hm%-481,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gXc:[function(a){return a.BA},null,null,1,0,482,"methodCountSelected",351,365],
+sXc:[function(a,b){a.BA=this.ct(a,C.fQ,a.BA,b)},null,null,3,0,385,23,[],"methodCountSelected",351],
+gHu:[function(a){return a.qY},null,null,1,0,483,"topExclusiveCodes",351,365],
+sHu:[function(a,b){a.qY=this.ct(a,C.jI,a.qY,b)},null,null,3,0,484,23,[],"topExclusiveCodes",351],
+i4:[function(a){var z,y,x,w
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null)return
-this.oC(a,y)},"call$0","gQd",0,0,107,"enteredView"],
+x=[]
+w=R.Jk([])
+C.Nm.FV(x,["Method","Exclusive","Caller","Inclusive"])
+a.Hm=new L.XN(x,w,null,null)
+this.oC(a,y)
+this.f9(a,y)},"call$0","gQd",0,0,107,"enteredView"],
 yG:[function(a){},"call$0","gCn",0,0,107,"_startRequest"],
 M8:[function(a){},"call$0","gjt",0,0,107,"_endRequest"],
 wW:[function(a,b){var z,y
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null)return
-this.oC(a,y)},"call$1","ghj",2,0,229,231,"methodCountSelectedChanged"],
+this.oC(a,y)
+this.f9(a,y)},"call$1","ghj",2,0,223,225,[],"methodCountSelectedChanged"],
 Ub:[function(a,b,c,d){var z,y,x
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null){N.Jx("").To("No isolate found.")
 return}x="/"+z+"/profile"
-a.hm.glw().fB(x).ml(new X.RR(a,y)).OA(new X.EL(a))},"call$3","gFz",6,0,376,18,307,74,"refreshData"],
+a.hm.gDF().fB(x).ml(new X.RR(a,y)).OA(new X.EL(a))},"call$3","gFz",6,0,369,18,[],301,[],74,[],"refreshData"],
 IW:[function(a,b,c,d){J.CJ(b,L.hh(b,d))
-this.oC(a,b)},"call$3","gja",6,0,481,14,482,470,"_loadProfileData"],
-oC:[function(a,b){var z,y,x,w
+this.oC(a,b)
+this.f9(a,b)},"call$3","gja",6,0,485,14,[],486,[],466,[],"_loadProfileData"],
+yF:[function(a,b){this.oC(a,b)
+this.f9(a,b)},"call$1","gAL",2,0,487,14,[],"_refresh"],
+f9:[function(a,b){var z,y
+z=[]
+for(y=J.GP(a.qY);y.G();)z.push(X.Tl(b,y.gl(),null))
+a.Hm.rT(z)
+this.ct(a,C.ep,null,a.Hm)},"call$1","gCK",2,0,487,14,[],"_refreshTree"],
+oC:[function(a,b){var z,y
 J.U2(a.qY)
-J.U2(a.iZ)
 if(b==null||J.Tv(b)==null)return
 z=J.UQ(a.fb,a.BA)
-y=J.RE(b)
-x=y.gB1(b).T0(z)
-J.bj(a.qY,x)
-w=y.gB1(b).hg(z)
-J.bj(a.iZ,w)},"call$1","guE",2,0,483,14,"_refreshTopMethods"],
-nN:[function(a,b,c){if(b==null)return""
-return c===!0?H.d(b.gfF()):H.d(b.gDu())},"call$2","gRb",4,0,484,136,485,"codeTicks"],
-n8:[function(a,b,c){var z,y,x
-if(b==null)return""
-z=a.hm.gZ6().R6()
-y=a.hm.gnI().AQ(z)
-if(y==null)return""
-x=c===!0?b.gfF():b.gDu()
-return C.CD.yM(J.FW(x,J.Tv(y).ghV())*100,2)},"call$2","gCP",4,0,484,136,485,"codePercent"],
-uq:[function(a,b){if(b==null||J.O6(b)==null)return""
-return J.O6(b)},"call$1","gcW",2,0,486,136,"codeName"],
-"@":function(){return[C.bp]},
-static:{jD:[function(a){var z,y,x,w,v,u
+y=J.Tv(b).T0(z)
+J.bj(a.qY,y)},"call$1","guE",2,0,487,14,[],"_refreshTopMethods"],
+ka:[function(a,b){return"padding-left: "+H.d(J.p0(b.gyt(),16))+"px;"},"call$1","gGX",2,0,488,489,[],"padding",365],
+LZ:[function(a,b){var z=J.bY(b.gyt(),5)
+if(z>>>0!==z||z>=5)return H.e(C.PQ,z)
+return C.PQ[z]},"call$1","gth",2,0,488,489,[],"coloring",365],
+YF:[function(a,b,c,d){var z,y,x
+z=J.u3(d)
+y=J.x(z)
+if(typeof z==="object"&&z!==null&&!!y.$istV){y=a.Hm
+x=z.rowIndex
+if(typeof x!=="number")return x.W()
+y.qU(x-1)}},"call$3","gpR",6,0,490,18,[],301,[],74,[],"toggleExpanded",365],
+"@":function(){return[C.jR]},
+static:{jD:[function(a){var z,y,x,w,v
 z=R.Jk([])
-y=R.Jk([])
-x=$.Nd()
-w=P.Py(null,null,null,J.O,W.I0)
-v=J.O
-u=W.cv
-u=H.VM(new V.qC(P.Py(null,null,null,v,u),null,null),[v,u])
+y=$.Nd()
+x=P.Py(null,null,null,J.O,W.I0)
+w=J.O
+v=W.cv
+v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
 a.BA=0
 a.fb=[10,20,50]
-a.iZ=z
-a.qY=y
-a.SO=x
-a.B7=w
-a.ZQ=u
+a.qY=z
+a.qO="#tableTree"
+a.SO=y
+a.B7=x
+a.X0=v
 C.XH.ZL(a)
-C.XH.oX(a)
-return a},null,null,0,0,108,"new IsolateProfileElement$created" /* new IsolateProfileElement$created:0:0 */]}},
-"+IsolateProfileElement":[487],
+C.XH.G6(a)
+return a},null,null,0,0,108,"new IsolateProfileElement$created"]}},
+"+IsolateProfileElement":[491],
 waa:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true},
 RR:{
-"":"Tp:361;a-77,b-77",
-call$1:[function(a){var z,y
+"^":"Tp:353;a-77,b-77",
+call$1:[function(a){var z,y,x,w
 z=J.UQ(a,"samples")
 N.Jx("").To("Profile contains "+H.d(z)+" samples.")
-y=this.b
-J.CJ(y,L.hh(y,a))
-J.fo(this.a,y)},"call$1",null,2,0,361,488,"call"],
+y=this.a
+x=this.b
+J.CJ(x,L.hh(x,a))
+w=J.RE(y)
+w.oC(y,x)
+w.f9(y,x)},"call$1",null,2,0,353,492,[],"call"],
 $isEH:true},
-"+IsolateProfileElement_refreshData_closure":[471],
+"+IsolateProfileElement_refreshData_closure":[467],
 EL:{
-"":"Tp:229;c-77",
-call$1:[function(a){},"call$1",null,2,0,229,18,"call"],
+"^":"Tp:223;c-77",
+call$1:[function(a){},"call$1",null,2,0,223,18,[],"call"],
 $isEH:true},
-"+IsolateProfileElement_refreshData_closure":[471]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{
-"":"",
+"+IsolateProfileElement_refreshData_closure":[467]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{
+"^":"",
 St:{
-"":["V0;Pw%-489,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gAq:[function(a){return a.Pw},null,null,1,0,490,"isolate",359,360],
-sAq:[function(a,b){a.Pw=this.ct(a,C.Y2,a.Pw,b)},null,null,3,0,491,23,"isolate",359],
+"^":["V0;Pw%-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gAq:[function(a){return a.Pw},null,null,1,0,493,"isolate",351,352],
+sAq:[function(a,b){a.Pw=this.ct(a,C.Z8,a.Pw,b)},null,null,3,0,494,23,[],"isolate",351],
 "@":function(){return[C.aM]},
 static:{JR:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18027,43 +18379,43 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.nM.ZL(a)
-C.nM.oX(a)
-return a},null,null,0,0,108,"new IsolateSummaryElement$created" /* new IsolateSummaryElement$created:0:0 */]}},
-"+IsolateSummaryElement":[492],
+a.X0=w
+C.Qt.ZL(a)
+C.Qt.G6(a)
+return a},null,null,0,0,108,"new IsolateSummaryElement$created"]}},
+"+IsolateSummaryElement":[495],
 V0:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["json_view_element","package:observatory/src/observatory_elements/json_view.dart",,Z,{
-"":"",
+"^":"",
 vj:{
-"":["V4;eb%-77,kf%-77,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gvL:[function(a){return a.eb},null,null,1,0,108,"json",359,360],
-svL:[function(a,b){a.eb=this.ct(a,C.Gd,a.eb,b)},null,null,3,0,229,23,"json",359],
+"^":["V4;eb%-77,kf%-77,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gvL:[function(a){return a.eb},null,null,1,0,108,"json",351,352],
+svL:[function(a,b){a.eb=this.ct(a,C.Gd,a.eb,b)},null,null,3,0,223,23,[],"json",351],
 i4:[function(a){Z.uL.prototype.i4.call(this,a)
 a.kf=0},"call$0","gQd",0,0,107,"enteredView"],
-yC:[function(a,b){this.ct(a,C.eR,"a","b")},"call$1","gHl",2,0,152,231,"jsonChanged"],
-gW0:[function(a){return J.AG(a.eb)},null,null,1,0,369,"primitiveString"],
+yC:[function(a,b){this.ct(a,C.eR,"a","b")},"call$1","gHl",2,0,150,225,[],"jsonChanged"],
+gW0:[function(a){return J.AG(a.eb)},null,null,1,0,362,"primitiveString"],
 gmm:[function(a){var z,y
 z=a.eb
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)return"Map"
 else if(typeof z==="object"&&z!==null&&(z.constructor===Array||!!y.$isList))return"List"
-return"Primitive"},null,null,1,0,369,"valueType"],
+return"Primitive"},null,null,1,0,362,"valueType"],
 gkG:[function(a){var z=a.kf
 a.kf=J.WB(z,1)
-return z},null,null,1,0,478,"counter"],
+return z},null,null,1,0,482,"counter"],
 gaK:[function(a){var z,y
 z=a.eb
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&(z.constructor===Array||!!y.$isList))return z
-return[]},null,null,1,0,479,"list"],
+return[]},null,null,1,0,483,"list"],
 gvc:[function(a){var z,y
 z=a.eb
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)return J.qA(y.gvc(z))
-return[]},null,null,1,0,479,"keys"],
-r6:[function(a,b){return J.UQ(a.eb,b)},"call$1","gP",2,0,25,42,"value"],
+return[]},null,null,1,0,483,"keys"],
+r6:[function(a,b){return J.UQ(a.eb,b)},"call$1","gP",2,0,25,42,[],"value"],
 "@":function(){return[C.KH]},
 static:{mA:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18075,18 +18427,18 @@
 a.kf=0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.GB.ZL(a)
-C.GB.oX(a)
-return a},null,null,0,0,108,"new JsonViewElement$created" /* new JsonViewElement$created:0:0 */]}},
-"+JsonViewElement":[493],
+C.GB.G6(a)
+return a},null,null,0,0,108,"new JsonViewElement$created"]}},
+"+JsonViewElement":[496],
 V4:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["library_ref_element","package:observatory/src/observatory_elements/library_ref.dart",,R,{
-"":"",
+"^":"",
 LU:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-"@":function(){return[C.uy]},
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"@":function(){return[C.QU]},
 static:{rA:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -18094,19 +18446,20 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Z3.ZL(a)
-C.Z3.oX(a)
-return a},null,null,0,0,108,"new LibraryRefElement$created" /* new LibraryRefElement$created:0:0 */]}},
-"+LibraryRefElement":[364]}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{
-"":"",
-CX:{
-"":["V6;N7%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtD:[function(a){return a.N7},null,null,1,0,358,"library",359,360],
-stD:[function(a,b){a.N7=this.ct(a,C.EV,a.N7,b)},null,null,3,0,361,23,"library",359],
-"@":function(){return[C.Ob]},
+C.Z3.G6(a)
+return a},null,null,0,0,108,"new LibraryRefElement$created"]}},
+"+LibraryRefElement":[357]}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{
+"^":"",
+T2:{
+"^":["V10;N7%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtD:[function(a){return a.N7},null,null,1,0,350,"library",351,352],
+stD:[function(a,b){a.N7=this.ct(a,C.EV,a.N7,b)},null,null,3,0,353,23,[],"library",351],
+"@":function(){return[C.Gg]},
 static:{SP:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -18118,17 +18471,17 @@
 a.N7=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.MG.ZL(a)
-C.MG.oX(a)
-return a},null,null,0,0,108,"new LibraryViewElement$created" /* new LibraryViewElement$created:0:0 */]}},
-"+LibraryViewElement":[494],
-V6:{
-"":"uL+Pi;",
+C.MG.G6(a)
+return a},null,null,0,0,108,"new LibraryViewElement$created"]}},
+"+LibraryViewElement":[497],
+V10:{
+"^":"uL+Pi;",
 $isd3:true}}],["logging","package:logging/logging.dart",,N,{
-"":"",
+"^":"",
 TJ:{
-"":"a;oc>,eT>,n2,Cj>,wd>,Gs",
+"^":"a;oc>,eT>,n2,Cj>,wd>,Gs",
 gB8:function(){var z,y,x
 z=this.eT
 y=z==null||J.de(J.O6(z),"")
@@ -18142,7 +18495,7 @@
 else{if(this.eT!=null)throw H.b(P.f("Please set \"hierarchicalLoggingEnabled\" to true if you want to change the level on a non-root logger."))
 $.Y4=a}},
 gSZ:function(){return this.IE()},
-mL:[function(a){return a.P>=this.gOR().P},"call$1","goT",2,0,null,23],
+Im:[function(a){return a.P>=this.gOR().P},"call$1","goT",2,0,null,23,[]],
 Y6:[function(a,b,c,d){var z,y,x,w,v
 if(a.P>=this.gOR().P){z=this.gB8()
 y=new P.iP(Date.now(),!1)
@@ -18152,25 +18505,25 @@
 w=new N.HV(a,b,z,y,x,c,d)
 if($.RL)for(v=this;v!=null;){z=J.RE(v)
 z.od(v,w)
-v=z.geT(v)}else J.EY(N.Jx(""),w)}},"call$4","gA9",4,4,null,77,77,495,20,146,147],
-X2:[function(a,b,c){return this.Y6(C.Ab,a,b,c)},function(a){return this.X2(a,null,null)},"x9","call$3",null,"git",2,4,null,77,77,20,146,147],
-yl:[function(a,b,c){return this.Y6(C.R5,a,b,c)},function(a){return this.yl(a,null,null)},"J4","call$3",null,"gjW",2,4,null,77,77,20,146,147],
-ZG:[function(a,b,c){return this.Y6(C.IF,a,b,c)},function(a){return this.ZG(a,null,null)},"To","call$3",null,"gqa",2,4,null,77,77,20,146,147],
-xH:[function(a,b,c){return this.Y6(C.UP,a,b,c)},function(a){return this.xH(a,null,null)},"j2","call$3",null,"goa",2,4,null,77,77,20,146,147],
-WB:[function(a,b,c){return this.Y6(C.xl,a,b,c)},function(a){return this.WB(a,null,null)},"hh","call$3",null,"gxx",2,4,null,77,77,20,146,147],
+v=z.geT(v)}else J.EY(N.Jx(""),w)}},"call$4","gA9",4,4,null,77,77,498,[],20,[],152,[],153,[]],
+X2:[function(a,b,c){return this.Y6(C.Ab,a,b,c)},function(a){return this.X2(a,null,null)},"x9","call$3",null,"git",2,4,null,77,77,20,[],152,[],153,[]],
+yl:[function(a,b,c){return this.Y6(C.R5,a,b,c)},function(a){return this.yl(a,null,null)},"J4","call$3",null,"gjW",2,4,null,77,77,20,[],152,[],153,[]],
+ZG:[function(a,b,c){return this.Y6(C.IF,a,b,c)},function(a){return this.ZG(a,null,null)},"To","call$3",null,"gqa",2,4,null,77,77,20,[],152,[],153,[]],
+xH:[function(a,b,c){return this.Y6(C.UP,a,b,c)},function(a){return this.xH(a,null,null)},"j2","call$3",null,"goa",2,4,null,77,77,20,[],152,[],153,[]],
+WB:[function(a,b,c){return this.Y6(C.cV,a,b,c)},function(a){return this.WB(a,null,null)},"hh","call$3",null,"gxx",2,4,null,77,77,20,[],152,[],153,[]],
 IE:[function(){if($.RL||this.eT==null){var z=this.Gs
 if(z==null){z=P.bK(null,null,!0,N.HV)
 this.Gs=z}z.toString
-return H.VM(new P.Ik(z),[H.Kp(z,0)])}else return N.Jx("").IE()},"call$0","gOp",0,0,null],
+return H.VM(new P.Ik(z),[H.Kp(z,0)])}else return N.Jx("").IE()},"call$0","gnc",0,0,null],
 od:[function(a,b){var z=this.Gs
 if(z!=null){if(z.Gv>=4)H.vh(z.q7())
-z.Iv(b)}},"call$1","gHh",2,0,null,22],
+z.Iv(b)}},"call$1","gHh",2,0,null,22,[]],
 QL:function(a,b,c){var z=this.eT
 if(z!=null)J.Tr(z).u(0,this.oc,this)},
 $isTJ:true,
-static:{"":"DY",Jx:function(a){return $.U0().to(a,new N.dG(a))}}},
+static:{"^":"DY",Jx:function(a){return $.U0().to(a,new N.dG(a))}}},
 dG:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 if(C.xB.nC(z,"."))H.vh(new P.AT("name shouldn't start with a '.'"))
@@ -18178,72 +18531,72 @@
 if(y===-1)x=z!==""?N.Jx(""):null
 else{x=N.Jx(C.xB.Nj(z,0,y))
 z=C.xB.yn(z,y+1)}w=P.L5(null,null,null,J.O,N.TJ)
-v=new N.TJ(z,x,null,w,H.VM(new Q.A2(w),[null,null]),null)
+v=new N.TJ(z,x,null,w,H.VM(new Q.Gj(w),[null,null]),null)
 v.QL(z,x,w)
 return v},"call$0",null,0,0,null,"call"],
 $isEH:true},
 qV:{
-"":"a;oc>,P>",
+"^":"a;oc>,P>",
 r6:function(a,b){return this.P.call$1(b)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isqV&&this.P===b.P},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$isqV&&this.P===b.P},"call$1","gUJ",2,0,null,104,[]],
 C:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P<z},"call$1","gix",2,0,null,104],
+return this.P<z},"call$1","gix",2,0,null,104,[]],
 E:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P<=z},"call$1","gf5",2,0,null,104],
+return this.P<=z},"call$1","gf5",2,0,null,104,[]],
 D:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P>z},"call$1","gh1",2,0,null,104],
+return this.P>z},"call$1","gh1",2,0,null,104,[]],
 F:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P>=z},"call$1","gNH",2,0,null,104],
+return this.P>=z},"call$1","gNH",2,0,null,104,[]],
 iM:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P-z},"call$1","gYc",2,0,null,104],
+return this.P-z},"call$1","gYc",2,0,null,104,[]],
 giO:function(a){return this.P},
 bu:[function(a){return this.oc},"call$0","gXo",0,0,null],
 $isqV:true,
-static:{"":"V7K,tmj,Enk,LkO,reI,pd,Eb,AN,JY,lDu,B9"}},
+static:{"^":"V7K,tmj,Enk,us,reI,pd,Wr,AN,JY,lM,B9"}},
 HV:{
-"":"a;OR<,G1>,iJ,Fl<,O0,kc>,I4<",
+"^":"a;OR<,G1>,iJ,Fl<,O0,kc>,I4<",
 bu:[function(a){return"["+this.OR.oc+"] "+this.iJ+": "+this.G1},"call$0","gXo",0,0,null],
 $isHV:true,
-static:{"":"xO"}}}],["","main.dart",,F,{
-"":"",
+static:{"^":"xO"}}}],["","main.dart",,F,{
+"^":"",
 E2:[function(){N.Jx("").sOR(C.IF)
 N.Jx("").gSZ().yI(new F.em())
 N.Jx("").To("Starting Observatory")
 var z=H.VM(new P.Zf(P.Dt(null)),[null])
 N.Jx("").To("Loading Google Charts API")
 J.UQ($.cM(),"google").V7("load",["visualization","1",P.jT(H.B7(["packages",["corechart","table"],"callback",new P.r7(P.xZ(z.gv6(z),!0))],P.L5(null,null,null,null,null)))])
-z.MM.ml(L.vN()).ml(new F.Lb())},"call$0","lS",0,0,null],
+z.MM.ml(L.vN()).ml(new F.Lb())},"call$0","qg",0,0,null],
 em:{
-"":"Tp:497;",
-call$1:[function(a){P.JS(a.gOR().oc+": "+H.d(a.gFl())+": "+H.d(J.yj(a)))},"call$1",null,2,0,null,496,"call"],
+"^":"Tp:500;",
+call$1:[function(a){P.JS(a.gOR().oc+": "+H.d(a.gFl())+": "+H.d(J.yj(a)))},"call$1",null,2,0,null,499,[],"call"],
 $isEH:true},
 Lb:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){N.Jx("").To("Initializing Polymer")
-A.Ok()},"call$1",null,2,0,null,240,"call"],
+A.Ok()},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true}}],["message_viewer_element","package:observatory/src/observatory_elements/message_viewer.dart",,L,{
-"":"",
+"^":"",
 PF:{
-"":["uL;Gj%-355,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gG1:[function(a){return a.Gj},null,null,1,0,358,"message",360],
+"^":["uL;Gj%-347,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gG1:[function(a){return a.Gj},null,null,1,0,350,"message",352],
 sG1:[function(a,b){a.Gj=b
 this.ct(a,C.US,"",this.gQW(a))
-this.ct(a,C.wt,[],this.glc(a))
-N.Jx("").To("Viewing message of type '"+H.d(J.UQ(a.Gj,"type"))+"'")},null,null,3,0,361,183,"message",360],
+this.ct(a,C.zu,[],this.glc(a))
+N.Jx("").To("Viewing message of type '"+H.d(J.UQ(a.Gj,"type"))+"'")},null,null,3,0,353,183,[],"message",352],
 gQW:[function(a){var z=a.Gj
 if(z==null||J.UQ(z,"type")==null)return"Error"
-return J.UQ(a.Gj,"type")},null,null,1,0,369,"messageType"],
+return J.UQ(a.Gj,"type")},null,null,1,0,362,"messageType"],
 glc:[function(a){var z=a.Gj
 if(z==null||J.UQ(z,"members")==null)return[]
-return J.UQ(a.Gj,"members")},null,null,1,0,498,"members"],
+return J.UQ(a.Gj,"members")},null,null,1,0,501,"members"],
 "@":function(){return[C.rc]},
 static:{A5:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18253,26 +18606,26 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Wp.ZL(a)
-C.Wp.oX(a)
-return a},null,null,0,0,108,"new MessageViewerElement$created" /* new MessageViewerElement$created:0:0 */]}},
-"+MessageViewerElement":[475]}],["metadata","../../../../../../../../../dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{
-"":"",
+C.Wp.G6(a)
+return a},null,null,0,0,108,"new MessageViewerElement$created"]}},
+"+MessageViewerElement":[474]}],["metadata","../../../../../../../../../dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{
+"^":"",
 fA:{
-"":"a;T9,Jt",
-static:{"":"Ze,en,pjg,PZ,xa"}},
+"^":"a;T9,Jt",
+static:{"^":"n4I,en,pjg,PZ,xa"}},
 tz:{
-"":"a;"},
+"^":"a;"},
 jA:{
-"":"a;oc>"},
-Jo:{
-"":"a;"},
+"^":"a;oc>"},
+PO:{
+"^":"a;"},
 c5:{
-"":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{
-"":"",
+"^":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{
+"^":"",
 qT:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.KG]},
 static:{BW:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18282,30 +18635,30 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Xg.ZL(a)
-C.Xg.oX(a)
-return a},null,null,0,0,108,"new NavigationBarElement$created" /* new NavigationBarElement$created:0:0 */]}},
-"+NavigationBarElement":[475]}],["navigation_bar_isolate_element","package:observatory/src/observatory_elements/navigation_bar_isolate.dart",,F,{
-"":"",
+C.Xg.G6(a)
+return a},null,null,0,0,108,"new NavigationBarElement$created"]}},
+"+NavigationBarElement":[474]}],["navigation_bar_isolate_element","package:observatory/src/observatory_elements/navigation_bar_isolate.dart",,F,{
+"^":"",
 Xd:{
-"":["V10;rK%-499,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gNa:[function(a){return a.rK},null,null,1,0,500,"links",359,372],
-sNa:[function(a,b){a.rK=this.ct(a,C.AX,a.rK,b)},null,null,3,0,501,23,"links",359],
+"^":["V11;rK%-477,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNa:[function(a){return a.rK},null,null,1,0,502,"links",351,365],
+sNa:[function(a,b){a.rK=this.ct(a,C.AX,a.rK,b)},null,null,3,0,503,23,[],"links",351],
 Pz:[function(a,b){Z.uL.prototype.Pz.call(this,a,b)
-this.ct(a,C.T7,"",this.gMm(a))},"call$1","gpx",2,0,152,231,"appChanged"],
-lJ:[function(a){var z,y
+this.ct(a,C.T7,"",this.gMm(a))},"call$1","gpx",2,0,150,225,[],"appChanged"],
+Zc:[function(a){var z,y
 z=a.hm
 if(z==null)return""
 y=z.gZ6().Pr()
 if(y==null)return""
-return J.O6(y)},"call$0","gMm",0,0,369,"currentIsolateName"],
-KdI:[function(a,b){var z=a.hm
+return J.O6(y)},"call$0","gMm",0,0,362,"currentIsolateName"],
+Ta:[function(a,b){var z=a.hm
 if(z==null)return""
 switch(b){case"Stacktrace":return z.gZ6().kP("stacktrace")
 case"Library":return z.gZ6().kP("library")
 case"CPU Profile":return z.gZ6().kP("profile")
-default:return z.gZ6().kP("")}},"call$1","gz7",2,0,206,502,"currentIsolateLink"],
+default:return z.gZ6().kP("")}},"call$1","gcD",2,0,504,505,[],"currentIsolateLink"],
 "@":function(){return[C.AR]},
 static:{L1:[function(a){var z,y,x,w,v
 z=R.Jk(["Stacktrace","Library","CPU Profile"])
@@ -18317,21 +18670,21 @@
 a.rK=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.Vn.ZL(a)
-C.Vn.oX(a)
-return a},null,null,0,0,108,"new NavigationBarIsolateElement$created" /* new NavigationBarIsolateElement$created:0:0 */]}},
-"+NavigationBarIsolateElement":[503],
-V10:{
-"":"uL+Pi;",
+C.Vn.G6(a)
+return a},null,null,0,0,108,"new NavigationBarIsolateElement$created"]}},
+"+NavigationBarIsolateElement":[506],
+V11:{
+"^":"uL+Pi;",
 $isd3:true}}],["observatory","package:observatory/observatory.dart",,L,{
-"":"",
+"^":"",
 m7:[function(a){var z
 N.Jx("").To("Google Charts API loaded")
 z=J.UQ(J.UQ($.cM(),"google"),"visualization")
 $.NR=z
-return z},"call$1","vN",2,0,229,240],
-TK:[function(a){var z,y,x,w,v,u
+return z},"call$1","vN",2,0,223,235,[]],
+CX:[function(a){var z,y,x,w,v,u
 z=$.mE().R4(0,a)
 if(z==null)return 0
 try{x=z.gQK().input
@@ -18343,7 +18696,7 @@
 if(typeof w!=="number")return H.s(w)
 y=H.BU(C.xB.yn(x,v+w),16,null)
 return y}catch(u){H.Ru(u)
-return 0}},"call$1","Yh",2,0,null,218],
+return 0}},"call$1","Cz",2,0,null,212,[]],
 r5:[function(a){var z,y,x,w,v
 z=$.kj().R4(0,a)
 if(z==null)return
@@ -18354,10 +18707,10 @@
 if(0>=y.length)return H.e(y,0)
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
-return C.xB.Nj(x,w,v+y)},"call$1","cK",2,0,null,218],
+return C.xB.Nj(x,w,v+y)},"call$1","cK",2,0,null,212,[]],
 Lw:[function(a){var z=L.r5(a)
 if(z==null)return
-return J.ZZ(z,1)},"call$1","J4",2,0,null,218],
+return J.ZZ(z,1)},"call$1","J4",2,0,null,212,[]],
 CB:[function(a){var z,y,x,w
 z=$.XJ().R4(0,a)
 if(z==null)return
@@ -18367,58 +18720,60 @@
 if(0>=y.length)return H.e(y,0)
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
-return C.xB.yn(x,w+y)},"call$1","jU",2,0,null,218],
+return C.xB.yn(x,w+y)},"call$1","jU",2,0,null,212,[]],
 mL:{
-"":["Pi;Z6<-504,lw<-505,nI<-506,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null],
+"^":["Pi;Z6<-507,DF<-508,nI<-509,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null],
 pO:[function(){var z,y,x
 z=this.Z6
 z.sXT(this)
-y=this.lw
+y=this.DF
 y.sXT(this)
 x=this.nI
 x.sXT(this)
 $.tE=this
 y.se0(x.gPI())
 z.kI()},"call$0","gGo",0,0,null],
-AQ:[function(a){return J.UQ(this.nI.gi2(),a)},"call$1","grE",2,0,null,241],
+AQ:[function(a){return J.UQ(this.nI.gi2(),a)},"call$1","grE",2,0,null,236,[]],
 US:function(){this.pO()},
 hq:function(){this.pO()},
-static:{"":"Tj,pQ"}},
+static:{"^":"li,pQ"}},
 Kf:{
-"":"a;oV<",
-Gl:[function(a,b){this.oV.V7("addColumn",[a,b])},"call$2","gGU",4,0,null,11,507],
+"^":"a;oV<",
+goH:function(){return this.oV.nQ("getNumberOfColumns")},
+gWT:function(a){return this.oV.nQ("getNumberOfRows")},
+Gl:[function(a,b){this.oV.V7("addColumn",[a,b])},"call$2","gGU",4,0,null,11,[],510,[]],
 lb:[function(){var z=this.oV
 z.V7("removeRows",[0,z.nQ("getNumberOfRows")])},"call$0","gGL",0,0,null],
 RP:[function(a,b){var z=[]
 C.Nm.FV(z,H.VM(new H.A8(b,P.En()),[null,null]))
-this.oV.V7("addRow",[H.VM(new P.Tz(z),[null])])},"call$1","gJW",2,0,null,508]},
+this.oV.V7("addRow",[H.VM(new P.Tz(z),[null])])},"call$1","gJW",2,0,null,489,[]]},
 qu:{
-"":"a;YZ,bG>",
+"^":"a;YZ,bG>",
 W2:[function(a){var z=P.jT(this.bG)
-this.YZ.V7("draw",[a.goV(),z])},"call$1","gW8",2,0,null,178]},
+this.YZ.V7("draw",[a.goV(),z])},"call$1","gW8",2,0,null,178,[]]},
 bv:{
-"":["Pi;WP,XR<-509,Z0<-510,md,mY,F3,Gg,LE<-511,a3,mU,mM,Td,AP,fn",null,function(){return[C.mI]},function(){return[C.mI]},null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
-gB1:[function(a){return this.WP},null,null,1,0,512,"profile",359,372],
-sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,513,23,"profile",359],
-gjO:[function(a){return this.md},null,null,1,0,369,"id",359,372],
-sjO:[function(a,b){this.md=F.Wi(this,C.EN,this.md,b)},null,null,3,0,25,23,"id",359],
-goc:[function(a){return this.mY},null,null,1,0,369,"name",359,372],
-soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,"name",359],
-gw2:[function(){return this.F3},null,null,1,0,358,"entry",359,372],
-sw2:[function(a){this.F3=F.Wi(this,C.tP,this.F3,a)},null,null,3,0,361,23,"entry",359],
-gVc:[function(){return this.Gg},null,null,1,0,369,"rootLib",359,372],
-sVc:[function(a){this.Gg=F.Wi(this,C.iG,this.Gg,a)},null,null,3,0,25,23,"rootLib",359],
-gS0:[function(){return this.a3},null,null,1,0,478,"newHeapUsed",359,372],
-sS0:[function(a){this.a3=F.Wi(this,C.IO,this.a3,a)},null,null,3,0,390,23,"newHeapUsed",359],
-gcu:[function(){return this.mU},null,null,1,0,478,"oldHeapUsed",359,372],
-scu:[function(a){this.mU=F.Wi(this,C.ap,this.mU,a)},null,null,3,0,390,23,"oldHeapUsed",359],
-gKu:[function(){return this.mM},null,null,1,0,358,"topFrame",359,372],
-sKu:[function(a){this.mM=F.Wi(this,C.ch,this.mM,a)},null,null,3,0,361,23,"topFrame",359],
-gNh:[function(a){return this.Td},null,null,1,0,369,"fileAndLine",359,372],
-bj:function(a,b){return this.gNh(a).call$1(b)},
-sNh:[function(a,b){this.Td=F.Wi(this,C.SK,this.Td,b)},null,null,3,0,25,23,"fileAndLine",359],
+"^":["Pi;WP,XR<-511,Z0<-512,md,mY,F3,rU,LE<-513,iP,mU,mM,Td,AP,fn",null,function(){return[C.mI]},function(){return[C.mI]},null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
+gB1:[function(a){return this.WP},null,null,1,0,514,"profile",351,365],
+sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,515,23,[],"profile",351],
+gjO:[function(a){return this.md},null,null,1,0,362,"id",351,365],
+sjO:[function(a,b){this.md=F.Wi(this,C.EN,this.md,b)},null,null,3,0,25,23,[],"id",351],
+goc:[function(a){return this.mY},null,null,1,0,362,"name",351,365],
+soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,[],"name",351],
+gw2:[function(){return this.F3},null,null,1,0,350,"entry",351,365],
+sw2:[function(a){this.F3=F.Wi(this,C.tP,this.F3,a)},null,null,3,0,353,23,[],"entry",351],
+gVc:[function(){return this.rU},null,null,1,0,362,"rootLib",351,365],
+sVc:[function(a){this.rU=F.Wi(this,C.iF,this.rU,a)},null,null,3,0,25,23,[],"rootLib",351],
+gCi:[function(){return this.iP},null,null,1,0,482,"newHeapUsed",351,365],
+sCi:[function(a){this.iP=F.Wi(this,C.IO,this.iP,a)},null,null,3,0,385,23,[],"newHeapUsed",351],
+guq:[function(){return this.mU},null,null,1,0,482,"oldHeapUsed",351,365],
+suq:[function(a){this.mU=F.Wi(this,C.ap,this.mU,a)},null,null,3,0,385,23,[],"oldHeapUsed",351],
+gKu:[function(){return this.mM},null,null,1,0,350,"topFrame",351,365],
+sKu:[function(a){this.mM=F.Wi(this,C.ch,this.mM,a)},null,null,3,0,353,23,[],"topFrame",351],
+gNh:[function(a){return this.Td},null,null,1,0,362,"fileAndLine",351,365],
+bj:function(a,b){return this.gNh(this).call$1(b)},
+sNh:[function(a,b){this.Td=F.Wi(this,C.SK,this.Td,b)},null,null,3,0,25,23,[],"fileAndLine",351],
 zr:[function(a){var z="/"+H.d(this.md)+"/"
-$.tE.lw.fB(z).ml(new L.eS(this)).OA(new L.IQ())},"call$0","gBq",0,0,null],
+$.tE.DF.fB(z).ml(new L.eS(this)).OA(new L.IQ())},"call$0","gBq",0,0,null],
 eC:[function(a){var z,y,x,w
 z=J.U6(a)
 if(!J.de(z.t(a,"type"),"Isolate")){N.Jx("").hh("Unexpected message type in Isolate.update: "+H.d(z.t(a,"type")))
@@ -18426,12 +18781,11 @@
 return}y=z.t(a,"name")
 this.mY=F.Wi(this,C.YS,this.mY,y)
 y=J.UQ(z.t(a,"rootLib"),"id")
-this.Gg=F.Wi(this,C.iG,this.Gg,y)
+this.rU=F.Wi(this,C.iF,this.rU,y)
 if(z.t(a,"entry")!=null){y=z.t(a,"entry")
 this.F3=F.Wi(this,C.tP,this.F3,y)}if(z.t(a,"topFrame")!=null){y=z.t(a,"topFrame")
 this.mM=F.Wi(this,C.ch,this.mM,y)}x=H.B7([],P.L5(null,null,null,null,null))
 J.kH(z.t(a,"timers"),new L.TI(x))
-P.JS(x)
 y=this.LE
 w=J.w1(y)
 w.u(y,"total",x.t(0,"time_total_runtime"))
@@ -18440,9 +18794,9 @@
 w.u(y,"init",J.WB(J.WB(J.WB(x.t(0,"time_script_loading"),x.t(0,"time_creating_snapshot")),x.t(0,"time_isolate_initialization")),x.t(0,"time_bootstrap")))
 w.u(y,"dart",x.t(0,"time_dart_execution"))
 y=J.UQ(z.t(a,"heap"),"usedNew")
-this.a3=F.Wi(this,C.IO,this.a3,y)
+this.iP=F.Wi(this,C.IO,this.iP,y)
 z=J.UQ(z.t(a,"heap"),"usedOld")
-this.mU=F.Wi(this,C.ap,this.mU,z)},"call$1","gpn",2,0,null,144],
+this.mU=F.Wi(this,C.ap,this.mU,z)},"call$1","gpn",2,0,null,144,[]],
 bu:[function(a){return H.d(this.md)},"call$0","gXo",0,0,null],
 hv:[function(a){var z,y,x,w
 z=this.Z0
@@ -18451,7 +18805,7 @@
 while(!0){w=y.gB(z)
 if(typeof w!=="number")return H.s(w)
 if(!(x<w))break
-if(J.kE(y.t(z,x),a)===!0)return y.t(z,x);++x}},"call$1","gSB",2,0,null,514],
+if(J.kE(y.t(z,x),a)===!0)return y.t(z,x);++x}return},"call$1","gSB",2,0,null,516,[]],
 R7:[function(){var z,y,x,w
 N.Jx("").To("Reset all code ticks.")
 z=this.Z0
@@ -18467,25 +18821,25 @@
 u=J.UQ(v.t(w,"script"),"id")
 t=x.t(y,u)
 if(t==null){t=L.Ak(v.t(w,"script"))
-x.u(y,u,t)}t.o6(v.t(w,"hits"))}},"call$1","gHY",2,0,null,515],
+x.u(y,u,t)}t.o6(v.t(w,"hits"))}},"call$1","gHY",2,0,null,517,[]],
 $isbv:true,
-static:{"":"tE?"}},
+static:{"^":"tE?"}},
 eS:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.eC(a)},"call$1",null,2,0,null,144,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.eC(a)},"call$1",null,2,0,null,144,[],"call"],
 $isEH:true},
 IQ:{
-"":"Tp:349;",
-call$2:[function(a,b){N.Jx("").hh("Error while updating isolate summary: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,null,18,516,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while updating isolate summary: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,null,18,[],472,[],"call"],
 $isEH:true},
 TI:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.U6(a)
-this.a.u(0,z.t(a,"name"),z.t(a,"time"))},"call$1",null,2,0,null,517,"call"],
+this.a.u(0,z.t(a,"name"),z.t(a,"time"))},"call$1",null,2,0,null,518,[],"call"],
 $isEH:true},
-pt:{
-"":["Pi;XT?,i2<-518,AP,fn",null,function(){return[C.mI]},null,null],
-Ou:[function(){J.kH(this.XT.lw.gjR(),new L.dY(this))},"call$0","gPI",0,0,107],
+yU:{
+"^":["Pi;XT?,i2<-519,AP,fn",null,function(){return[C.mI]},null,null],
+Ql:[function(){J.kH(this.XT.DF.gjR(),new L.dY(this))},"call$0","gPI",0,0,107],
 AQ:[function(a){var z,y,x,w,v,u
 z=this.i2
 y=J.U6(z)
@@ -18497,31 +18851,31 @@
 u=R.Jk(u)
 x=new L.bv(null,w,v,a,"",null,null,u,0,0,null,null,null,null)
 y.u(z,a,x)
-return x}return x},"call$1","grE",2,0,null,241],
+return x}return x},"call$1","grE",2,0,null,236,[]],
 N8:[function(a){var z=[]
 J.kH(this.i2,new L.vY(a,z))
 H.bQ(z,new L.zZ(this))
-J.kH(a,new L.dS(this))},"call$1","gajF",2,0,null,242],
-static:{AC:[function(a,b){return J.pb(b,new L.Ub(a))},"call$2","mc",4,0,null,241,242]}},
+J.kH(a,new L.dS(this))},"call$1","gajF",2,0,null,237,[]],
+static:{AC:[function(a,b){return J.pb(b,new L.Ub(a))},"call$2","mc",4,0,null,236,[],237,[]]}},
 Ub:{
-"":"Tp:229;a",
-call$1:[function(a){return J.de(J.UQ(a,"id"),this.a)},"call$1",null,2,0,null,519,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.de(J.UQ(a,"id"),this.a)},"call$1",null,2,0,null,520,[],"call"],
 $isEH:true},
 dY:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.U6(a)
-if(J.de(z.t(a,"type"),"IsolateList"))this.a.N8(z.t(a,"members"))},"call$1",null,2,0,null,470,"call"],
+if(J.de(z.t(a,"type"),"IsolateList"))this.a.N8(z.t(a,"members"))},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 vY:{
-"":"Tp:349;a,b",
-call$2:[function(a,b){if(L.AC(a,this.a)!==!0)this.b.push(a)},"call$2",null,4,0,null,421,277,"call"],
+"^":"Tp:341;a,b",
+call$2:[function(a,b){if(L.AC(a,this.a)!==!0)this.b.push(a)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 zZ:{
-"":"Tp:229;c",
-call$1:[function(a){J.V1(this.c.i2,a)},"call$1",null,2,0,null,241,"call"],
+"^":"Tp:223;c",
+call$1:[function(a){J.V1(this.c.i2,a)},"call$1",null,2,0,null,236,[],"call"],
 $isEH:true},
 dS:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z,y,x,w,v,u,t,s
 z=J.U6(a)
 y=z.t(a,"id")
@@ -18534,18 +18888,18 @@
 s=P.L5(null,null,null,J.O,J.GW)
 s=R.Jk(s)
 v=new L.bv(null,u,t,z.t(a,"id"),z.t(a,"name"),null,null,s,0,0,null,null,null,null)
-w.u(x,y,v)}J.KM(v)},"call$1",null,2,0,null,144,"call"],
+w.u(x,y,v)}J.KM(v)},"call$1",null,2,0,null,144,[],"call"],
 $isEH:true},
 dZ:{
-"":"Pi;XT?,WP,kg,UL,AP,fn",
-gB1:[function(a){return this.WP},null,null,1,0,373,"profile",359,372],
-sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,374,23,"profile",359],
-gb8:[function(){return this.kg},null,null,1,0,369,"currentHash",359,372],
-sb8:[function(a){this.kg=F.Wi(this,C.h1,this.kg,a)},null,null,3,0,25,23,"currentHash",359],
-gXX:[function(){return this.UL},null,null,1,0,520,"currentHashUri",359,372],
-sXX:[function(a){this.UL=F.Wi(this,C.tv,this.UL,a)},null,null,3,0,521,23,"currentHashUri",359],
+"^":"Pi;XT?,WP,kg,UL,AP,fn",
+gB1:[function(a){return this.WP},null,null,1,0,366,"profile",351,365],
+sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,367,23,[],"profile",351],
+gb8:[function(){return this.kg},null,null,1,0,362,"currentHash",351,365],
+sb8:[function(a){this.kg=F.Wi(this,C.h1,this.kg,a)},null,null,3,0,25,23,[],"currentHash",351],
+gXX:[function(){return this.UL},null,null,1,0,521,"currentHashUri",351,365],
+sXX:[function(a){this.UL=F.Wi(this,C.tv,this.UL,a)},null,null,3,0,522,23,[],"currentHashUri",351],
 kI:[function(){var z=C.PP.aM(window)
-H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new L.us(this)),z.Sg),[H.Kp(z,0)]).Zz()
+H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new L.Qe(this)),z.Sg),[H.Kp(z,0)]).Zz()
 if(!this.S7())this.df()},"call$0","gMz",0,0,null],
 vI:[function(){var z,y,x,w,v
 z=$.oy().R4(0,this.kg)
@@ -18558,91 +18912,121 @@
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
 return C.xB.Nj(x,w,v+y)},"call$0","gzJ",0,0,null],
-gwB:[function(){return this.vI()!=null},null,null,1,0,373,"hasCurrentIsolate",372],
+gwB:[function(){return this.vI()!=null},null,null,1,0,366,"hasCurrentIsolate",365],
 R6:[function(){var z=this.vI()
 if(z==null)return""
 return J.ZZ(z,2)},"call$0","gKo",0,0,null],
 Pr:[function(){var z=this.R6()
 if(z==="")return
 return this.XT.nI.AQ(z)},"call$0","gjf",0,0,null],
-S7:[function(){var z=J.ON(C.ol.gmW(window))
+S7:[function(){var z=J.Co(C.ol.gmW(window))
 z=F.Wi(this,C.h1,this.kg,z)
 this.kg=z
 if(J.de(z,"")||J.de(this.kg,"#")){J.We(C.ol.gmW(window),"#/isolates/")
 return!0}return!1},"call$0","goO",0,0,null],
 df:[function(){var z,y,x
-z=J.ON(C.ol.gmW(window))
+z=J.Co(C.ol.gmW(window))
 z=F.Wi(this,C.h1,this.kg,z)
 this.kg=z
 y=J.ZZ(z,1)
-z=P.r6($.cO().ej(y))
+z=P.r6($.qG().ej(y))
 this.UL=F.Wi(this,C.tv,this.UL,z)
 z=$.wf()
 x=this.kg
 z=z.Ej
 if(typeof x!=="string")H.vh(new P.AT(x))
 if(z.test(x))this.WP=F.Wi(this,C.vb,this.WP,!0)
-else{this.XT.lw.ox(y)
+else{this.XT.DF.ox(y)
 this.WP=F.Wi(this,C.vb,this.WP,!1)}},"call$0","glq",0,0,null],
 kP:[function(a){var z=this.R6()
-return"#/"+z+"/"+H.d(a)},"call$1","gVM",2,0,206,279,"currentIsolateRelativeLink",372],
-XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.xM,!1))},"call$1","gOs",2,0,206,522,"currentIsolateScriptLink",372],
-r4:[function(a,b){return"#/"+H.d(a)+"/"+H.d(b)},"call$2","gLc",4,0,523,524,279,"relativeLink",372],
-Lr:[function(a){return"#/"+H.d(a)},"call$1","geP",2,0,206,279,"absoluteLink",372],
-static:{"":"x4,K3D,qY,HT"}},
-us:{
-"":"Tp:229;a",
+return"#/"+z+"/"+H.d(a)},"call$1","gVM",2,0,504,274,[],"currentIsolateRelativeLink",365],
+XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.xM,!1))},"call$1","gOs",2,0,504,523,[],"currentIsolateScriptLink",365],
+r4:[function(a,b,c){return"#/"+H.d(b)+"/"+H.d(c)},"call$2","gLc",4,0,524,525,[],274,[],"relativeLink",365],
+da:[function(a){return"#/"+H.d(a)},"call$1","geP",2,0,504,274,[],"absoluteLink",365],
+static:{"^":"x4,YF,qY,HT"}},
+Qe:{
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 if(z.S7())return
 F.Wi(z,C.D2,z.vI()==null,z.vI()!=null)
-z.df()},"call$1",null,2,0,null,405,"call"],
+z.df()},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 DP:{
-"":["Pi;Yu<-476,m7<-371,L4<-371,Fv,ZZ,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null,null],
-ga0:[function(){return this.Fv},null,null,1,0,478,"ticks",359,372],
-sa0:[function(a){this.Fv=F.Wi(this,C.p1,this.Fv,a)},null,null,3,0,390,23,"ticks",359],
-gGK:[function(){return this.ZZ},null,null,1,0,525,"percent",359,372],
-sGK:[function(a){this.ZZ=F.Wi(this,C.tI,this.ZZ,a)},null,null,3,0,526,23,"percent",359],
+"^":["Pi;Yu<-475,m7<-364,L4<-364,Fv,ZZ,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null,null],
+ga0:[function(){return this.Fv},null,null,1,0,482,"ticks",351,365],
+sa0:[function(a){this.Fv=F.Wi(this,C.p1,this.Fv,a)},null,null,3,0,385,23,[],"ticks",351],
+gGK:[function(){return this.ZZ},null,null,1,0,526,"percent",351,365],
+sGK:[function(a){this.ZZ=F.Wi(this,C.tI,this.ZZ,a)},null,null,3,0,527,23,[],"percent",351],
 oS:[function(){var z=this.ZZ
 if(z==null||J.Hb(z,0))return""
-return J.Ez(this.ZZ,2)+"% ("+H.d(this.Fv)+")"},"call$0","gu3",0,0,369,"formattedTicks",372],
-xt:[function(){return"0x"+J.u1(this.Yu,16)},"call$0","gZd",0,0,369,"formattedAddress",372],
-E7:[function(a){var z
-if(a==null||J.de(a.gfF(),0)){this.ZZ=F.Wi(this,C.tI,this.ZZ,null)
-return}z=J.FW(this.Fv,a.gfF())
-z=F.Wi(this,C.tI,this.ZZ,z*100)
-this.ZZ=z
-if(J.Hb(z,0)){this.ZZ=F.Wi(this,C.tI,this.ZZ,null)
-return}},"call$1","gIH",2,0,null,136]},
+return J.Ez(this.ZZ,2)+"% ("+H.d(this.Fv)+")"},"call$0","gu3",0,0,362,"formattedTicks",365],
+xt:[function(){return"0x"+J.u1(this.Yu,16)},"call$0","gZd",0,0,362,"formattedAddress",365]},
 WAE:{
-"":"a;eg",
+"^":"a;eg",
 bu:[function(a){return"CodeKind."+this.eg},"call$0","gXo",0,0,null],
-static:{"":"j6,bS,WAg",CQ:[function(a){var z=J.x(a)
+static:{"^":"j6,pg,WAg",CQ:[function(a){var z=J.x(a)
 if(z.n(a,"Native"))return C.nj
 else if(z.n(a,"Dart"))return C.l8
 else if(z.n(a,"Collected"))return C.WA
-throw H.b(P.hS())},"call$1","Tx",2,0,null,86]}},
+throw H.b(P.hS())},"call$1","Tx",2,0,null,86,[]]}},
 N8:{
-"":"a;Yu<,a0<"},
+"^":"a;Yu<,z4,Iw"},
+Vi:{
+"^":"a;tT>,Ou<"},
 kx:{
-"":["Pi;fY>,vg,Mb,a0<,fF@,Du@,va<-527,Qo,kY,mY,Tl,AP,fn",null,null,null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
-gkx:[function(){return this.Qo},null,null,1,0,358,"functionRef",359,372],
-skx:[function(a){this.Qo=F.Wi(this,C.yg,this.Qo,a)},null,null,3,0,361,23,"functionRef",359],
-gZN:[function(){return this.kY},null,null,1,0,358,"codeRef",359,372],
-sZN:[function(a){this.kY=F.Wi(this,C.EX,this.kY,a)},null,null,3,0,361,23,"codeRef",359],
-goc:[function(a){return this.mY},null,null,1,0,369,"name",359,372],
-soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,"name",359],
-gBr:[function(){return this.Tl},null,null,1,0,369,"user_name",359,372],
-sBr:[function(a){this.Tl=F.Wi(this,C.wj,this.Tl,a)},null,null,3,0,25,23,"user_name",359],
+"^":["Pi;fY>,vg,Mb,a0<,VS<,hw,fF<,Du<,va<-528,Qo,uP,mY,B0,AP,fn",null,null,null,null,null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
+gkx:[function(){return this.Qo},null,null,1,0,350,"functionRef",351,365],
+skx:[function(a){this.Qo=F.Wi(this,C.yg,this.Qo,a)},null,null,3,0,353,23,[],"functionRef",351],
+gZN:[function(){return this.uP},null,null,1,0,350,"codeRef",351,365],
+sZN:[function(a){this.uP=F.Wi(this,C.EX,this.uP,a)},null,null,3,0,353,23,[],"codeRef",351],
+goc:[function(a){return this.mY},null,null,1,0,362,"name",351,365],
+soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,[],"name",351],
+giK:[function(){return this.B0},null,null,1,0,362,"userName",351,365],
+siK:[function(a){this.B0=F.Wi(this,C.ct,this.B0,a)},null,null,3,0,25,23,[],"userName",351],
+Ne:[function(a,b){var z,y,x,w,v,u,t
+z=J.U6(b)
+this.fF=H.BU(z.t(b,"inclusive_ticks"),null,null)
+this.Du=H.BU(z.t(b,"exclusive_ticks"),null,null)
+y=z.t(b,"ticks")
+if(y!=null&&J.z8(J.q8(y),0)){z=J.U6(y)
+x=this.a0
+w=0
+while(!0){v=z.gB(y)
+if(typeof v!=="number")return H.s(v)
+if(!(w<v))break
+u=H.BU(z.t(y,w),16,null)
+t=H.BU(z.t(y,w+1),null,null)
+x.push(new L.N8(u,H.BU(z.t(y,w+2),null,null),t))
+w+=3}}},"call$1","gK0",2,0,null,144,[]],
+QQ:[function(){return this.fs(this.VS)},"call$0","gyj",0,0,null],
+dJ:[function(a){return this.U8(this.VS,a)},"call$1","gf7",2,0,null,136,[]],
+fs:[function(a){var z,y,x
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]),y=0;z.G();){x=z.lo.gOu()
+if(typeof x!=="number")return H.s(x)
+y+=x}return y},"call$1","gJ6",2,0,null,529,[]],
+U8:[function(a,b){var z,y
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();){y=z.lo
+if(J.de(J.on(y),b))return y.gOu()}return 0},"call$2","gGp",4,0,null,529,[],136,[]],
+hI:[function(a,b){var z=J.U6(a)
+this.GV(this.VS,z.t(a,"callers"),b)
+this.GV(this.hw,z.t(a,"callees"),b)},"call$2","gL0",4,0,null,136,[],530,[]],
+GV:[function(a,b,c){var z,y,x,w,v
+C.Nm.sB(a,0)
+z=J.U6(b)
+y=0
+while(!0){x=z.gB(b)
+if(typeof x!=="number")return H.s(x)
+if(!(y<x))break
+w=H.BU(z.t(b,y),null,null)
+v=H.BU(z.t(b,y+1),null,null)
+if(w>>>0!==w||w>=c.length)return H.e(c,w)
+a.push(new L.Vi(c[w],v))
+y+=2}H.ZE(a,0,a.length-1,new L.fx())},"call$3","gI1",6,0,null,529,[],231,[],530,[]],
 FB:[function(){this.fF=0
 this.Du=0
 C.Nm.sB(this.a0,0)
 for(var z=J.GP(this.va);z.G();)z.gl().sa0(0)},"call$0","gNB",0,0,null],
-xa:[function(a,b){var z,y
-for(z=J.GP(this.va);z.G();){y=z.gl()
-if(J.de(y.gYu(),a)){y.sa0(J.WB(y.ga0(),b))
-return}}},"call$2","gXO",4,0,null,514,122],
-Pi:[function(a){var z,y,x,w,v
+fo:[function(a){var z,y,x,w,v
 z=this.va
 y=J.w1(z)
 y.V1(z)
@@ -18652,142 +19036,128 @@
 if(typeof v!=="number")return H.s(v)
 if(!(w<v))break
 c$0:{if(J.de(x.t(a,w),""))break c$0
-y.h(z,new L.DP(H.BU(x.t(a,w),null,null),x.t(a,w+1),x.t(a,w+2),0,null,null,null))}w+=3}},"call$1","gwj",2,0,null,528],
+y.h(z,new L.DP(H.BU(x.t(a,w),null,null),x.t(a,w+1),x.t(a,w+2),0,null,null,null))}w+=3}},"call$1","gwj",2,0,null,531,[]],
 tg:[function(a,b){var z=J.Wx(b)
-return z.F(b,this.vg)&&z.C(b,this.Mb)},"call$1","gdj",2,0,null,514],
+return z.F(b,this.vg)&&z.C(b,this.Mb)},"call$1","gdj",2,0,null,516,[]],
 NV:function(a){var z,y
 z=J.U6(a)
 y=z.t(a,"function")
 y=R.Jk(y)
 this.Qo=F.Wi(this,C.yg,this.Qo,y)
 y=H.B7(["type","@Code","id",z.t(a,"id"),"name",z.t(a,"name"),"user_name",z.t(a,"user_name")],P.L5(null,null,null,null,null))
-this.kY=F.Wi(this,C.EX,this.kY,y)
+y=R.Jk(y)
+this.uP=F.Wi(this,C.EX,this.uP,y)
 y=z.t(a,"name")
 this.mY=F.Wi(this,C.YS,this.mY,y)
 y=z.t(a,"user_name")
-this.Tl=F.Wi(this,C.wj,this.Tl,y)
-this.Pi(z.t(a,"disassembly"))},
-$iskx:true,
-static:{Hj:function(a){var z,y,x,w
-z=R.Jk([])
-y=H.B7([],P.L5(null,null,null,null,null))
-y=R.Jk(y)
-x=H.B7([],P.L5(null,null,null,null,null))
-x=R.Jk(x)
-w=J.U6(a)
-x=new L.kx(C.l8,H.BU(w.t(a,"start"),16,null),H.BU(w.t(a,"end"),16,null),[],0,0,z,y,x,null,null,null,null)
-x.NV(a)
-return x}}},
+this.B0=F.Wi(this,C.ct,this.B0,y)
+if(z.t(a,"disassembly")!=null)this.fo(z.t(a,"disassembly"))},
+$iskx:true},
+fx:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.xH(b.gOu(),a.gOu())},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
 CM:{
-"":"a;Aq>,hV<",
-qy:[function(a){var z=J.UQ(a,"code")
-if(z==null)return this.LV(C.l8,a)
-return L.Hj(z)},"call$1","gS5",2,0,null,529],
-LV:[function(a,b){var z,y,x,w,v,u
-z=J.U6(b)
-y=H.BU(z.t(b,"start"),16,null)
-x=H.BU(z.t(b,"end"),16,null)
-w=z.t(b,"name")
-z=R.Jk([])
-v=H.B7([],P.L5(null,null,null,null,null))
-v=R.Jk(v)
-u=H.B7([],P.L5(null,null,null,null,null))
-u=R.Jk(u)
-return new L.kx(a,y,x,[],0,0,z,v,u,w,null,null,null)},"call$2","gAH",4,0,null,530,531],
-U5:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
-z={}
-y=J.U6(a)
-if(!J.de(y.t(a,"type"),"ProfileCode"))return
-x=L.CQ(y.t(a,"kind"))
-w=x===C.l8
-if(w)v=y.t(a,"code")!=null?H.BU(J.UQ(y.t(a,"code"),"start"),16,null):H.BU(y.t(a,"start"),16,null)
-else v=H.BU(y.t(a,"start"),16,null)
-u=this.Aq
-t=u.hv(v)
-z.a=t
-if(t==null){if(w)z.a=this.qy(a)
-else z.a=this.LV(x,a)
-J.bi(u.gZ0(),z.a)}s=H.BU(y.t(a,"inclusive_ticks"),null,null)
-r=H.BU(y.t(a,"exclusive_ticks"),null,null)
-z.a.sfF(s)
-z.a.sDu(r)
-q=y.t(a,"ticks")
-if(q!=null&&J.z8(J.q8(q),0)){y=J.U6(q)
-p=0
-while(!0){w=y.gB(q)
-if(typeof w!=="number")return H.s(w)
-if(!(p<w))break
-v=H.BU(y.t(q,p),16,null)
-o=H.BU(y.t(q,p+1),null,null)
-J.bi(z.a.ga0(),new L.N8(v,o))
-p+=2}}if(J.z8(J.q8(z.a.ga0()),0)&&J.z8(J.q8(z.a.gva()),0)){J.kH(z.a.ga0(),new L.ct(z))
-J.kH(z.a.gva(),new L.hM(z))}},"call$1","gu5",2,0,null,532],
+"^":"a;Aq>,jV,hV<",
+vD:[function(a){var z=J.U6(a)
+if(L.CQ(z.t(a,"kind"))===C.l8&&z.t(a,"code")!=null)return H.BU(J.UQ(z.t(a,"code"),"start"),16,null)
+return H.BU(z.t(a,"start"),16,null)},"call$1","gRU",2,0,null,136,[]],
+U5:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
+z=J.U6(a)
+if(!J.de(z.t(a,"type"),"ProfileCode"))return
+y=this.Aq
+x=y.hv(this.vD(a))
+if(x==null){w=L.CQ(z.t(a,"kind"))
+if(w===C.l8){x=z.t(a,"code")
+if(x!=null){v=J.U6(x)
+u=H.BU(v.t(x,"start"),16,null)
+t=H.BU(v.t(x,"end"),16,null)
+s=v.t(x,"name")
+r=v.t(x,"user_name")
+q=H.B7(["type","@Code","id",v.t(x,"id"),"name",s,"user_name",r],P.L5(null,null,null,null,null))
+p=R.Jk(q)
+v=v.t(x,"function")
+o=R.Jk(v)}else{u=null
+t=null
+s=null
+r=null
+p=null
+o=null}}else{u=null
+t=null
+s=null
+r=null
+p=null
+o=null}if(u==null){u=H.BU(z.t(a,"start"),16,null)
+t=H.BU(z.t(a,"end"),16,null)
+s=z.t(a,"name")
+r=s}v=R.Jk([])
+q=H.B7([],P.L5(null,null,null,null,null))
+q=R.Jk(q)
+n=H.B7([],P.L5(null,null,null,null,null))
+n=R.Jk(n)
+x=new L.kx(w,u,t,[],[],[],0,0,v,q,n,s,null,null,null)
+x.uP=F.Wi(x,C.EX,n,p)
+x.Qo=F.Wi(x,C.yg,x.Qo,o)
+x.B0=F.Wi(x,C.ct,x.B0,r)
+if(z.t(a,"disassembly")!=null)x.fo(z.t(a,"disassembly"))
+J.bi(y.gZ0(),x)}J.eh(x,a)
+this.jV.push(x)},"call$1","gu5",2,0,null,532,[]],
 T0:[function(a){var z,y
 z=this.Aq.gZ0()
 y=J.w1(z)
-y.So(z,new L.vu())
+y.GT(z,new L.vu())
 if(J.u6(y.gB(z),a)||J.de(a,0))return z
-return y.D6(z,0,a)},"call$1","gy8",2,0,null,122],
-hg:[function(a){var z,y
-z=this.Aq.gZ0()
-y=J.w1(z)
-y.So(z,new L.Ja())
-if(J.u6(y.gB(z),a)||J.de(a,0))return z
-return y.D6(z,0,a)},"call$1","geI",2,0,null,122],
-uH:function(a,b){var z,y
+return y.D6(z,0,a)},"call$1","gy8",2,0,null,122,[]],
+uH:function(a,b){var z,y,x,w,v
 z=J.U6(b)
 y=z.t(b,"codes")
 this.hV=z.t(b,"samples")
 z=J.U6(y)
 N.Jx("").To("Creating profile from "+H.d(this.hV)+" samples and "+H.d(z.gB(y))+" code objects.")
 this.Aq.R7()
-z.aN(y,new L.xn(this))},
-static:{hh:function(a,b){var z=new L.CM(a,0)
+x=this.jV
+C.Nm.sB(x,0)
+z.aN(y,new L.xn(this))
+w=0
+while(!0){v=z.gB(y)
+if(typeof v!=="number")return H.s(v)
+if(!(w<v))break
+if(w>=x.length)return H.e(x,w)
+x[w].hI(z.t(y,w),x);++w}C.Nm.sB(x,0)},
+static:{hh:function(a,b){var z=new L.CM(a,H.VM([],[L.kx]),0)
 z.uH(a,b)
 return z}}},
 xn:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w
 try{this.a.U5(a)}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-N.Jx("").xH("Error processing code object. "+H.d(z)+" "+H.d(y),z,y)}},"call$1",null,2,0,null,136,"call"],
-$isEH:true},
-ct:{
-"":"Tp:534;a",
-call$1:[function(a){this.a.a.xa(a.gYu(),a.ga0())},"call$1",null,2,0,null,533,"call"],
-$isEH:true},
-hM:{
-"":"Tp:229;a",
-call$1:[function(a){a.E7(this.a.a)},"call$1",null,2,0,null,341,"call"],
+N.Jx("").xH("Error processing code object. "+H.d(z)+" "+H.d(y),z,y)}},"call$1",null,2,0,null,136,[],"call"],
 $isEH:true},
 vu:{
-"":"Tp:535;",
-call$2:[function(a,b){return J.xH(b.gDu(),a.gDu())},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-Ja:{
-"":"Tp:535;",
-call$2:[function(a,b){return J.xH(b.gfF(),a.gfF())},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:533;",
+call$2:[function(a,b){return J.xH(b.gDu(),a.gDu())},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 c2:{
-"":["Pi;Rd<-476,eB,P2,AP,fn",function(){return[C.mI]},null,null,null,null],
-gu9:[function(){return this.eB},null,null,1,0,478,"hits",359,372],
-su9:[function(a){this.eB=F.Wi(this,C.K7,this.eB,a)},null,null,3,0,390,23,"hits",359],
-ga4:[function(a){return this.P2},null,null,1,0,369,"text",359,372],
-sa4:[function(a,b){this.P2=F.Wi(this,C.MB,this.P2,b)},null,null,3,0,25,23,"text",359],
+"^":["Pi;Rd>-475,eB,P2,AP,fn",function(){return[C.mI]},null,null,null,null],
+gu9:[function(){return this.eB},null,null,1,0,482,"hits",351,365],
+su9:[function(a){this.eB=F.Wi(this,C.K7,this.eB,a)},null,null,3,0,385,23,[],"hits",351],
+ga4:[function(a){return this.P2},null,null,1,0,362,"text",351,365],
+sa4:[function(a,b){this.P2=F.Wi(this,C.MB,this.P2,b)},null,null,3,0,25,23,[],"text",351],
 goG:function(){return J.J5(this.eB,0)},
 gVt:function(){return J.z8(this.eB,0)},
 $isc2:true},
 rj:{
-"":["Pi;W6,xN,Hz,Sw<-536,UK,AP,fn",null,null,null,function(){return[C.mI]},null,null,null],
-gfY:[function(a){return this.W6},null,null,1,0,369,"kind",359,372],
-sfY:[function(a,b){this.W6=F.Wi(this,C.fy,this.W6,b)},null,null,3,0,25,23,"kind",359],
-gKC:[function(){return this.xN},null,null,1,0,358,"scriptRef",359,372],
-sKC:[function(a){this.xN=F.Wi(this,C.Be,this.xN,a)},null,null,3,0,361,23,"scriptRef",359],
-gBi:[function(){return this.Hz},null,null,1,0,358,"libraryRef",359,372],
-sBi:[function(a){this.Hz=F.Wi(this,C.cg,this.Hz,a)},null,null,3,0,361,23,"libraryRef",359],
+"^":["Pi;W6,xN,Hz,Sw<-534,UK,AP,fn",null,null,null,function(){return[C.mI]},null,null,null],
+gfY:[function(a){return this.W6},null,null,1,0,362,"kind",351,365],
+sfY:[function(a,b){this.W6=F.Wi(this,C.fy,this.W6,b)},null,null,3,0,25,23,[],"kind",351],
+gKC:[function(){return this.xN},null,null,1,0,350,"scriptRef",351,365],
+sKC:[function(a){this.xN=F.Wi(this,C.Be,this.xN,a)},null,null,3,0,353,23,[],"scriptRef",351],
+gBi:[function(){return this.Hz},null,null,1,0,350,"libraryRef",351,365],
+sBi:[function(a){this.Hz=F.Wi(this,C.cg,this.Hz,a)},null,null,3,0,353,23,[],"libraryRef",351],
 giI:function(){return this.UK},
-gX4:[function(){return J.Pr(this.Sw,1)},null,null,1,0,537,"linesForDisplay",372],
+gX4:[function(){return J.Pr(this.Sw,1)},null,null,1,0,535,"linesForDisplay",365],
 Av:[function(a){var z,y,x,w
 z=this.Sw
 y=J.U6(z)
@@ -18795,16 +19165,16 @@
 if(x.F(a,y.gB(z)))y.sB(z,x.g(a,1))
 w=y.t(z,a)
 if(w==null){w=new L.c2(a,-1,"",null,null)
-y.u(z,a,w)}return w},"call$1","gKN",2,0,null,538],
+y.u(z,a,w)}return w},"call$1","gKN",2,0,null,536,[]],
 lu:[function(a){var z,y,x,w
 if(a==null)return
 N.Jx("").To("Loading source for "+H.d(J.UQ(this.xN,"name")))
-z=J.Gn(a,"\n")
+z=J.uH(a,"\n")
 this.UK=z.length===0
 for(y=0;y<z.length;y=x){x=y+1
 w=this.Av(x)
 if(y>=z.length)return H.e(z,y)
-J.c9(w,z[y])}},"call$1","ghH",2,0,null,27],
+J.c9(w,z[y])}},"call$1","ghH",2,0,null,27,[]],
 o6:[function(a){var z,y,x
 z=J.U6(a)
 y=0
@@ -18812,14 +19182,14 @@
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
 this.Av(z.t(a,y)).su9(z.t(a,y+1))
-y+=2}F.Wi(this,C.C2,"","("+C.CD.yM(this.Nk(),1)+"% covered)")},"call$1","gpc",2,0,null,539],
+y+=2}F.Wi(this,C.C2,"","("+C.CD.yM(this.Nk(),1)+"% covered)")},"call$1","gpc",2,0,null,537,[]],
 Nk:[function(){var z,y,x,w
 for(z=J.GP(this.Sw),y=0,x=0;z.G();){w=z.gl()
 if(w==null)continue
 if(!w.goG())continue;++x
 if(!w.gVt())continue;++y}if(x===0)return 0
-return y/x*100},"call$0","gUO",0,0,525,"coveredPercentage",372],
-nZ:[function(){return"("+C.CD.yM(this.Nk(),1)+"% covered)"},"call$0","gic",0,0,369,"coveredPercentageFormatted",372],
+return y/x*100},"call$0","gCx",0,0,526,"coveredPercentage",365],
+nZ:[function(){return"("+C.CD.yM(this.Nk(),1)+"% covered)"},"call$0","gic",0,0,362,"coveredPercentageFormatted",365],
 Ea:function(a){var z,y
 z=J.U6(a)
 y=H.B7(["id",z.t(a,"id"),"name",z.t(a,"name"),"user_name",z.t(a,"user_name")],P.L5(null,null,null,null,null))
@@ -18842,42 +19212,42 @@
 x=new L.rj(null,z,y,x,!0,null,null)
 x.Ea(a)
 return x}}},
-R2:{
-"":"Pi;XT?,e0?",
+Nu:{
+"^":"Pi;XT?,e0?",
 pG:function(){return this.e0.call$0()},
-gIw:[function(){return this.SI},null,null,1,0,369,"prefix",359,372],
-sIw:[function(a){this.SI=F.Wi(this,C.NA,this.SI,a)},null,null,3,0,25,23,"prefix",359],
-gjR:[function(){return this.Tj},null,null,1,0,498,"responses",359,372],
-sjR:[function(a){this.Tj=F.Wi(this,C.wH,this.Tj,a)},null,null,3,0,540,23,"responses",359],
+geG:[function(){return this.SI},null,null,1,0,362,"prefix",351,365],
+seG:[function(a){this.SI=F.Wi(this,C.qb3,this.SI,a)},null,null,3,0,25,23,[],"prefix",351],
+gjR:[function(){return this.Tj},null,null,1,0,501,"responses",351,365],
+sjR:[function(a){this.Tj=F.Wi(this,C.wH,this.Tj,a)},null,null,3,0,538,23,[],"responses",351],
 FH:[function(a){var z,y,x,w,v
 z=null
-try{z=C.lM.kV(a)}catch(w){v=H.Ru(w)
+try{z=C.xr.kV(a)}catch(w){v=H.Ru(w)
 y=v
 x=new H.XO(w,null)
-this.AI(H.d(y)+" "+H.d(x))}return z},"call$1","gkJ",2,0,null,470],
+this.AI(H.d(y)+" "+H.d(x))}return z},"call$1","gkJ",2,0,null,466,[]],
 f3:[function(a){var z,y
 z=this.FH(a)
 if(z==null)return
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)this.dq([z])
-else this.dq(z)},"call$1","gER",2,0,null,541],
+else this.dq(z)},"call$1","gt7",2,0,null,539,[]],
 dq:[function(a){var z=R.Jk(a)
 this.Tj=F.Wi(this,C.wH,this.Tj,z)
-if(this.e0!=null)this.pG()},"call$1","gvw",2,0,null,375],
+if(this.e0!=null)this.pG()},"call$1","gvw",2,0,null,368,[]],
 AI:[function(a){this.dq([H.B7(["type","Error","errorType","ResponseError","text",a],P.L5(null,null,null,null,null))])
-N.Jx("").hh(a)},"call$1","gug",2,0,null,20],
+N.Jx("").hh(a)},"call$1","gug",2,0,null,20,[]],
 Uu:[function(a){var z,y,x,w,v
 z=L.Lw(a)
 if(z==null){this.AI(z+" is not an isolate id.")
 return}y=this.XT.nI.AQ(z)
 if(y==null){this.AI(z+" could not be found.")
-return}x=L.TK(a)
+return}x=L.CX(a)
 w=J.x(x)
 if(w.n(x,0)){this.AI(a+" is not a valid code request.")
 return}v=y.hv(x)
 if(v!=null){N.Jx("").To("Found code with 0x"+w.WZ(x,16)+" in isolate.")
 this.dq([H.B7(["type","Code","code",v],P.L5(null,null,null,null,null))])
-return}this.ym(0,a).ml(new L.Q4(this,y,x)).OA(this.gSC())},"call$1","gVB",2,0,null,542],
+return}this.ym(0,a).ml(new L.Q4(this,y,x)).OA(this.gSC())},"call$1","gVB",2,0,null,540,[]],
 GY:[function(a){var z,y,x,w,v
 z=L.Lw(a)
 if(z==null){this.AI(z+" is not an isolate id.")
@@ -18890,61 +19260,68 @@
 if(v&&!w.giI()){N.Jx("").To("Found script "+H.d(J.UQ(w.gKC(),"name"))+" in isolate")
 this.dq([H.B7(["type","Script","script",w],P.L5(null,null,null,null,null))])
 return}if(v){this.fB(a).ml(new L.aJ(this,w))
-return}this.fB(a).ml(new L.u4(this,y,x))},"call$1","gPc",2,0,null,542],
-fs:[function(a,b){var z,y,x
+return}this.fB(a).ml(new L.u4(this,y,x))},"call$1","gPc",2,0,null,540,[]],
+xl:[function(a,b){var z,y,x
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isew){z=W.qc(a.target)
 y=J.RE(z)
 x=H.d(y.gys(z))+" "+y.gpo(z)
 if(y.gys(z)===0)x="No service found. Did you run with --enable-vm-service ?"
-this.dq([H.B7(["type","Error","errorType","RequestError","text",x],P.L5(null,null,null,null,null))])}else this.AI(H.d(a)+" "+H.d(b))},"call$2","gSC",4,0,543,18,472],
+this.dq([H.B7(["type","Error","errorType","RequestError","text",x],P.L5(null,null,null,null,null))])}else this.AI(H.d(a)+" "+H.d(b))},"call$2","gSC",4,0,541,18,[],468,[]],
 ox:[function(a){var z=$.mE().Ej
 if(z.test(a)){this.Uu(a)
 return}z=$.Ww().Ej
 if(z.test(a)){this.GY(a)
-return}this.ym(0,a).ml(new L.pF(this)).OA(this.gSC())},"call$1","gRD",2,0,null,542],
-fB:[function(a){return this.ym(0,a).ml(new L.Q2())},"call$1","gHi",2,0,null,542]},
+return}this.ym(0,a).ml(new L.pF(this)).OA(this.gSC())},"call$1","gRD",2,0,null,540,[]],
+fB:[function(a){return this.ym(0,C.xB.nC(a,"#")?C.xB.yn(a,1):a).ml(new L.Q2())},"call$1","gHi",2,0,null,540,[]]},
 Q4:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){var z,y,x
+"^":"Tp:223;a,b,c",
+call$1:[function(a){var z,y,x,w,v,u,t
 z=this.a
 y=z.FH(a)
 if(y==null)return
-x=L.Hj(y)
+x=R.Jk([])
+w=H.B7([],P.L5(null,null,null,null,null))
+w=R.Jk(w)
+v=H.B7([],P.L5(null,null,null,null,null))
+v=R.Jk(v)
+u=J.U6(y)
+t=new L.kx(C.l8,H.BU(u.t(y,"start"),16,null),H.BU(u.t(y,"end"),16,null),[],[],[],0,0,x,w,v,null,null,null,null)
+t.NV(y)
 N.Jx("").To("Added code with 0x"+J.u1(this.c,16)+" to isolate.")
-J.bi(this.b.gZ0(),x)
-z.dq([H.B7(["type","Code","code",x],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,541,"call"],
+J.bi(this.b.gZ0(),t)
+z.dq([H.B7(["type","Code","code",t],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,539,[],"call"],
 $isEH:true},
 aJ:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=this.b
 z.lu(J.UQ(a,"source"))
 N.Jx("").To("Grabbed script "+H.d(J.UQ(z.gKC(),"name"))+" source.")
-this.a.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,470,"call"],
+this.a.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 u4:{
-"":"Tp:229;c,d,e",
+"^":"Tp:223;c,d,e",
 call$1:[function(a){var z=L.Ak(a)
 N.Jx("").To("Added script "+H.d(J.UQ(z.xN,"name"))+" to isolate.")
 this.c.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])
-J.kW(this.d.gXR(),this.e,z)},"call$1",null,2,0,null,470,"call"],
+J.kW(this.d.gXR(),this.e,z)},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 pF:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.f3(a)},"call$1",null,2,0,null,541,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.f3(a)},"call$1",null,2,0,null,539,[],"call"],
 $isEH:true},
 Q2:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z,y
-try{z=C.lM.kV(a)
-return z}catch(y){H.Ru(y)}return},"call$1",null,2,0,null,470,"call"],
+try{z=C.xr.kV(a)
+return z}catch(y){H.Ru(y)}return},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
-tb:{
-"":"R2;XT,e0,SI,Tj,AP,fn",
+r1:{
+"^":"Nu;XT,e0,SI,Tj,AP,fn",
 ym:[function(a,b){N.Jx("").To("Requesting "+b)
-return W.It(J.WB(this.SI,b),null,null)},"call$1","gkq",2,0,null,542]},
+return W.It(J.WB(this.SI,b),null,null)},"call$1","gkq",2,0,null,540,[]]},
 Rb:{
-"":"R2;eA,Wj,XT,e0,SI,Tj,AP,fn",
+"^":"Nu;eA,Wj,XT,e0,SI,Tj,AP,fn",
 AJ:[function(a){var z,y,x,w,v
 z=J.RE(a)
 y=J.UQ(z.gRn(a),"id")
@@ -18955,7 +19332,7 @@
 v=z.t(0,y)
 if(v!=null){z.Rz(0,y)
 P.JS("Completing "+H.d(y))
-J.Xf(v,w)}else P.JS("Could not find completer for "+H.d(y))},"call$1","gpJ",2,0,152,19],
+J.Xf(v,w)}else P.JS("Could not find completer for "+H.d(y))},"call$1","gpJ",2,0,150,19,[]],
 ym:[function(a,b){var z,y,x
 z=""+this.Wj
 y=H.B7([],P.L5(null,null,null,null,null))
@@ -18965,14 +19342,64 @@
 this.Wj=this.Wj+1
 x=H.VM(new P.Zf(P.Dt(null)),[null])
 this.eA.u(0,z,x)
-J.Ih(W.Pv(window.parent),C.lM.KP(y),"*")
-return x.MM},"call$1","gkq",2,0,null,542]}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{
-"":"",
+J.Ih(W.Pv(window.parent),C.xr.KP(y),"*")
+return x.MM},"call$1","gkq",2,0,null,540,[]]},
+Y2:{
+"^":["Pi;eT>,yt<-475,wd>-476,oH<-477",null,function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]}],
+goE:function(a){return this.np},
+soE:function(a,b){var z=this.np
+this.np=b
+if(z!==b)if(b)this.C4(0)
+else this.o8()},
+r8:[function(){this.soE(0,!this.np)
+return this.np},"call$0","gMk",0,0,null],
+$isY2:true},
+XN:{
+"^":["Pi;JL,WT>-476,AP,fn",null,function(){return[C.mI]},null,null],
+rT:[function(a){var z,y
+z=this.WT
+y=J.w1(z)
+y.V1(z)
+y.FV(z,a)},"call$1","gE3",2,0,null,542,[]],
+qU:[function(a){var z,y,x
+P.JS(a)
+z=this.WT
+y=J.U6(z)
+P.JS(y.gB(z))
+x=y.t(z,a)
+if(x.r8())this.ad(x)
+else this.cB(x)
+P.JS("e")},"call$1","gMk",2,0,null,543,[]],
+ad:[function(a){var z,y,x,w,v,u,t
+z=this.WT
+y=J.U6(z)
+x=y.u8(z,a)
+w=J.RE(a)
+v=0
+while(!0){u=J.q8(w.gwd(a))
+if(typeof u!=="number")return H.s(u)
+if(!(v<u))break
+u=x+v+1
+t=J.UQ(w.gwd(a),v)
+if(u===-1)y.h(z,t)
+else y.xe(z,u,t);++v}},"call$1","ghF",2,0,null,489,[]],
+cB:[function(a){var z,y,x,w,v
+z=J.RE(a)
+y=J.q8(z.gwd(a))
+if(J.de(y,0))return
+if(typeof y!=="number")return H.s(y)
+x=0
+for(;x<y;++x)if(J.YV(J.UQ(z.gwd(a),x))===!0)this.cB(J.UQ(z.gwd(a),x))
+z.soE(a,!1)
+z=this.WT
+w=J.U6(z)
+for(v=w.u8(z,a)+1,x=0;x<y;++x)w.KI(z,v)},"call$1","gjc",2,0,null,489,[]]}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{
+"^":"",
 F1:{
-"":["V11;k5%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gzj:[function(a){return a.k5},null,null,1,0,373,"devtools",359,360],
-szj:[function(a,b){a.k5=this.ct(a,C.Na,a.k5,b)},null,null,3,0,374,23,"devtools",359],
-te:[function(a){var z,y
+"^":["V12;k5%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gzj:[function(a){return a.k5},null,null,1,0,366,"devtools",351,352],
+szj:[function(a,b){a.k5=this.ct(a,C.Na,a.k5,b)},null,null,3,0,367,23,[],"devtools",351],
+ZB:[function(a){var z,y
 if(a.k5===!0){z=P.L5(null,null,null,null,null)
 y=R.Jk([])
 y=new L.Rb(z,0,null,null,"http://127.0.0.1:8181",y,null,null)
@@ -18980,12 +19407,12 @@
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(y.gpJ()),z.Sg),[H.Kp(z,0)]).Zz()
 z=P.L5(null,null,null,J.O,L.bv)
 z=R.Jk(z)
-z=new L.mL(new L.dZ(null,!1,"",null,null,null),y,new L.pt(null,z,null,null),null,null)
+z=new L.mL(new L.dZ(null,!1,"",null,null,null),y,new L.yU(null,z,null,null),null,null)
 z.hq()
 a.hm=this.ct(a,C.wh,a.hm,z)}else{z=R.Jk([])
 y=P.L5(null,null,null,J.O,L.bv)
 y=R.Jk(y)
-y=new L.mL(new L.dZ(null,!1,"",null,null,null),new L.tb(null,null,"http://127.0.0.1:8181",z,null,null),new L.pt(null,y,null,null),null,null)
+y=new L.mL(new L.dZ(null,!1,"",null,null,null),new L.r1(null,null,"http://127.0.0.1:8181",z,null,null),new L.yU(null,y,null,null),null,null)
 y.US()
 a.hm=this.ct(a,C.wh,a.hm,y)}},null,null,0,0,108,"created"],
 "@":function(){return[C.y2]},
@@ -18998,25 +19425,25 @@
 a.k5=!1
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.k0.ZL(a)
-C.k0.oX(a)
-C.k0.te(a)
-return a},null,null,0,0,108,"new ObservatoryApplicationElement$created" /* new ObservatoryApplicationElement$created:0:0 */]}},
+C.k0.G6(a)
+C.k0.ZB(a)
+return a},null,null,0,0,108,"new ObservatoryApplicationElement$created"]}},
 "+ObservatoryApplicationElement":[544],
-V11:{
-"":"uL+Pi;",
+V12:{
+"^":"uL+Pi;",
 $isd3:true}}],["observatory_element","package:observatory/src/observatory_elements/observatory_element.dart",,Z,{
-"":"",
+"^":"",
 uL:{
-"":["LP;hm%-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["LP;hm%-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 i4:[function(a){A.zs.prototype.i4.call(this,a)},"call$0","gQd",0,0,107,"enteredView"],
 xo:[function(a){A.zs.prototype.xo.call(this,a)},"call$0","gbt",0,0,107,"leftView"],
-aC:[function(a,b,c,d){A.zs.prototype.aC.call(this,a,b,c,d)},"call$3","gxR",6,0,545,12,231,232,"attributeChanged"],
-guw:[function(a){return a.hm},null,null,1,0,546,"app",359,360],
-suw:[function(a,b){a.hm=this.ct(a,C.wh,a.hm,b)},null,null,3,0,547,23,"app",359],
-Pz:[function(a,b){},"call$1","gpx",2,0,152,231,"appChanged"],
-gpQ:[function(a){return!0},null,null,1,0,373,"applyAuthorStyles"],
+aC:[function(a,b,c,d){A.zs.prototype.aC.call(this,a,b,c,d)},"call$3","gxR",6,0,545,12,[],225,[],226,[],"attributeChanged"],
+guw:[function(a){return a.hm},null,null,1,0,546,"app",351,352],
+suw:[function(a,b){a.hm=this.ct(a,C.wh,a.hm,b)},null,null,3,0,547,23,[],"app",351],
+Pz:[function(a,b){},"call$1","gpx",2,0,150,225,[],"appChanged"],
+gpQ:[function(a){return!0},null,null,1,0,366,"applyAuthorStyles"],
 Om:[function(a,b){var z,y,x,w
 if(b==null)return"-"
 z=J.LL(J.p0(b,1000))
@@ -19026,18 +19453,28 @@
 z=C.jn.Y(z,60000)
 w=C.jn.cU(z,1000)
 z=C.jn.Y(z,1000)
-return Z.Ce(y,2)+":"+Z.Ce(x,2)+":"+Z.Ce(w,2)+"."+Z.Ce(z,3)},"call$1","gSs",2,0,548,549,"formatTime"],
+return Z.Ce(y,2)+":"+Z.Ce(x,2)+":"+Z.Ce(w,2)+"."+Z.Ce(z,3)},"call$1","gSs",2,0,548,549,[],"formatTime"],
 Ze:[function(a,b){var z=J.Wx(b)
 if(z.C(b,1024))return H.d(b)+"B"
 else if(z.C(b,1048576))return""+C.CD.yu(C.CD.UD(z.V(b,1024)))+"KB"
 else if(z.C(b,1073741824))return""+C.CD.yu(C.CD.UD(z.V(b,1048576)))+"MB"
 else if(z.C(b,1099511627776))return""+C.CD.yu(C.CD.UD(z.V(b,1073741824)))+"GB"
-else return""+C.CD.yu(C.CD.UD(z.V(b,1099511627776)))+"TB"},"call$1","gbJ",2,0,391,550,"formatSize"],
+else return""+C.CD.yu(C.CD.UD(z.V(b,1099511627776)))+"TB"},"call$1","gbJ",2,0,387,550,[],"formatSize"],
 bj:[function(a,b){var z,y,x
 z=J.U6(b)
 y=J.UQ(z.t(b,"script"),"user_name")
 x=J.U6(y)
-return x.yn(y,J.WB(x.cn(y,"/"),1))+":"+H.d(z.t(b,"line"))},"call$1","gNh",2,0,551,552,"fileAndLine"],
+return x.yn(y,J.WB(x.cn(y,"/"),1))+":"+H.d(z.t(b,"line"))},"call$1","gNh",2,0,551,552,[],"fileAndLine"],
+nt:[function(a,b){return J.de(b,"@Null")},"call$1","gYx",2,0,553,11,[],"isNullRef"],
+Qq:[function(a,b){var z=J.x(b)
+return z.n(b,"@Smi")||z.n(b,"@Mint")||z.n(b,"@Bigint")},"call$1","gBI",2,0,553,11,[],"isIntRef"],
+TJ:[function(a,b){return J.de(b,"@Bool")},"call$1","gUA",2,0,553,11,[],"isBoolRef"],
+qH:[function(a,b){return J.de(b,"@String")},"call$1","gwm",2,0,553,11,[],"isStringRef"],
+JG:[function(a,b){return J.de(b,"@Instance")},"call$1","gUq",2,0,553,11,[],"isInstanceRef"],
+CL:[function(a,b){return J.de(b,"@Closure")},"call$1","gj7",2,0,553,11,[],"isClosureRef"],
+Bk:[function(a,b){var z=J.x(b)
+return z.n(b,"@GrowableObjectArray")||z.n(b,"@Array")},"call$1","gmv",2,0,553,11,[],"isListRef"],
+VR:[function(a,b){return!C.Nm.tg(["@Null","@Smi","@Mint","@Biginit","@Bool","@String","@Closure","@Instance","@GrowableObjectArray","@Array"],b)},"call$1","gua",2,0,553,11,[],"isUnexpectedRef"],
 "@":function(){return[C.Br]},
 static:{Hx:[function(a){var z,y,x,w
 z=$.Nd()
@@ -19047,21 +19484,21 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Pf.ZL(a)
-C.Pf.oX(a)
-return a},null,null,0,0,108,"new ObservatoryElement$created" /* new ObservatoryElement$created:0:0 */],Ce:[function(a,b){var z,y,x,w
+C.Pf.G6(a)
+return a},null,null,0,0,108,"new ObservatoryElement$created"],Ce:[function(a,b){var z,y,x,w
 for(z=J.Wx(a),y="";x=J.Wx(b),x.D(b,1);){w=x.W(b,1)
 if(typeof w!=="number")H.vh(new P.AT(w))
 if(z.C(a,Math.pow(10,w)))y+="0"
-b=x.W(b,1)}return y+H.d(a)},"call$2","px",4,0,243,23,244,"_zeroPad"]}},
-"+ObservatoryElement":[553],
+b=x.W(b,1)}return y+H.d(a)},"call$2","Rz",4,0,238,23,[],239,[],"_zeroPad"]}},
+"+ObservatoryElement":[554],
 LP:{
-"":"ir+Pi;",
+"^":"ir+Pi;",
 $isd3:true}}],["observe.src.change_notifier","package:observe/src/change_notifier.dart",,O,{
-"":"",
+"^":"",
 Pi:{
-"":"a;",
+"^":"a;",
 gUj:function(a){var z=a.AP
 if(z==null){z=this.gqw(a)
 z=P.bK(this.gl1(a),z,!0,null)
@@ -19078,36 +19515,36 @@
 if(x&&z!=null){x=H.VM(new P.Yp(z),[T.z2])
 if(y.Gv>=4)H.vh(y.q7())
 y.Iv(x)
-return!0}return!1},"call$0","gDx",0,0,373],
+return!0}return!1},"call$0","gDx",0,0,366],
 gUV:function(a){var z,y
 z=a.AP
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 return z},
-ct:[function(a,b,c,d){return F.Wi(a,b,c,d)},"call$3","gAn",6,0,null,257,231,232],
+ct:[function(a,b,c,d){return F.Wi(a,b,c,d)},"call$3","gAn",6,0,null,252,[],225,[],226,[]],
 nq:[function(a,b){var z,y
 z=a.AP
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)return
 if(a.fn==null){a.fn=[]
-P.rb(this.gDx(a))}a.fn.push(b)},"call$1","gbW",2,0,null,22],
+P.rb(this.gDx(a))}a.fn.push(b)},"call$1","giA",2,0,null,22,[]],
 $isd3:true}}],["observe.src.change_record","package:observe/src/change_record.dart",,T,{
-"":"",
+"^":"",
 z2:{
-"":"a;",
+"^":"a;",
 $isz2:true},
 qI:{
-"":"z2;WA<,oc>,jL>,zZ>",
+"^":"z2;WA<,oc>,jL>,zZ>",
 bu:[function(a){return"#<PropertyChangeRecord "+H.d(this.oc)+" from: "+H.d(this.jL)+" to: "+H.d(this.zZ)+">"},"call$0","gXo",0,0,null],
 $isqI:true}}],["observe.src.compound_path_observer","package:observe/src/compound_path_observer.dart",,Y,{
-"":"",
+"^":"",
 J3:{
-"":"Pi;b9,kK,Sv,rk,YX,B6,AP,fn",
+"^":"Pi;b9,kK,Sv,rk,YX,B6,AP,fn",
 kb:function(a){return this.rk.call$1(a)},
 gB:function(a){return this.b9.length},
-gP:[function(a){return this.Sv},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+gP:[function(a){return this.Sv},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 wE:[function(a){var z,y,x,w,v
 if(this.YX)return
 this.YX=!0
@@ -19120,7 +19557,7 @@
 x.push(w)}this.Ow()},"call$0","gM",0,0,null],
 TF:[function(a){if(this.B6)return
 this.B6=!0
-P.rb(this.gMc())},"call$1","geu",2,0,152,240],
+P.rb(this.gMc())},"call$1","geu",2,0,150,235,[]],
 Ow:[function(){var z,y
 this.B6=!1
 z=this.b9
@@ -19139,10 +19576,10 @@
 ni:[function(a){return this.cO(0)},"call$0","gl1",0,0,108],
 $isJ3:true},
 E5:{
-"":"Tp:229;",
-call$1:[function(a){return J.Vm(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.Vm(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true}}],["observe.src.dirty_check","package:observe/src/dirty_check.dart",,O,{
-"":"",
+"^":"",
 Y3:[function(){var z,y,x,w,v,u,t,s,r,q
 if($.Td)return
 if($.tW==null)return
@@ -19169,40 +19606,40 @@
 Ht:[function(){var z={}
 z.a=!1
 z=new O.o5(z)
-return new P.zG(null,null,null,null,new O.u3(z),new O.id(z),null,null,null,null,null,null)},"call$0","Zq",0,0,null],
+return new P.zG(null,null,null,null,new O.zI(z),new O.id(z),null,null,null,null,null,null)},"call$0","Zq",0,0,null],
 o5:{
-"":"Tp:554;a",
+"^":"Tp:555;a",
 call$2:[function(a,b){var z=this.a
 if(z.a)return
 z.a=!0
-a.RK(b,new O.b5(z))},"call$2",null,4,0,null,162,148,"call"],
+a.RK(b,new O.b5(z))},"call$2",null,4,0,null,162,[],146,[],"call"],
 $isEH:true},
 b5:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){this.a.a=!1
 O.Y3()},"call$0",null,0,0,null,"call"],
 $isEH:true},
-u3:{
-"":"Tp:163;b",
+zI:{
+"^":"Tp:163;b",
 call$4:[function(a,b,c,d){if(d==null)return d
-return new O.Zb(this.b,b,c,d)},"call$4",null,8,0,null,161,162,148,110,"call"],
+return new O.Zb(this.b,b,c,d)},"call$4",null,8,0,null,161,[],162,[],146,[],110,[],"call"],
 $isEH:true},
 Zb:{
-"":"Tp:108;c,d,e,f",
+"^":"Tp:108;c,d,e,f",
 call$0:[function(){this.c.call$2(this.d,this.e)
 return this.f.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 id:{
-"":"Tp:555;UI",
+"^":"Tp:556;UI",
 call$4:[function(a,b,c,d){if(d==null)return d
-return new O.iV(this.UI,b,c,d)},"call$4",null,8,0,null,161,162,148,110,"call"],
+return new O.iV(this.UI,b,c,d)},"call$4",null,8,0,null,161,[],162,[],146,[],110,[],"call"],
 $isEH:true},
 iV:{
-"":"Tp:229;bK,Gq,Rm,w3",
+"^":"Tp:223;bK,Gq,Rm,w3",
 call$1:[function(a){this.bK.call$2(this.Gq,this.Rm)
-return this.w3.call$1(a)},"call$1",null,2,0,null,21,"call"],
+return this.w3.call$1(a)},"call$1",null,2,0,null,21,[],"call"],
 $isEH:true}}],["observe.src.list_diff","package:observe/src/list_diff.dart",,G,{
-"":"",
+"^":"",
 f6:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z=J.WB(J.xH(f,e),1)
 y=J.WB(J.xH(c,b),1)
@@ -19238,7 +19675,7 @@
 if(typeof n!=="number")return n.g()
 n=P.J(o+1,n+1)
 if(t>=l)return H.e(m,t)
-m[t]=n}}return x},"call$6","cL",12,0,null,245,246,247,248,249,250],
+m[t]=n}}return x},"call$6","cL",12,0,null,240,[],241,[],242,[],243,[],244,[],245,[]],
 Mw:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=a.length
 y=z-1
@@ -19273,10 +19710,10 @@
 v=p
 y=w}else{u.push(2)
 v=o
-x=s}}}return H.VM(new H.iK(u),[null]).br(0)},"call$1","fZ",2,0,null,251],
+x=s}}}return H.VM(new H.iK(u),[null]).br(0)},"call$1","fZ",2,0,null,246,[]],
 rB:[function(a,b,c){var z,y,x
 for(z=J.U6(a),y=J.U6(b),x=0;x<c;++x)if(!J.de(z.t(a,x),y.t(b,x)))return x
-return c},"call$3","UF",6,0,null,252,253,254],
+return c},"call$3","UF",6,0,null,247,[],248,[],249,[]],
 xU:[function(a,b,c){var z,y,x,w,v,u
 z=J.U6(a)
 y=z.gB(a)
@@ -19287,7 +19724,7 @@
 u=z.t(a,y)
 w=J.xH(w,1)
 u=J.de(u,x.t(b,w))}else u=!1
-if(!u)break;++v}return v},"call$3","M9",6,0,null,252,253,254],
+if(!u)break;++v}return v},"call$3","M9",6,0,null,247,[],248,[],249,[]],
 jj:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=J.Wx(c)
 y=J.Wx(f)
@@ -19337,7 +19774,7 @@
 s=new G.DA(a,y,t,n,0)}J.bi(s.Il,z.t(d,o));++o
 break
 default:}if(s!=null)p.push(s)
-return p},"call$6","Lr",12,0,null,245,246,247,248,249,250],
+return p},"call$6","Lr",12,0,null,240,[],241,[],242,[],243,[],244,[],245,[]],
 m1:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=b.gWA()
 y=J.zj(b)
@@ -19355,8 +19792,7 @@
 y=J.WB(z,J.q8(u.ok.G4))
 x=q.jr
 p=P.J(y,J.WB(x,q.dM))-P.y(z,x)
-if(p>=0){if(r>=a.length)H.vh(new P.bJ("value "+r))
-a.splice(r,1)[0];--r
+if(p>=0){C.Nm.KI(a,r);--r
 z=J.xH(q.dM,J.q8(q.ok.G4))
 if(typeof z!=="number")return H.s(z)
 s-=z
@@ -19377,23 +19813,23 @@
 q.jr=J.WB(q.jr,m)
 if(typeof m!=="number")return H.s(m)
 s+=m
-t=!0}else t=!1}if(!t)a.push(u)},"call$2","c7",4,0,null,255,22],
-VT:[function(a,b){var z,y
+t=!0}else t=!1}if(!t)a.push(u)},"call$2","c7",4,0,null,250,[],22,[]],
+xl:[function(a,b){var z,y
 z=H.VM([],[G.DA])
 for(y=H.VM(new H.a7(b,b.length,0,null),[H.Kp(b,0)]);y.G();)G.m1(z,y.lo)
-return z},"call$2","um",4,0,null,68,256],
-n2:[function(a,b){var z,y,x,w,v,u
+return z},"call$2","bN",4,0,null,68,[],251,[]],
+u2:[function(a,b){var z,y,x,w,v,u
 if(b.length===1)return b
 z=[]
-for(y=G.VT(a,b),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=a.h3;y.G();){w=y.lo
+for(y=G.xl(a,b),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=a.h3;y.G();){w=y.lo
 if(J.de(w.gNg(),1)&&J.de(J.q8(w.gRt().G4),1)){v=J.i4(w.gRt().G4,0)
 u=J.zj(w)
 if(u>>>0!==u||u>=x.length)return H.e(x,u)
 if(!J.de(v,x[u]))z.push(w)
 continue}v=J.RE(w)
-C.Nm.FV(z,G.jj(a,v.gvH(w),J.WB(v.gvH(w),w.gNg()),w.gIl(),0,J.q8(w.gRt().G4)))}return z},"call$2","Pd",4,0,null,68,256],
+C.Nm.FV(z,G.jj(a,v.gvH(w),J.WB(v.gvH(w),w.gNg()),w.gIl(),0,J.q8(w.gRt().G4)))}return z},"call$2","SI",4,0,null,68,[],251,[]],
 DA:{
-"":"a;WA<,ok,Il<,jr,dM",
+"^":"a;WA<,ok,Il<,jr,dM",
 gvH:function(a){return this.jr},
 gRt:function(){return this.ok},
 gNg:function(){return this.dM},
@@ -19404,7 +19840,7 @@
 if(!J.de(this.dM,J.q8(this.ok.G4)))return!0
 z=J.WB(this.jr,this.dM)
 if(typeof z!=="number")return H.s(z)
-return a<z},"call$1","gw9",2,0,null,42],
+return a<z},"call$1","gcW",2,0,null,42,[]],
 bu:[function(a){return"#<ListChangeRecord index: "+H.d(this.jr)+", removed: "+H.d(this.ok)+", addedCount: "+H.d(this.dM)+">"},"call$0","gXo",0,0,null],
 $isDA:true,
 static:{XM:function(a,b,c,d){var z
@@ -19413,46 +19849,46 @@
 z=new P.Yp(d)
 z.$builtinTypeInfo=[null]
 return new G.DA(a,z,d,b,c)}}}}],["observe.src.metadata","package:observe/src/metadata.dart",,K,{
-"":"",
+"^":"",
 nd:{
-"":"a;"},
+"^":"a;"},
 vly:{
-"":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{
-"":"",
+"^":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{
+"^":"",
 Wi:[function(a,b,c,d){var z=J.RE(a)
 if(z.gUV(a)&&!J.de(c,d))z.nq(a,H.VM(new T.qI(a,b,c,d),[null]))
-return d},"call$4","Ha",8,0,null,93,257,231,232],
+return d},"call$4","Ha",8,0,null,93,[],252,[],225,[],226,[]],
 d3:{
-"":"a;",
+"^":"a;",
 $isd3:true},
-X6:{
-"":"Tp:349;a,b",
+lS:{
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z,y,x,w,v
 z=this.b
-y=z.wv.rN(a).Ax
+y=z.wv.rN(a).gAx()
 if(!J.de(b,y)){x=this.a
 w=x.a
 if(w==null){v=[]
 x.a=v
 x=v}else x=w
 x.push(H.VM(new T.qI(z,a,b,y),[null]))
-z.V2.u(0,a,y)}},"call$2",null,4,0,null,12,231,"call"],
+z.V2.u(0,a,y)}},"call$2",null,4,0,null,12,[],225,[],"call"],
 $isEH:true}}],["observe.src.observable_box","package:observe/src/observable_box.dart",,A,{
-"":"",
+"^":"",
 xh:{
-"":"Pi;L1,AP,fn",
-gP:[function(a){return this.L1},null,null,1,0,function(){return H.IG(function(a){return{func:"Oy",ret:a}},this.$receiver,"xh")},"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
-sP:[function(a,b){this.L1=F.Wi(this,C.ls,this.L1,b)},null,null,3,0,function(){return H.IG(function(a){return{func:"qyi",void:true,args:[a]}},this.$receiver,"xh")},232,"value",359],
+"^":"Pi;L1,AP,fn",
+gP:[function(a){return this.L1},null,null,1,0,function(){return H.IG(function(a){return{func:"Oy",ret:a}},this.$receiver,"xh")},"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
+sP:[function(a,b){this.L1=F.Wi(this,C.ls,this.L1,b)},null,null,3,0,function(){return H.IG(function(a){return{func:"lU6",void:true,args:[a]}},this.$receiver,"xh")},226,[],"value",351],
 bu:[function(a){return"#<"+H.d(new H.cu(H.dJ(this),null))+" value: "+H.d(this.L1)+">"},"call$0","gXo",0,0,null]}}],["observe.src.observable_list","package:observe/src/observable_list.dart",,Q,{
-"":"",
+"^":"",
 wn:{
-"":"uF;b3,xg,h3,AP,fn",
+"^":"Ay;b3,xg,h3,AP,fn",
 gvp:function(){var z=this.xg
-if(z==null){z=P.bK(new Q.cj(this),null,!0,null)
+if(z==null){z=P.bK(new Q.Bj(this),null,!0,null)
 this.xg=z}z.toString
 return H.VM(new P.Ik(z),[H.Kp(z,0)])},
-gB:[function(a){return this.h3.length},null,null,1,0,478,"length",359],
+gB:[function(a){return this.h3.length},null,null,1,0,482,"length",351],
 sB:[function(a,b){var z,y,x,w,v,u
 z=this.h3
 y=z.length
@@ -19480,10 +19916,10 @@
 u=[]
 w=new P.Yp(u)
 w.$builtinTypeInfo=[null]
-this.iH(new G.DA(this,w,u,y,x))}C.Nm.sB(z,b)},null,null,3,0,390,23,"length",359],
+this.iH(new G.DA(this,w,u,y,x))}C.Nm.sB(z,b)},null,null,3,0,385,23,[],"length",351],
 t:[function(a,b){var z=this.h3
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,function(){return H.IG(function(a){return{func:"Zg",ret:a,args:[J.im]}},this.$receiver,"wn")},47,"[]",359],
+return z[b]},"call$1","gIA",2,0,function(){return H.IG(function(a){return{func:"Zg",ret:a,args:[J.im]}},this.$receiver,"wn")},47,[],"[]",351],
 u:[function(a,b,c){var z,y,x,w
 z=this.h3
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
@@ -19495,75 +19931,98 @@
 w=new P.Yp(x)
 w.$builtinTypeInfo=[null]
 this.iH(new G.DA(this,w,x,b,1))}if(b>=z.length)return H.e(z,b)
-z[b]=c},"call$2","gj3",4,0,function(){return H.IG(function(a){return{func:"GX",void:true,args:[J.im,a]}},this.$receiver,"wn")},47,23,"[]=",359],
-gl0:[function(a){return P.lD.prototype.gl0.call(this,this)},null,null,1,0,373,"isEmpty",359],
-gor:[function(a){return P.lD.prototype.gor.call(this,this)},null,null,1,0,373,"isNotEmpty",359],
+z[b]=c},"call$2","gj3",4,0,function(){return H.IG(function(a){return{func:"UR",void:true,args:[J.im,a]}},this.$receiver,"wn")},47,[],23,[],"[]=",351],
+gl0:[function(a){return P.lD.prototype.gl0.call(this,this)},null,null,1,0,366,"isEmpty",351],
+gor:[function(a){return P.lD.prototype.gor.call(this,this)},null,null,1,0,366,"isNotEmpty",351],
 h:[function(a,b){var z,y,x,w
 z=this.h3
 y=z.length
-this.Fg(y,y+1)
+this.nU(y,y+1)
 x=this.xg
 if(x!=null){w=x.iE
 x=w==null?x!=null:w!==x}else x=!1
 if(x)this.iH(G.XM(this,y,1,null))
-C.Nm.h(z,b)},"call$1","ght",2,0,null,23],
+C.Nm.h(z,b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y,x,w
 z=this.h3
 y=z.length
 C.Nm.FV(z,b)
-this.Fg(y,z.length)
+this.nU(y,z.length)
 x=z.length-y
 z=this.xg
 if(z!=null){w=z.iE
 z=w==null?z!=null:w!==z}else z=!1
-if(z&&x>0)this.iH(G.XM(this,y,x,null))},"call$1","gDY",2,0,null,109],
+if(z&&x>0)this.iH(G.XM(this,y,x,null))},"call$1","gDY",2,0,null,109,[]],
 Rz:[function(a,b){var z,y
 for(z=this.h3,y=0;y<z.length;++y)if(J.de(z[y],b)){this.UZ(0,y,y+1)
-return!0}return!1},"call$1","gRI",2,0,null,124],
-UZ:[function(a,b,c){var z,y,x,w,v,u
-if(b>this.h3.length)H.vh(P.TE(b,0,this.h3.length))
-z=c>=b
-if(c<b||c>this.h3.length)H.vh(P.TE(c,b,this.h3.length))
-y=c-b
-x=this.h3
-w=x.length
-v=w-y
-this.ct(this,C.Wn,w,v)
-u=w===0
-v=v===0
-this.ct(this,C.ai,u,v)
-this.ct(this,C.nZ,!u,!v)
-v=this.xg
-if(v!=null){u=v.iE
-v=u==null?v!=null:u!==v}else v=!1
-if(v&&y>0){if(b>x.length)H.vh(P.TE(b,0,x.length))
-if(c<b||c>x.length)H.vh(P.TE(c,b,x.length))
-z=new H.nH(x,b,c)
+return!0}return!1},"call$1","gRI",2,0,null,124,[]],
+UZ:[function(a,b,c){var z,y,x,w,v,u,t
+z=b>=0
+if(!z||b>this.h3.length)H.vh(P.TE(b,0,this.h3.length))
+y=c>=b
+if(!y||c>this.h3.length)H.vh(P.TE(c,b,this.h3.length))
+x=c-b
+w=this.h3
+v=w.length
+u=v-x
+this.ct(this,C.Wn,v,u)
+t=v===0
+u=u===0
+this.ct(this,C.ai,t,u)
+this.ct(this,C.nZ,!t,!u)
+u=this.xg
+if(u!=null){t=u.iE
+u=t==null?u!=null:t!==u}else u=!1
+if(u&&x>0){if(!z||b>w.length)H.vh(P.TE(b,0,w.length))
+if(!y||c>w.length)H.vh(P.TE(c,b,w.length))
+z=new H.nH(w,b,c)
 z.$builtinTypeInfo=[null]
 if(b<0)H.vh(new P.bJ("value "+b))
 if(c<0)H.vh(new P.bJ("value "+c))
 if(b>c)H.vh(P.TE(b,0,c))
 z=z.br(0)
-v=new P.Yp(z)
-v.$builtinTypeInfo=[null]
-this.iH(new G.DA(this,v,z,b,0))}C.Nm.UZ(x,b,c)},"call$2","gYH",4,0,null,115,116],
+y=new P.Yp(z)
+y.$builtinTypeInfo=[null]
+this.iH(new G.DA(this,y,z,b,0))}C.Nm.UZ(w,b,c)},"call$2","gYH",4,0,null,115,[],116,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.h3.length)throw H.b(P.TE(b,0,this.h3.length))
+z=this.h3
+y=z.length
+if(b===y){this.h(0,c)
+return}C.Nm.sB(z,y+1)
+y=z.length
+H.Og(z,b+1,y,this,b)
+y=z.length
+this.nU(y-1,y)
+y=this.xg
+if(y!=null){x=y.iE
+y=x==null?y!=null:x!==y}else y=!1
+if(y)this.iH(G.XM(this,b,1,null))
+if(b<0||b>=z.length)return H.e(z,b)
+z[b]=c},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){var z,y
+z=this.h3
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+this.UZ(0,b,b+1)
+return y},"call$1","gNM",2,0,null,47,[]],
 iH:[function(a){var z,y
 z=this.xg
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)return
 if(this.b3==null){this.b3=[]
-P.rb(this.gL6())}this.b3.push(a)},"call$1","gSi",2,0,null,22],
-Fg:[function(a,b){var z,y
+P.rb(this.gL6())}this.b3.push(a)},"call$1","gSi",2,0,null,22,[]],
+nU:[function(a,b){var z,y
 this.ct(this,C.Wn,a,b)
 z=a===0
 y=J.x(b)
 this.ct(this,C.ai,z,y.n(b,0))
-this.ct(this,C.nZ,!z,!y.n(b,0))},"call$2","gdX",4,0,null,231,232],
+this.ct(this,C.nZ,!z,!y.n(b,0))},"call$2","gdX",4,0,null,225,[],226,[]],
 cv:[function(){var z,y,x
 z=this.b3
 if(z==null)return!1
-y=G.n2(this,z)
+y=G.u2(this,z)
 this.b3=null
 z=this.xg
 if(z!=null){x=z.iE
@@ -19571,40 +20030,40 @@
 if(x){x=H.VM(new P.Yp(y),[G.DA])
 if(z.Gv>=4)H.vh(z.q7())
 z.Iv(x)
-return!0}return!1},"call$0","gL6",0,0,373],
+return!0}return!1},"call$0","gL6",0,0,366],
 $iswn:true,
 static:{uX:function(a,b){var z=H.VM([],[b])
 return H.VM(new Q.wn(null,null,z,null,null),[b])}}},
-uF:{
-"":"ar+Pi;",
+Ay:{
+"^":"ar+Pi;",
 $isd3:true},
-cj:{
-"":"Tp:108;a",
+Bj:{
+"^":"Tp:108;a",
 call$0:[function(){this.a.xg=null},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["observe.src.observable_map","package:observe/src/observable_map.dart",,V,{
-"":"",
+"^":"",
 HA:{
-"":"z2;G3>,jL>,zZ>,JD,dr",
+"^":"z2;G3>,jL>,zZ>,JD,dr",
 bu:[function(a){var z
 if(this.JD)z="insert"
 else z=this.dr?"remove":"set"
 return"#<MapChangeRecord "+z+" "+H.d(this.G3)+" from: "+H.d(this.jL)+" to: "+H.d(this.zZ)+">"},"call$0","gXo",0,0,null],
 $isHA:true},
 qC:{
-"":"Pi;Zp,AP,fn",
+"^":"Pi;Zp,AP,fn",
 gvc:[function(a){var z=this.Zp
-return z.gvc(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"pD",ret:[P.cX,a]}},this.$receiver,"qC")},"keys",359],
+return z.gvc(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"pD",ret:[P.cX,a]}},this.$receiver,"qC")},"keys",351],
 gUQ:[function(a){var z=this.Zp
-return z.gUQ(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"NE",ret:[P.cX,b]}},this.$receiver,"qC")},"values",359],
+return z.gUQ(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"NE",ret:[P.cX,b]}},this.$receiver,"qC")},"values",351],
 gB:[function(a){var z=this.Zp
-return z.gB(z)},null,null,1,0,478,"length",359],
+return z.gB(z)},null,null,1,0,482,"length",351],
 gl0:[function(a){var z=this.Zp
-return z.gB(z)===0},null,null,1,0,373,"isEmpty",359],
+return z.gB(z)===0},null,null,1,0,366,"isEmpty",351],
 gor:[function(a){var z=this.Zp
-return z.gB(z)!==0},null,null,1,0,373,"isNotEmpty",359],
-di:[function(a){return this.Zp.di(a)},"call$1","gmc",2,0,556,23,"containsValue",359],
-x4:[function(a){return this.Zp.x4(a)},"call$1","gV9",2,0,556,42,"containsKey",359],
-t:[function(a,b){return this.Zp.t(0,b)},"call$1","gIA",2,0,function(){return H.IG(function(a,b){return{func:"JB",ret:b,args:[P.a]}},this.$receiver,"qC")},42,"[]",359],
+return z.gB(z)!==0},null,null,1,0,366,"isNotEmpty",351],
+di:[function(a){return this.Zp.di(a)},"call$1","gmc",2,0,557,23,[],"containsValue",351],
+x4:[function(a){return this.Zp.x4(a)},"call$1","gV9",2,0,557,42,[],"containsKey",351],
+t:[function(a,b){return this.Zp.t(0,b)},"call$1","gIA",2,0,function(){return H.IG(function(a,b){return{func:"JB",ret:b,args:[P.a]}},this.$receiver,"qC")},42,[],"[]",351],
 u:[function(a,b,c){var z,y,x,w,v
 z=this.Zp
 y=z.gB(z)
@@ -19614,15 +20073,9 @@
 if(w!=null){v=w.iE
 w=v==null?w!=null:v!==w}else w=!1
 if(w){z=z.gB(z)
-w=y!==z
-if(w){if(this.gUV(this)&&w){z=new T.qI(this,C.Wn,y,z)
-z.$builtinTypeInfo=[null]
-this.nq(this,z)}z=new V.HA(b,null,c,!0,!1)
-z.$builtinTypeInfo=[null,null]
-this.nq(this,z)}else if(!J.de(x,c)){z=new V.HA(b,x,c,!1,!1)
-z.$builtinTypeInfo=[null,null]
-this.nq(this,z)}}},"call$2","gj3",4,0,function(){return H.IG(function(a,b){return{func:"fK",void:true,args:[a,b]}},this.$receiver,"qC")},42,23,"[]=",359],
-FV:[function(a,b){J.kH(b,new V.zT(this))},"call$1","gDY",2,0,null,104],
+if(y!==z){F.Wi(this,C.Wn,y,z)
+this.nq(this,H.VM(new V.HA(b,null,c,!0,!1),[null,null]))}else if(!J.de(x,c))this.nq(this,H.VM(new V.HA(b,x,c,!1,!1),[null,null]))}},"call$2","gj3",4,0,function(){return H.IG(function(a,b){return{func:"fK",void:true,args:[a,b]}},this.$receiver,"qC")},42,[],23,[],"[]=",351],
+FV:[function(a,b){J.kH(b,new V.zT(this))},"call$1","gDY",2,0,null,104,[]],
 Rz:[function(a,b){var z,y,x,w,v
 z=this.Zp
 y=z.gB(z)
@@ -19631,7 +20084,7 @@
 if(w!=null){v=w.iE
 w=v==null?w!=null:v!==w}else w=!1
 if(w&&y!==z.gB(z)){this.nq(this,H.VM(new V.HA(b,x,null,!1,!0),[null,null]))
-F.Wi(this,C.Wn,y,z.gB(z))}return x},"call$1","gRI",2,0,null,42],
+F.Wi(this,C.Wn,y,z.gB(z))}return x},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){var z,y,x,w
 z=this.Zp
 y=z.gB(z)
@@ -19640,7 +20093,7 @@
 x=w==null?x!=null:w!==x}else x=!1
 if(x&&y>0){z.aN(0,new V.Lo(this))
 F.Wi(this,C.Wn,y,0)}z.V1(0)},"call$0","gyP",0,0,null],
-aN:[function(a,b){return this.Zp.aN(0,b)},"call$1","gjw",2,0,null,110],
+aN:[function(a,b){return this.Zp.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 $isZ0:true,
 static:{WF:function(a,b,c){var z=V.Bq(a,b,c)
@@ -19651,21 +20104,21 @@
 else y=typeof a==="object"&&a!==null&&!!z.$isFo?H.VM(new V.qC(P.L5(null,null,null,b,c),null,null),[b,c]):H.VM(new V.qC(P.Py(null,null,null,b,c),null,null),[b,c])
 return y}}},
 zT:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"vPt",args:[a,b]}},this.a,"qC")}},
 Lo:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=this.a
-z.nq(z,H.VM(new V.HA(a,b,null,!1,!0),[null,null]))},"call$2",null,4,0,null,42,23,"call"],
+z.nq(z,H.VM(new V.HA(a,b,null,!1,!0),[null,null]))},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true}}],["observe.src.path_observer","package:observe/src/path_observer.dart",,L,{
-"":"",
+"^":"",
 Wa:[function(a,b){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isqI)return J.de(a.oc,b)
 if(typeof a==="object"&&a!==null&&!!z.$isHA){z=J.RE(b)
 if(typeof b==="object"&&b!==null&&!!z.$iswv)b=z.gfN(b)
-return J.de(a.G3,b)}return!1},"call$2","mD",4,0,null,22,42],
+return J.de(a.G3,b)}return!1},"call$2","mD",4,0,null,22,[],42,[]],
 yf:[function(a,b){var z,y,x,w,v
 if(a==null)return
 x=b
@@ -19675,14 +20128,13 @@
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$iswv){z=H.vn(a)
 y=H.jO(J.bB(z.gAx()).LU)
-try{if(L.My(y,b)){x=b
-x=z.tu(x,1,J.GL(x),[])
-return x.Ax}if(L.iN(y,C.fz)){x=J.UQ(a,J.GL(b))
+try{if(L.TH(y,b)){x=z.rN(b).gAx()
+return x}if(L.M6(y,C.fz)){x=J.UQ(a,J.GL(b))
 return x}}catch(v){x=H.Ru(v)
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.iN(y,C.OV))throw v}else throw v}}}x=$.aT()
-if(x.mL(C.Ab))x.x9("can't get "+H.d(b)+" in "+H.d(a))
-return},"call$2","MT",4,0,null,6,66],
+if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.M6(y,C.OV))throw v}else throw v}}}x=$.aT()
+if(x.Im(C.Ab))x.x9("can't get "+H.d(b)+" in "+H.d(a))
+return},"call$2","MT",4,0,null,6,[],66,[]],
 h6:[function(a,b,c){var z,y,x,w,v
 if(a==null)return!1
 x=b
@@ -19693,19 +20145,19 @@
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$iswv){z=H.vn(a)
 y=H.jO(J.bB(z.gAx()).LU)
-try{if(L.hg(y,b)){z.PU(b,c)
-return!0}if(L.iN(y,C.eC)){J.kW(a,J.GL(b),c)
+try{if(L.dR(y,b)){z.PU(b,c)
+return!0}if(L.M6(y,C.eC)){J.kW(a,J.GL(b),c)
 return!0}}catch(v){x=H.Ru(v)
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.iN(y,C.OV))throw v}else throw v}}}x=$.aT()
-if(x.mL(C.Ab))x.x9("can't set "+H.d(b)+" in "+H.d(a))
-return!1},"call$3","nV",6,0,null,6,66,23],
-My:[function(a,b){var z
+if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.M6(y,C.OV))throw v}else throw v}}}x=$.aT()
+if(x.Im(C.Ab))x.x9("can't set "+H.d(b)+" in "+H.d(a))
+return!1},"call$3","nV",6,0,null,6,[],66,[],23,[]],
+TH:[function(a,b){var z
 for(;!J.de(a,$.aA());){z=a.gYK().nb
 if(z.x4(b))return!0
 if(z.x4(C.OV))return!0
-a=L.pY(a)}return!1},"call$2","If",4,0,null,11,12],
-hg:[function(a,b){var z,y,x,w
+a=L.pY(a)}return!1},"call$2","fY",4,0,null,11,[],12,[]],
+dR:[function(a,b){var z,y,x,w
 z=new H.GD(H.le(H.d(b.gfN(b))+"="))
 for(;!J.de(a,$.aA());){y=a.gYK().nb
 x=y.t(0,b)
@@ -19713,23 +20165,23 @@
 if(typeof x==="object"&&x!==null&&!!w.$isRY)return!0
 if(y.x4(z))return!0
 if(y.x4(C.OV))return!0
-a=L.pY(a)}return!1},"call$2","Qd",4,0,null,11,12],
-iN:[function(a,b){var z,y
+a=L.pY(a)}return!1},"call$2","Jh",4,0,null,11,[],12,[]],
+M6:[function(a,b){var z,y
 for(;!J.de(a,$.aA());){z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS&&z.guU())return!0
-a=L.pY(a)}return!1},"call$2","iS",4,0,null,11,12],
+a=L.pY(a)}return!1},"call$2","SU",4,0,null,11,[],12,[]],
 pY:[function(a){var z,y
 try{z=a.gAY()
 return z}catch(y){H.Ru(y)
-return $.aA()}},"call$1","WV",2,0,null,11],
+return $.aA()}},"call$1","WV",2,0,null,11,[]],
 rd:[function(a){a=J.JA(a,$.c3(),"")
 if(a==="")return!0
 if(0>=a.length)return H.e(a,0)
 if(a[0]===".")return!1
-return $.tN().zD(a)},"call$1","QO",2,0,null,86],
+return $.tN().zD(a)},"call$1","KL",2,0,null,86,[]],
 WR:{
-"":"Pi;ay,YB,BK,kN,cs,cT,AP,fn",
+"^":"Pi;ay,YB,BK,kN,cs,cT,AP,fn",
 E4:function(a){return this.cT.call$1(a)},
 gWA:function(){var z=this.kN
 if(0>=z.length)return H.e(z,0)
@@ -19740,8 +20192,8 @@
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)this.ov()
-return C.Nm.grZ(this.kN)},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+return C.Nm.grZ(this.kN)},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:[function(a,b){var z,y,x,w
 z=this.BK
 y=z.length
@@ -19757,7 +20209,7 @@
 if(w>=z.length)return H.e(z,w)
 if(L.h6(x,z[w],b)){z=this.kN
 if(y>=z.length)return H.e(z,y)
-z[y]=b}},null,null,3,0,452,232,"value",359],
+z[y]=b}},null,null,3,0,446,226,[],"value",351],
 k0:[function(a){O.Pi.prototype.k0.call(this,this)
 this.ov()
 this.XI()},"call$0","gqw",0,0,107],
@@ -19782,7 +20234,7 @@
 if(w===y&&x)u=this.E4(u)
 v=this.kN;++w
 if(w>=v.length)return H.e(v,w)
-v[w]=u}},function(){return this.Zy(null)},"ov","call$1$end",null,"gFD",0,3,null,77,116],
+v[w]=u}},function(){return this.Zy(null)},"ov","call$1$end",null,"gFD",0,3,null,77,116,[]],
 hd:[function(a){var z,y,x,w,v,u,t,s,r
 for(z=this.BK,y=z.length-1,x=this.cT!=null,w=a,v=null,u=null;w<=y;w=s){t=this.kN
 s=w+1
@@ -19800,7 +20252,7 @@
 t[s]=u}this.ij(a)
 if(this.gUV(this)&&!J.de(v,u)){z=new T.qI(this,C.ls,v,u)
 z.$builtinTypeInfo=[null]
-this.nq(this,z)}},"call$1$start","gWx",0,3,null,336,115],
+this.nq(this,z)}},"call$1$start","gWx",0,3,null,330,115,[]],
 Rl:[function(a,b){var z,y
 if(b==null)b=this.BK.length
 if(typeof b!=="number")return H.s(b)
@@ -19809,7 +20261,7 @@
 if(z>=y.length)return H.e(y,z)
 y=y[z]
 if(y!=null)y.ed()
-this.Kh(z)}},function(){return this.Rl(0,null)},"XI",function(a){return this.Rl(a,null)},"ij","call$2",null,null,"gmi",0,4,null,336,77,115,116],
+this.Kh(z)}},function(){return this.Rl(0,null)},"XI",function(a){return this.Rl(a,null)},"ij","call$2",null,null,"gmi",0,4,null,330,77,115,[],116,[]],
 Kh:[function(a){var z,y,x,w,v
 z=this.kN
 if(a>=z.length)return H.e(z,a)
@@ -19833,7 +20285,7 @@
 w.o7=P.VH(P.AY(),z)
 w.Bd=z.Al(P.v3())
 if(a>=v.length)return H.e(v,a)
-v[a]=w}}},"call$1","gCf",2,0,null,341],
+v[a]=w}}},"call$1","gCf",2,0,null,383,[]],
 d4:function(a,b,c){var z,y,x,w
 if(this.YB)for(z=J.rr(b).split("."),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]),y=this.BK;z.G();){x=z.lo
 if(J.de(x,""))continue
@@ -19850,26 +20302,26 @@
 z.d4(a,b,c)
 return z}}},
 qL:{
-"":"Tp:229;",
-call$1:[function(a){return},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Px:{
-"":"Tp:557;a,b,c",
+"^":"Tp:558;a,b,c",
 call$1:[function(a){var z,y
 for(z=J.GP(a),y=this.c;z.G();)if(z.gl().ck(y)){this.a.hd(this.b)
-return}},"call$1",null,2,0,null,256,"call"],
+return}},"call$1",null,2,0,null,251,[],"call"],
 $isEH:true},
 C4:{
-"":"Tp:558;d,e,f",
+"^":"Tp:559;d,e,f",
 call$1:[function(a){var z,y
 for(z=J.GP(a),y=this.f;z.G();)if(L.Wa(z.gl(),y)){this.d.hd(this.e)
-return}},"call$1",null,2,0,null,256,"call"],
+return}},"call$1",null,2,0,null,251,[],"call"],
 $isEH:true},
 Md:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return new H.VR(H.v4("^(?:(?:[$_a-zA-Z]+[$_a-zA-Z0-9]*|(?:[0-9]|[1-9]+[0-9]+)))(?:\\.(?:[$_a-zA-Z]+[$_a-zA-Z0-9]*|(?:[0-9]|[1-9]+[0-9]+)))*$",!1,!0,!1),null,null)},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["observe.src.to_observable","package:observe/src/to_observable.dart",,R,{
-"":"",
+"^":"",
 Jk:[function(a){var z,y,x
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isd3)return a
@@ -19878,190 +20330,12 @@
 return y}if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)){z=z.ez(a,R.np())
 x=Q.uX(null,null)
 x.FV(0,z)
-return x}return a},"call$1","np",2,0,229,23],
+return x}return a},"call$1","np",2,0,223,23,[]],
 km:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,R.Jk(a),R.Jk(b))},"call$2",null,4,0,null,421,277,"call"],
-$isEH:true}}],["path","package:path/path.dart",,B,{
-"":"",
-ab:function(){var z,y,x,w
-z=P.uo()
-y=$.Ur()
-x=$.wE()
-if(y==null?x==null:y===x)return z.mS(P.r6($.cO().ej("."))).bu(0)
-else{w=z.t4()
-return C.xB.Nj(w,0,w.length-1)}},
-"":"As<"}],["path.context","package:path/src/context.dart",,F,{
-"":"",
-YF:[function(a,b){var z,y,x,w,v,u
-for(z=1;z<8;++z){if(b[z]==null||b[z-1]!=null)continue
-for(y=8;y>=1;y=x){x=y-1
-if(b[x]!=null)break}w=new P.Rn("")
-w.vM=""
-v=a+"("
-v=""+v
-w.vM=v
-u=new H.nH(b,0,y)
-u.$builtinTypeInfo=[null]
-if(y<0)H.vh(new P.bJ("value "+y))
-if(0>y)H.vh(P.TE(0,0,y))
-u=new H.A8(u,new F.No())
-u.$builtinTypeInfo=[null,null]
-u=u.zV(0,", ")
-v+=u
-w.vM=v
-u="): part "+(z-1)+" was null, but part "+z+" was not."
-v+=u
-w.vM=v
-throw H.b(new P.AT(v))}},"call$2","nE",4,0,null,221,258],
-lI:{
-"":"a;S,l",
-tM:[function(a){var z,y,x
-z=Q.lo(a,this.S)
-z.IV()
-y=z.wZ
-x=y.length
-if(x===0){y=z.SF
-return y==null?".":y}if(x===1){y=z.SF
-return y==null?".":y}C.Nm.mv(y)
-y=z.ZB
-if(0>=y.length)return H.e(y,0)
-y.pop()
-z.IV()
-return z.bu(0)},"call$1","gP5",2,0,null,266],
-C8:[function(a,b,c,d,e,f,g,h,i){var z=[b,c,d,e,f,g,h,i]
-F.YF("join",z)
-return this.IP(H.VM(new H.U5(z,new F.u2()),[null]))},function(a,b,c){return this.C8(a,b,c,null,null,null,null,null,null)},"tX","call$8",null,"gnr",2,14,null,77,77,77,77,77,77,77,559,560,561,562,563,564,565,566],
-IP:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
-z=P.p9("")
-for(y=H.VM(new H.U5(a,new F.q7()),[H.ip(a,"mW",0)]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=this.S,w=y.OI,v=!1,u=!1;y.G();){t=w.gl()
-if(Q.lo(t,x).aA&&u){s=Q.lo(t,x)
-r=Q.lo(z.vM,x).SF
-q=r==null?"":r
-s.SF=q
-if(J.kE(q,x.gnK())===!0){q=s.ZB
-p=x.gmI()
-if(0>=q.length)return H.e(q,0)
-q[0]=p}z.vM=""
-q=s.bu(0)
-z.vM=z.vM+q}else if(Q.lo(t,x).SF!=null){u=!Q.lo(t,x).aA
-z.vM=""
-o=typeof t==="string"?t:H.d(t)
-z.vM=z.vM+o}else{q=J.U6(t)
-if(J.z8(q.gB(t),0)&&J.kE(q.t(t,0),x.gDF())===!0);else if(v===!0){q=x.gmI()
-z.vM=z.vM+q}o=typeof t==="string"?t:H.d(t)
-z.vM=z.vM+o}v=J.kE(t,x.gnK())}return z.vM},"call$1","gl4",2,0,null,182],
-Fr:[function(a,b){var z,y,x
-z=Q.lo(b,this.S)
-y=H.VM(new H.U5(z.wZ,new F.Qt()),[null])
-y=P.F(y,!0,H.ip(y,"mW",0))
-z.wZ=y
-x=z.SF
-if(x!=null)C.Nm.xe(y,0,x)
-return z.wZ},"call$1","gOG",2,0,null,266]},
-u2:{
-"":"Tp:229;",
-call$1:[function(a){return a!=null},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-q7:{
-"":"Tp:229;",
-call$1:[function(a){return!J.de(a,"")},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-Qt:{
-"":"Tp:229;",
-call$1:[function(a){return J.FN(a)!==!0},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-No:{
-"":"Tp:229;",
-call$1:[function(a){return a==null?"null":"\""+H.d(a)+"\""},"call$1",null,2,0,null,165,"call"],
-$isEH:true}}],["path.parsed_path","package:path/src/parsed_path.dart",,Q,{
-"":"",
-v5:{
-"":"a;S,SF,aA,wZ,ZB",
-IV:[function(){var z,y
-z=this.ZB
-while(!0){y=this.wZ
-if(!(y.length!==0&&J.de(C.Nm.grZ(y),"")))break
-C.Nm.mv(this.wZ)
-if(0>=z.length)return H.e(z,0)
-z.pop()}y=z.length
-if(y>0)z[y-1]=""},"call$0","gio",0,0,null],
-bu:[function(a){var z,y,x,w,v
-z=P.p9("")
-y=this.SF
-if(y!=null)z.KF(y)
-for(y=this.ZB,x=0;x<this.wZ.length;++x){if(x>=y.length)return H.e(y,x)
-w=y[x]
-w=typeof w==="string"?w:H.d(w)
-z.vM=z.vM+w
-v=this.wZ
-if(x>=v.length)return H.e(v,x)
-w=v[x]
-w=typeof w==="string"?w:H.d(w)
-z.vM=z.vM+w}z.KF(C.Nm.grZ(y))
-return z.vM},"call$0","gXo",0,0,null],
-static:{lo:function(a,b){var z,y,x,w,v,u,t,s,r,q
-z=b.xZ(a)
-y=b.uP(a)
-if(z!=null)a=J.ZZ(a,J.q8(z))
-x=[]
-w=[]
-v=b.gDF()
-u=v.R4(0,a)
-if(u!=null){t=u.QK
-if(0>=t.length)return H.e(t,0)
-w.push(t[0])
-if(0>=t.length)return H.e(t,0)
-a=J.ZZ(a,J.q8(t[0]))}else w.push("")
-if(typeof a!=="string")H.vh(new P.AT(a))
-v=new H.Pb(v,a,null)
-t=J.U6(a)
-s=0
-for(;v.G();){r=v.Wh.QK
-x.push(t.Nj(a,s,r.index))
-if(0>=r.length)return H.e(r,0)
-w.push(r[0])
-q=r.index
-if(0>=r.length)return H.e(r,0)
-r=J.q8(r[0])
-if(typeof r!=="number")return H.s(r)
-s=q+r}v=t.gB(a)
-if(typeof v!=="number")return H.s(v)
-if(s<v){x.push(t.yn(a,s))
-w.push("")}return new Q.v5(b,z,y!=null,x,w)}}}}],["path.style","package:path/src/style.dart",,S,{
-"":"",
-Rh:[function(){if(!J.de(P.uo().Fi,"file"))return $.wE()
-if(!J.Eg(P.uo().r0,"/"))return $.wE()
-if(P.R6("","","a/b",null,0,null,null,null,"").t4()==="a\\b")return $.CE()
-return $.KL()},"call$0","RI",0,0,null],
-OO:{
-"":"a;TL<",
-xZ:[function(a){var z,y
-z=this.gEw()
-if(typeof a!=="string")H.vh(new P.AT(a))
-y=new H.KW(z,a)
-if(!y.gl0(y))return J.UQ(y.gtH(y),0)
-return this.uP(a)},"call$1","gye",2,0,null,266],
-uP:[function(a){var z,y
-z=this.gTL()
-if(z==null)return
-z.toString
-if(typeof a!=="string")H.vh(new P.AT(a))
-y=new H.KW(z,a)
-if(!y.gA(y).G())return
-return J.UQ(y.gtH(y),0)},"call$1","gvZ",2,0,null,266],
-bu:[function(a){return this.goc(this)},"call$0","gXo",0,0,null],
-static:{"":"aC<"}}}],["path.style.posix","package:path/src/style/posix.dart",,Z,{
-"":"",
-OF:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"}}],["path.style.url","package:path/src/style/url.dart",,E,{
-"":"",
-rM:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL:ir<,TL"}}],["path.style.windows","package:path/src/style/windows.dart",,T,{
-"":"",
-IV:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL:r9<,TL"}}],["polymer","package:polymer/polymer.dart",,A,{
-"":"",
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,R.Jk(a),R.Jk(b))},"call$2",null,4,0,null,417,[],272,[],"call"],
+$isEH:true}}],["polymer","package:polymer/polymer.dart",,A,{
+"^":"",
 JX:[function(){var z,y
 z=document.createElement("style",null)
 z.textContent=".polymer-veiled { opacity: 0; } \n.polymer-unveil{ -webkit-transition: opacity 0.3s; transition: opacity 0.3s; }\n"
@@ -20074,7 +20348,7 @@
 for(x=W.vD(document.querySelectorAll(y),null),x=x.gA(x);x.G();)J.pP(x.lo).h(0,"polymer-veiled")}},"call$0","r8",0,0,null],
 yV:[function(a){var z,y
 z=$.xY().Rz(0,a)
-if(z!=null)for(y=J.GP(z);y.G();)J.Or(y.gl())},"call$1","Km",2,0,null,12],
+if(z!=null)for(y=J.GP(z);y.G();)J.Or(y.gl())},"call$1","Km",2,0,null,12,[]],
 oF:[function(a,b){var z,y,x,w,v,u
 if(J.de(a,$.Tf()))return b
 b=A.oF(a.gAY(),b)
@@ -20086,18 +20360,18 @@
 if(w)for(w=J.GP(y.gc9());w.G();){v=w.lo.gAx()
 u=J.x(v)
 if(typeof v==="object"&&v!==null&&!!u.$isyL){if(typeof y!=="object"||y===null||!x.$isRS||A.bc(a,y)){if(b==null)b=H.B7([],P.L5(null,null,null,null,null))
-b.u(0,y.gIf(),y)}break}}}return b},"call$2","Sy",4,0,null,259,260],
+b.u(0,y.gIf(),y)}break}}}return b},"call$2","Cd",4,0,null,253,[],254,[]],
 Oy:[function(a,b){var z,y
 do{z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS&&z.glT()&&A.bc(a,z)||typeof z==="object"&&z!==null&&!!y.$isRY)return z
-a=a.gAY()}while(a!=null)
-return},"call$2","il",4,0,null,259,66],
+a=a.gAY()}while(!J.de(a,$.Tf()))
+return},"call$2","il",4,0,null,253,[],66,[]],
 bc:[function(a,b){var z,y
 z=H.le(H.d(b.gIf().fN)+"=")
 y=a.gYK().nb.t(0,new H.GD(z))
 z=J.x(y)
-return typeof y==="object"&&y!==null&&!!z.$isRS&&y.ghB()},"call$2","oS",4,0,null,259,261],
+return typeof y==="object"&&y!==null&&!!z.$isRS&&y.ghB()},"call$2","i8",4,0,null,253,[],255,[]],
 YG:[function(a,b,c){var z,y,x
 z=$.cM()
 if(z==null||a==null)return
@@ -20106,7 +20380,7 @@
 if(y==null)return
 x=J.UQ(y,"ShadowCSS")
 if(x==null)return
-x.V7("shimStyling",[a,b,c])},"call$3","OA",6,0,null,262,12,263],
+x.V7("shimStyling",[a,b,c])},"call$3","OA",6,0,null,256,[],12,[],257,[]],
 Hl:[function(a){var z,y,x,w,v,u,t
 if(a==null)return""
 w=J.RE(a)
@@ -20126,49 +20400,49 @@
 if(typeof w==="object"&&w!==null&&!!t.$isNh){y=w
 x=new H.XO(u,null)
 $.vM().J4("failed to get stylesheet text href=\""+H.d(z)+"\" error: "+H.d(y)+", trace: "+H.d(x))
-return""}else throw u}},"call$1","Js",2,0,null,264],
+return""}else throw u}},"call$1","Js",2,0,null,258,[]],
 Ad:[function(a,b){var z
 if(b==null)b=C.hG
 $.Ej().u(0,a,b)
 z=$.p2().Rz(0,a)
-if(z!=null)J.Or(z)},"call$2","ZK",2,2,null,77,12,11],
-zM:[function(a){A.Vx(a,new A.Mq())},"call$1","on",2,0,null,265],
+if(z!=null)J.Or(z)},"call$2","ZK",2,2,null,77,12,[],11,[]],
+zM:[function(a){A.Vx(a,new A.Mq())},"call$1","mo",2,0,null,259,[]],
 Vx:[function(a,b){var z
 if(a==null)return
 b.call$1(a)
-for(z=a.firstChild;z!=null;z=z.nextSibling)A.Vx(z,b)},"call$2","Dv",4,0,null,265,150],
+for(z=a.firstChild;z!=null;z=z.nextSibling)A.Vx(z,b)},"call$2","Dv",4,0,null,259,[],148,[]],
 lJ:[function(a,b,c,d){if(!J.co(b,"on-"))return d.call$3(a,b,c)
-return new A.L6(a,b)},"call$4","y4",8,0,null,266,12,265,267],
+return new A.L6(a,b)},"call$4","y4",8,0,null,260,[],12,[],259,[],261,[]],
 Hr:[function(a){var z
 for(;z=J.RE(a),z.gKV(a)!=null;)a=z.gKV(a)
-return $.od().t(0,a)},"call$1","Aa",2,0,null,265],
+return $.od().t(0,a)},"call$1","Fd",2,0,null,259,[]],
 HR:[function(a,b,c){var z,y,x
 z=H.vn(a)
 y=A.Rk(H.jO(J.bB(z.Ax).LU),b)
 if(y!=null){x=y.gMP()
 x=x.ev(x,new A.uJ())
-C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},"call$3","SU",6,0,null,41,268,258],
+C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},"call$3","xi",6,0,null,41,[],262,[],263,[]],
 Rk:[function(a,b){var z,y
 do{z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS)return z
-a=a.gAY()}while(a!=null)},"call$2","Uy",4,0,null,11,12],
+a=a.gAY()}while(a!=null)},"call$2","Uy",4,0,null,11,[],12,[]],
 ZI:[function(a,b){var z,y
 if(a==null)return
 z=document.createElement("style",null)
 z.textContent=a.textContent
 y=a.getAttribute("element")
 if(y!=null)z.setAttribute("element",y)
-b.appendChild(z)},"call$2","tO",4,0,null,269,270],
+b.appendChild(z)},"call$2","tO",4,0,null,264,[],265,[]],
 pX:[function(){var z=window
 C.ol.hr(z)
 C.ol.oB(z,W.aF(new A.hm()))},"call$0","ji",0,0,null],
 al:[function(a,b){var z,y,x
 z=J.RE(b)
 y=typeof b==="object"&&b!==null&&!!z.$isRY?z.gt5(b):H.Go(b,"$isRS").gdw()
-if(J.de(y.gvd(),C.PU)||J.de(y.gvd(),C.nN))if(a!=null){x=A.h5(a)
+if(J.de(y.gUx(),C.PU)||J.de(y.gUx(),C.nN))if(a!=null){x=A.h5(a)
 if(x!=null)return P.re(x)
-return H.jO(J.bB(H.vn(a).Ax).LU)}return y},"call$2","mN",4,0,null,23,66],
+return H.jO(J.bB(H.vn(a).Ax).LU)}return y},"call$2","mN",4,0,null,23,[],66,[]],
 h5:[function(a){var z
 if(a==null)return C.Qf
 if(typeof a==="number"&&Math.floor(a)===a)return C.yw
@@ -20177,7 +20451,7 @@
 if(typeof a==="string")return C.Db
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isiP)return C.Yc
-return},"call$1","V9",2,0,null,23],
+return},"call$1","V9",2,0,null,23,[]],
 Ok:[function(){if($.uP){var z=$.X3.iT(O.Ht())
 z.Gr(A.PB())
 return z}A.ei()
@@ -20216,43 +20490,65 @@
 x=!0}else{z="warning: more than one Dart script tag in "+H.d(b)+". Dartium currently only allows a single Dart script tag per document."
 v=$.oK
 if(v==null)H.qw(z)
-else v.call$1(z)}}return d},"call$4","bX",4,4,null,77,77,271,272,273,274],
-pw:[function(a){var z,y,x,w,v,u,t,s,r,q,p
+else v.call$1(z)}}return d},"call$4","fE",4,4,null,77,77,266,[],267,[],268,[],269,[]],
+pw:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 z=$.RQ()
 z.toString
-y=$.cO()
-x=z.mS(P.r6(y.ej(a)))
-z=$.UG().nb
-w=z.t(0,x)
-v=x.r0
-u=$.rw()
-if(J.co(v,u)&&J.Eg(x.r0,".dart")){t=z.t(0,P.r6(y.ej("package:"+J.ZZ(x.r0,u.length))))
-if(t!=null)w=t}if(w==null){$.M7().To(H.d(x)+" library not found")
-return}z=w.gYK().nb
+y=$.qG()
+x=P.r6(y.ej(a))
+w=x.Fi
+if(!J.de(w,"")){v=x.ku
+u=x.gJf(x)
+t=x.gtp(x)
+s=z.SK(x.r0)
+r=x.tP}else{if(!J.de(x.gJf(x),"")){v=x.ku
+u=x.gJf(x)
+t=x.gtp(x)
+s=z.SK(x.r0)
+r=x.tP}else{if(J.de(x.r0,"")){s=z.r0
+r=x.tP
+r=!J.de(r,"")?r:z.tP}else{q=J.co(x.r0,"/")
+p=x.r0
+s=q?z.SK(p):z.SK(z.Ky(z.r0,p))
+r=x.tP}v=z.ku
+u=z.gJf(z)
+t=z.gtp(z)}w=z.Fi}o=P.R6(x.Ka,u,s,null,t,r,null,w,v)
+x=$.UG().nb
+n=x.t(0,o)
+m=o.r0
+if(J.de(o.Fi,z.Fi))if(o.gWu()===z.gWu()){z=J.rY(m)
+if(z.Tc(m,".dart"))z=z.tg(m,"/packages/")===!0||z.nC(m,"packages/")
+else z=!1}else z=!1
+else z=!1
+if(z){z=o.r0
+q=J.U6(z)
+l=x.t(0,P.r6(y.ej("package:"+q.yn(z,J.WB(q.cn(z,"packages/"),9)))))
+if(l!=null)n=l}if(n==null){$.M7().To(H.d(o)+" library not found")
+return}z=n.gYK().nb
 z=z.gUQ(z)
 y=new A.Fn()
-v=new H.U5(z,y)
-v.$builtinTypeInfo=[H.ip(z,"mW",0)]
+x=new H.U5(z,y)
+x.$builtinTypeInfo=[H.ip(z,"mW",0)]
 z=z.gA(z)
 y=new H.SO(z,y)
-y.$builtinTypeInfo=[H.Kp(v,0)]
-for(;y.G();)A.ZB(w,z.gl())
-z=w.gYK().nb
+y.$builtinTypeInfo=[H.Kp(x,0)]
+for(;y.G();)A.ZB(n,z.gl())
+z=n.gYK().nb
 z=z.gUQ(z)
 y=new A.e3()
-v=new H.U5(z,y)
-v.$builtinTypeInfo=[H.ip(z,"mW",0)]
+x=new H.U5(z,y)
+x.$builtinTypeInfo=[H.ip(z,"mW",0)]
 z=z.gA(z)
 y=new H.SO(z,y)
-y.$builtinTypeInfo=[H.Kp(v,0)]
-for(;y.G();){s=z.gl()
-for(v=J.GP(s.gc9());v.G();){r=v.lo.gAx()
-u=J.x(r)
-if(typeof r==="object"&&r!==null&&!!u.$isV3){u=r.ns
-q=s.gYj()
-$.Ej().u(0,u,q)
-p=$.p2().Rz(0,u)
-if(p!=null)J.Or(p)}}}},"call$1","Xz",2,0,null,275],
+y.$builtinTypeInfo=[H.Kp(x,0)]
+for(;y.G();){k=z.gl()
+for(x=J.GP(k.gc9());x.G();){j=x.lo.gAx()
+q=J.x(j)
+if(typeof j==="object"&&j!==null&&!!q.$isV3){q=j.ns
+p=k.gYj()
+$.Ej().u(0,q,p)
+i=$.p2().Rz(0,q)
+if(i!=null)J.Or(i)}}}},"call$1","Xz",2,0,null,270,[]],
 ZB:[function(a,b){var z,y,x
 for(z=J.GP(b.gc9());y=!1,z.G();)if(z.lo.gAx()===C.za){y=!0
 break}if(!y)return
@@ -20266,13 +20562,13 @@
 z=$.oK
 if(z==null)H.qw(x)
 else z.call$1(x)
-return}a.CI(b.gIf(),C.xD)},"call$2","K0",4,0,null,93,221],
+return}a.CI(b.gIf(),C.xD)},"call$2","K0n",4,0,null,93,[],215,[]],
 Zj:{
-"":"Tp:229;",
-call$1:[function(a){A.pX()},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){A.pX()},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 XP:{
-"":"qE;zx,kw,aa,RT,Q7=,NF=,hf=,xX=,cI,lD,Gd=,Ei",
+"^":"qE;zx,kw,aa,RT,Q7=,NF=,hf=,xX=,cI,lD,Gd=,Ei",
 gt5:function(a){return a.zx},
 gP1:function(a){return a.aa},
 goc:function(a){return a.RT},
@@ -20315,15 +20611,15 @@
 y0:[function(a,b){if($.Ej().t(0,b)!=null)return!1
 $.p2().u(0,b,a)
 if(a.hasAttribute("noscript")===!0)A.Ad(b,null)
-return!0},"call$1","go8",2,0,null,12],
+return!0},"call$1","gLD",2,0,null,12,[]],
 PM:[function(a,b){if(b!=null&&J.UU(b,"-")>=0)if(!$.cd().x4(b)){J.bi($.xY().to(b,new A.q6()),a)
-return!0}return!1},"call$1","gd7",2,0,null,263],
+return!0}return!1},"call$1","gmL",2,0,null,257,[]],
 Ba:[function(a,b){var z,y,x,w
 for(z=a,y=null;z!=null;){x=J.RE(z)
 y=x.gQg(z).MW.getAttribute("extends")
 z=x.gP1(z)}x=document
 w=a.zx
-W.wi(window,x,b,w,y)},"call$1","gr7",2,0,null,12],
+W.wi(window,x,b,w,y)},"call$1","gr7",2,0,null,12,[]],
 YU:[function(a,b,c){var z,y,x,w,v,u,t
 if(c!=null&&J.YP(c)!=null){z=J.YP(c)
 y=P.L5(null,null,null,null,null)
@@ -20345,14 +20641,14 @@
 if(typeof console!="undefined")console.warn(t)
 continue}y=a.Q7
 if(y==null){y=H.B7([],P.L5(null,null,null,null,null))
-a.Q7=y}y.u(0,v,u)}}},"call$2","gvQ",4,0,null,259,567],
+a.Q7=y}y.u(0,v,u)}}},"call$2","gvQ",4,0,null,253,[],560,[]],
 Vk:[function(a){var z,y
 z=P.L5(null,null,null,J.O,P.a)
 a.xX=z
 y=a.aa
 if(y!=null)z.FV(0,J.Ng(y))
 new W.i7(a).aN(0,new A.CK(a))},"call$0","gYi",0,0,null],
-W3:[function(a,b){new W.i7(a).aN(0,new A.LJ(b))},"call$1","gSX",2,0,null,568],
+W3:[function(a,b){new W.i7(a).aN(0,new A.LJ(b))},"call$1","gSX",2,0,null,561,[]],
 Mi:[function(a){var z=this.Hs(a,"[rel=stylesheet]")
 a.cI=z
 for(z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.QC(z.lo)},"call$0","gax",0,0,null],
@@ -20372,13 +20668,13 @@
 w.vM=t+"\n"}if(w.vM.length>0){z=document.createElement("style",null)
 z.textContent=H.d(w)
 v=J.RE(x)
-v.mK(x,z,v.gq6(x))}}},"call$0","gWT",0,0,null],
+v.mK(x,z,v.gq6(x))}}},"call$0","gysu",0,0,null],
 oP:[function(a,b,c){var z,y,x
 z=W.vD(a.querySelectorAll(b),null)
 y=z.br(z)
 x=this.gZf(a)
 if(x!=null)C.Nm.FV(y,J.pe(x,b))
-return y},function(a,b){return this.oP(a,b,null)},"Hs","call$2",null,"gKQ",2,2,null,77,457,569],
+return y},function(a,b){return this.oP(a,b,null)},"Hs","call$2",null,"gKQ",2,2,null,77,452,[],562,[]],
 kO:[function(a,b){var z,y,x,w,v,u
 z=P.p9("")
 y=new A.Oc("[polymer-scope="+b+"]")
@@ -20386,17 +20682,17 @@
 v=typeof v==="string"?v:H.d(v)
 u=z.vM+v
 z.vM=u
-z.vM=u+"\n\n"}for(x=a.lD,x.toString,y=H.VM(new H.U5(x,y),[null]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=y.OI;y.G();){w=x.gl().gTa()
+z.vM=u+"\n\n"}for(x=a.lD,x.toString,y=H.VM(new H.U5(x,y),[null]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=y.OI;y.G();){w=x.gl().ghg()
 w=z.vM+w
 z.vM=w
-z.vM=w+"\n\n"}return z.vM},"call$1","gvf",2,0,null,570],
+z.vM=w+"\n\n"}return z.vM},"call$1","gvf",2,0,null,563,[]],
 J3:[function(a,b,c){var z
 if(b==="")return
 z=document.createElement("style",null)
 z.textContent=b
 z.toString
 z.setAttribute("element",a.RT+"-"+c)
-return z},"call$2","gpR",4,0,null,571,570],
+return z},"call$2","gNG",4,0,null,564,[],563,[]],
 q1:[function(a,b){var z,y,x,w
 if(J.de(b,$.Tf()))return
 this.q1(a,b.gAY())
@@ -20407,89 +20703,89 @@
 x=J.rY(w)
 if(x.Tc(w,"Changed")&&!x.n(w,"attributeChanged")){if(a.hf==null)a.hf=P.L5(null,null,null,null,null)
 w=x.Nj(w,0,J.xH(x.gB(w),7))
-a.hf.u(0,new H.GD(H.le(w)),y.gIf())}}},"call$1","gCB",2,0,null,259],
+a.hf.u(0,new H.GD(H.le(w)),y.gIf())}}},"call$1","gCB",2,0,null,253,[]],
 qC:[function(a,b){var z=P.L5(null,null,null,J.O,null)
 b.aN(0,new A.MX(z))
-return z},"call$1","gql",2,0,null,572],
+return z},"call$1","gir",2,0,null,565,[]],
 du:function(a){a.RT=a.getAttribute("name")
 this.yx(a)},
 $isXP:true,
-static:{"":"Nb",XL:function(a){a.Gd=H.B7([],P.L5(null,null,null,null,null))
+static:{"^":"Rlv",XL:function(a){a.Gd=H.B7([],P.L5(null,null,null,null,null))
 C.xk.ZL(a)
 C.xk.du(a)
 return a}}},
 q6:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return[]},"call$0",null,0,0,null,"call"],
 $isEH:true},
 CK:{
-"":"Tp:349;a",
-call$2:[function(a,b){if(C.kr.x4(a)!==!0&&!J.co(a,"on-"))this.a.xX.u(0,a,b)},"call$2",null,4,0,null,12,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){if(C.kr.x4(a)!==!0&&!J.co(a,"on-"))this.a.xX.u(0,a,b)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 LJ:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z,y,x
 z=J.rY(a)
 if(z.nC(a,"on-")){y=J.U6(b).u8(b,"{{")
 x=C.xB.cn(b,"}}")
-if(y>=0&&x>=0)this.a.u(0,z.yn(a,3),C.xB.bS(C.xB.Nj(b,y+2,x)))}},"call$2",null,4,0,null,12,23,"call"],
+if(y>=0&&x>=0)this.a.u(0,z.yn(a,3),C.xB.bS(C.xB.Nj(b,y+2,x)))}},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 ZG:{
-"":"Tp:229;",
-call$1:[function(a){return J.Vs(a).MW.hasAttribute("polymer-scope")!==!0},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.Vs(a).MW.hasAttribute("polymer-scope")!==!0},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 Oc:{
-"":"Tp:229;a",
-call$1:[function(a){return J.RF(a,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.RF(a,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 MX:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,J.Mz(J.GL(a)),b)},"call$2",null,4,0,null,12,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,J.Mz(J.GL(a)),b)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
-w11:{
-"":"Tp:108;",
+w9:{
+"^":"Tp:108;",
 call$0:[function(){var z=P.L5(null,null,null,J.O,J.O)
-C.FS.aN(0,new A.ppY(z))
+C.FS.aN(0,new A.r3y(z))
 return z},"call$0",null,0,0,null,"call"],
 $isEH:true},
-ppY:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,573,574,"call"],
+r3y:{
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,566,[],567,[],"call"],
 $isEH:true},
 yL:{
-"":"nd;",
+"^":"nd;",
 $isyL:true},
 zs:{
-"":["a;KM:ZQ=-357",function(){return[C.nJ]}],
+"^":["a;KM:X0=-349",function(){return[C.nJ]}],
 gpQ:function(a){return!1},
 Pa:[function(a){if(W.Pv(this.gM0(a).defaultView)!=null||$.Bh>0)this.Ec(a)},"call$0","gu1",0,0,null],
 Ec:[function(a){var z,y
 z=this.gQg(a).MW.getAttribute("is")
 y=z==null||z===""?this.gqn(a):z
-a.wV=$.cd().t(0,y)
+a.dZ=$.cd().t(0,y)
 this.Xl(a)
 this.Z2(a)
 this.fk(a)
 this.Uc(a)
 $.Bh=$.Bh+1
-this.z2(a,a.wV)
+this.z2(a,a.dZ)
 $.Bh=$.Bh-1},"call$0","gLi",0,0,null],
-i4:[function(a){if(a.wV==null)this.Ec(a)
+i4:[function(a){if(a.dZ==null)this.Ec(a)
 this.BT(a,!0)},"call$0","gQd",0,0,null],
 xo:[function(a){this.x3(a)},"call$0","gbt",0,0,null],
 z2:[function(a,b){if(b!=null){this.z2(a,J.lB(b))
-this.d0(a,b)}},"call$1","gtf",2,0,null,575],
+this.d0(a,b)}},"call$1","gET",2,0,null,568,[]],
 d0:[function(a,b){var z,y,x,w,v
 z=J.RE(b)
 y=z.Ja(b,"template")
-if(y!=null)if(J.Vs(a.wV).MW.hasAttribute("lightdom")===!0){this.Se(a,y)
+if(y!=null)if(J.Vs(a.dZ).MW.hasAttribute("lightdom")===!0){this.Se(a,y)
 x=null}else x=this.Tp(a,y)
 else x=null
 w=J.x(x)
 if(typeof x!=="object"||x===null||!w.$isI0)return
 v=z.gQg(b).MW.getAttribute("name")
 if(v==null)return
-a.B7.u(0,v,x)},"call$1","gcY",2,0,null,576],
+a.B7.u(0,v,x)},"call$1","gEB",2,0,null,569,[]],
 Se:[function(a,b){var z,y
 if(b==null)return
 z=J.x(b)
@@ -20497,7 +20793,7 @@
 y=z.ZK(a,a.SO)
 this.jx(a,y)
 this.lj(a,a)
-return y},"call$1","gAt",2,0,null,262],
+return y},"call$1","gAt",2,0,null,256,[]],
 Tp:[function(a,b){var z,y
 if(b==null)return
 this.gKE(a)
@@ -20509,45 +20805,45 @@
 y=typeof b==="object"&&b!==null&&!!y.$ishs?b:M.Ky(b)
 z.appendChild(y.ZK(a,a.SO))
 this.lj(a,z)
-return z},"call$1","gPA",2,0,null,262],
+return z},"call$1","gPA",2,0,null,256,[]],
 lj:[function(a,b){var z,y,x,w
-for(z=J.pe(b,"[id]"),z=z.gA(z),y=a.ZQ,x=J.w1(y);z.G();){w=z.lo
-x.u(y,J.F8(w),w)}},"call$1","gb7",2,0,null,577],
+for(z=J.pe(b,"[id]"),z=z.gA(z),y=a.X0,x=J.w1(y);z.G();){w=z.lo
+x.u(y,J.F8(w),w)}},"call$1","gb7",2,0,null,570,[]],
 aC:[function(a,b,c,d){var z=J.x(b)
-if(!z.n(b,"class")&&!z.n(b,"style"))this.D3(a,b,d)},"call$3","gxR",6,0,null,12,231,232],
-Z2:[function(a){J.Ng(a.wV).aN(0,new A.WC(a))},"call$0","gGN",0,0,null],
-fk:[function(a){if(J.ak(a.wV)==null)return
+if(!z.n(b,"class")&&!z.n(b,"style"))this.D3(a,b,d)},"call$3","gxR",6,0,null,12,[],225,[],226,[]],
+Z2:[function(a){J.Ng(a.dZ).aN(0,new A.WC(a))},"call$0","gGN",0,0,null],
+fk:[function(a){if(J.ak(a.dZ)==null)return
 this.gQg(a).aN(0,this.ghW(a))},"call$0","goQ",0,0,null],
 D3:[function(a,b,c){var z,y,x,w
 z=this.B2(a,b)
 if(z==null)return
 if(c==null||J.kE(c,$.VC())===!0)return
 y=H.vn(a)
-x=y.rN(z.gIf()).Ax
+x=y.rN(z.gIf()).gAx()
 w=Z.Zh(c,x,A.al(x,z))
-if(w==null?x!=null:w!==x)y.PU(z.gIf(),w)},"call$2","ghW",4,0,578,12,23],
-B2:[function(a,b){var z=J.ak(a.wV)
+if(w==null?x!=null:w!==x)y.PU(z.gIf(),w)},"call$2","ghW",4,0,571,12,[],23,[]],
+B2:[function(a,b){var z=J.ak(a.dZ)
 if(z==null)return
-return z.t(0,b)},"call$1","gHf",2,0,null,12],
+return z.t(0,b)},"call$1","gHf",2,0,null,12,[]],
 TW:[function(a,b){if(b==null)return
 if(typeof b==="boolean")return b?"":null
 else if(typeof b==="string"||typeof b==="number"&&Math.floor(b)===b||typeof b==="number")return H.d(b)
-return},"call$1","gk9",2,0,null,23],
+return},"call$1","gt4",2,0,null,23,[]],
 Id:[function(a,b){var z,y
-z=H.vn(a).rN(b).Ax
+z=H.vn(a).rN(b).gAx()
 y=this.TW(a,z)
 if(y!=null)this.gQg(a).MW.setAttribute(J.GL(b),y)
-else if(typeof z==="boolean")this.gQg(a).Rz(0,J.GL(b))},"call$1","gQp",2,0,null,12],
+else if(typeof z==="boolean")this.gQg(a).Rz(0,J.GL(b))},"call$1","gQp",2,0,null,12,[]],
 Z1:[function(a,b,c,d){var z,y,x,w,v,u,t
-if(a.wV==null)this.Ec(a)
+if(a.dZ==null)this.Ec(a)
 z=this.B2(a,b)
 if(z==null)return J.Jj(M.Ky(a),b,c,d)
 else{J.MV(M.Ky(a),b)
 y=z.gIf()
 x=$.ZH()
-if(x.mL(C.R5))x.J4("["+H.d(c)+"]: bindProperties: ["+H.d(d)+"] to ["+this.gqn(a)+"].["+H.d(y)+"]")
+if(x.Im(C.R5))x.J4("["+H.d(c)+"]: bindProperties: ["+H.d(d)+"] to ["+this.gqn(a)+"].["+H.d(y)+"]")
 w=L.ao(c,d,null)
-if(w.gP(w)==null)w.sP(0,H.vn(a).rN(y).Ax)
+if(w.gP(w)==null)w.sP(0,H.vn(a).rN(y).gAx())
 x=H.vn(a)
 v=y.fN
 u=d!=null?d:""
@@ -20556,9 +20852,9 @@
 t.bw(a,y,c,d)
 this.Id(a,z.gIf())
 J.kW(J.QE(M.Ky(a)),b,t)
-return t}},"call$3","gDT",4,2,null,77,12,285,266],
+return t}},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 gCd:function(a){return J.QE(M.Ky(a))},
-Ih:[function(a,b){return J.MV(M.Ky(a),b)},"call$1","gV0",2,0,null,12],
+Ih:[function(a,b){return J.MV(M.Ky(a),b)},"call$1","gC8",2,0,null,12,[]],
 x3:[function(a){var z,y
 if(a.Uk===!0)return
 $.P5().J4("["+this.gqn(a)+"] asyncUnbindAll")
@@ -20567,7 +20863,7 @@
 if(z!=null)z.TP(0)
 else z=new A.S0(null,null)
 z.M3=y
-z.ih=P.rT(C.RT,z.gv6(z))
+z.ih=P.rT(C.ny,z.gv6(z))
 a.oq=z},"call$0","gpj",0,0,null],
 GB:[function(a){var z,y
 if(a.Uk===!0)return
@@ -20584,32 +20880,32 @@
 z=a.oq
 if(z!=null){z.TP(0)
 a.oq=null}if(b===!0)return
-A.Vx(this.gKE(a),new A.TV())},function(a){return this.BT(a,null)},"oW","call$1$preventCascade",null,"gF7",0,3,null,77,579],
+A.Vx(this.gKE(a),new A.TV())},function(a){return this.BT(a,null)},"oW","call$1$preventCascade",null,"gF7",0,3,null,77,572,[]],
 Xl:[function(a){var z,y,x,w,v,u
-z=J.xR(a.wV)
-y=J.YP(a.wV)
+z=J.xR(a.dZ)
+y=J.YP(a.dZ)
 x=z==null
 if(!x)for(z.toString,w=H.VM(new P.i5(z),[H.Kp(z,0)]),v=w.Fb,w=H.VM(new P.N6(v,v.zN,null,null),[H.Kp(w,0)]),w.zq=w.Fb.H9;w.G();){u=w.fD
-this.rJ(a,u,H.vn(a).tu(u,1,J.GL(u),[]),null)}if(!x||y!=null)a.Wz=this.gUj(a).yI(this.gnu(a))},"call$0","gJx",0,0,null],
+this.rJ(a,u,H.vn(a).rN(u),null)}if(!x||y!=null)a.Wz=this.gUj(a).yI(this.gnu(a))},"call$0","gJx",0,0,null],
 Pv:[function(a,b){var z,y,x,w,v,u
-z=J.xR(a.wV)
-y=J.YP(a.wV)
-x=P.L5(null,null,null,P.wv,A.k8)
+z=J.xR(a.dZ)
+y=J.YP(a.dZ)
+x=P.L5(null,null,null,P.wv,A.bS)
 for(w=J.GP(b);w.G();){v=w.gl()
 u=J.x(v)
 if(typeof v!=="object"||v===null||!u.$isqI)continue
-J.Pz(x.to(v.oc,new A.Oa(v)),v.zZ)}x.aN(0,new A.n1(a,b,z,y))},"call$1","gnu",2,0,580,581],
+J.iG(x.to(v.oc,new A.Oa(v)),v.zZ)}x.aN(0,new A.n1(a,b,z,y))},"call$1","gnu",2,0,573,574,[]],
 rJ:[function(a,b,c,d){var z,y,x,w,v
-z=J.xR(a.wV)
+z=J.xR(a.dZ)
 if(z==null)return
 y=z.t(0,b)
 if(y==null)return
 x=J.x(d)
 if(typeof d==="object"&&d!==null&&!!x.$iswn){x=$.a3()
-if(x.mL(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: unregister observer "+H.d(b))
+if(x.Im(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: unregister observer "+H.d(b))
 this.l5(a,H.d(J.GL(b))+"__array")}x=J.x(c)
 if(typeof c==="object"&&c!==null&&!!x.$iswn){x=$.a3()
-if(x.mL(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: register observer "+H.d(b))
+if(x.Im(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: register observer "+H.d(b))
 w=c.gvp().w4(!1)
 x=w.Lj
 w.dB=x.cR(new A.xf(a,d,y))
@@ -20618,21 +20914,21 @@
 x=H.d(J.GL(b))+"__array"
 v=a.Sa
 if(v==null){v=P.L5(null,null,null,J.O,P.MO)
-a.Sa=v}v.u(0,x,w)}},"call$3","gDW",6,0,null,12,23,248],
+a.Sa=v}v.u(0,x,w)}},"call$3","gDW",6,0,null,12,[],23,[],243,[]],
 l5:[function(a,b){var z=a.Sa.Rz(0,b)
 if(z==null)return!1
 z.ed()
-return!0},"call$1","gjC",2,0,null,12],
+return!0},"call$1","gjC",2,0,null,12,[]],
 C0:[function(a){var z=a.Sa
 if(z==null)return
 for(z=z.gUQ(z),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)z.lo.ed()
 a.Sa.V1(0)
 a.Sa=null},"call$0","gNX",0,0,null],
 Uc:[function(a){var z,y
-z=J.wX(a.wV)
+z=J.wX(a.dZ)
 if(z.gl0(z))return
 y=$.SS()
-if(y.mL(C.R5))y.J4("["+this.gqn(a)+"] addHostListeners: "+H.d(z))
+if(y.Im(C.R5))y.J4("["+this.gqn(a)+"] addHostListeners: "+H.d(z))
 this.UH(a,a,z.gvc(z),this.gD4(a))},"call$0","ghu",0,0,null],
 UH:[function(a,b,c,d){var z,y,x,w,v,u,t
 for(z=c.Fb,z=H.VM(new P.N6(z,z.zN,null,null),[H.Kp(c,0)]),z.zq=z.Fb.H9,y=J.RE(b);z.G();){x=z.fD
@@ -20642,61 +20938,61 @@
 t=new W.Ov(0,w.uv,v,W.aF(d),u)
 t.$builtinTypeInfo=[H.Kp(w,0)]
 w=t.u7
-if(w!=null&&t.VP<=0)J.cZ(t.uv,v,w,u)}},"call$3","gPm",6,0,null,265,582,298],
+if(w!=null&&t.VP<=0)J.cZ(t.uv,v,w,u)}},"call$3","gPm",6,0,null,259,[],575,[],292,[]],
 iw:[function(a,b){var z,y,x,w,v,u,t
 z=J.RE(b)
 if(z.gXt(b)!==!0)return
 y=$.SS()
-x=y.mL(C.R5)
+x=y.Im(C.R5)
 if(x)y.J4(">>> ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")
-w=J.wX(a.wV)
+w=J.wX(a.dZ)
 v=z.gt5(b)
-u=J.UQ($.pT(),v)
+u=J.UQ($.QX(),v)
 t=w.t(0,u!=null?u:v)
-if(t!=null){if(x)y.J4("["+this.gqn(a)+"] found host handler name ["+H.d(t)+"]")
-this.ea(a,a,t,[b,typeof b==="object"&&b!==null&&!!z.$isDG?z.gey(b):null,a])}if(x)y.J4("<<< ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")},"call$1","gD4",2,0,583,405],
+if(t!=null){if(x)y.J4("["+this.gqn(a)+"] found host handler name ["+t+"]")
+this.ea(a,a,t,[b,typeof b==="object"&&b!==null&&!!z.$isHe?z.gey(b):null,a])}if(x)y.J4("<<< ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")},"call$1","gD4",2,0,576,400,[]],
 ea:[function(a,b,c,d){var z,y,x
 z=$.SS()
-y=z.mL(C.R5)
+y=z.Im(C.R5)
 if(y)z.J4(">>> ["+this.gqn(a)+"]: dispatch "+H.d(c))
 x=J.x(c)
 if(typeof c==="object"&&c!==null&&!!x.$isEH)H.Ek(c,d,P.Te(null))
 else if(typeof c==="string")A.HR(b,new H.GD(H.le(c)),d)
 else z.j2("invalid callback")
-if(y)z.To("<<< ["+this.gqn(a)+"]: dispatch "+H.d(c))},"call$3","gtW",6,0,null,6,584,258],
+if(y)z.To("<<< ["+this.gqn(a)+"]: dispatch "+H.d(c))},"call$3","gtW",6,0,null,6,[],577,[],263,[]],
 $iszs:true,
 $ishs:true,
 $isd3:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true},
+$isKV:true},
 WC:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=J.Vs(this.a)
 if(z.x4(a)!==!0)z.u(0,a,new A.Xi(b).call$0())
-z.t(0,a)},"call$2",null,4,0,null,12,23,"call"],
+z.t(0,a)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 Xi:{
-"":"Tp:108;b",
+"^":"Tp:108;b",
 call$0:[function(){return this.b},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TV:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.RE(a)
-if(typeof a==="object"&&a!==null&&!!z.$iszs)z.oW(a)},"call$1",null,2,0,null,292,"call"],
+if(typeof a==="object"&&a!==null&&!!z.$iszs)z.oW(a)},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Mq:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return J.AA(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a))},"call$1",null,2,0,null,265,"call"],
+return J.AA(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a))},"call$1",null,2,0,null,259,[],"call"],
 $isEH:true},
 Oa:{
-"":"Tp:108;a",
-call$0:[function(){return new A.k8(this.a.jL,null)},"call$0",null,0,0,null,"call"],
+"^":"Tp:108;a",
+call$0:[function(){return new A.bS(this.a.jL,null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 n1:{
-"":"Tp:349;b,c,d,e",
+"^":"Tp:341;b,c,d,e",
 call$2:[function(a,b){var z,y,x
 z=this.e
 if(z!=null&&z.x4(a))J.Jr(this.b,a)
@@ -20706,26 +21002,26 @@
 if(y!=null){z=this.b
 x=J.RE(b)
 J.Ut(z,a,x.gzZ(b),x.gjL(b))
-A.HR(z,y,[x.gjL(b),x.gzZ(b),this.c])}},"call$2",null,4,0,null,12,585,"call"],
+A.HR(z,y,[x.gjL(b),x.gzZ(b),this.c])}},"call$2",null,4,0,null,12,[],578,[],"call"],
 $isEH:true},
 xf:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){A.HR(this.a,this.c,[this.b])},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){A.HR(this.a,this.c,[this.b])},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 L6:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z,y,x
 z=$.SS()
-if(z.mL(C.R5))z.J4("event: ["+H.d(b)+"]."+H.d(this.b)+" => ["+H.d(a)+"]."+this.a+"())")
+if(z.Im(C.R5))z.J4("event: ["+H.d(b)+"]."+H.d(this.b)+" => ["+H.d(a)+"]."+this.a+"())")
 y=J.ZZ(this.b,3)
 x=C.FS.t(0,y)
 if(x!=null)y=x
 z=J.f5(b).t(0,y)
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new A.Rs(this.a,a,b)),z.Sg),[H.Kp(z,0)]).Zz()
-return H.VM(new A.xh(null,null,null),[null])},"call$2",null,4,0,null,285,265,"call"],
+return H.VM(new A.xh(null,null,null),[null])},"call$2",null,4,0,null,280,[],259,[],"call"],
 $isEH:true},
 Rs:{
-"":"Tp:229;c,d,e",
+"^":"Tp:223;c,d,e",
 call$1:[function(a){var z,y,x,w,v,u
 z=this.e
 y=A.Hr(z)
@@ -20737,44 +21033,44 @@
 u=L.ao(v,C.xB.yn(w,1),null)
 w=u.gP(u)}else v=y
 u=J.RE(a)
-x.ea(y,v,w,[a,typeof a==="object"&&a!==null&&!!u.$isDG?u.gey(a):null,z])},"call$1",null,2,0,null,405,"call"],
+x.ea(y,v,w,[a,typeof a==="object"&&a!==null&&!!u.$isHe?u.gey(a):null,z])},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 uJ:{
-"":"Tp:229;",
-call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,586,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,579,[],"call"],
 $isEH:true},
 hm:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z,y,x
 z=W.vD(document.querySelectorAll(".polymer-veiled"),null)
 for(y=z.gA(z);y.G();){x=J.pP(y.lo)
 x.h(0,"polymer-unveil")
 x.Rz(x,"polymer-veiled")}if(z.gor(z)){y=C.hi.aM(window)
-y.gtH(y).ml(new A.Ji(z))}},"call$1",null,2,0,null,240,"call"],
+y.gtH(y).ml(new A.Ji(z))}},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Ji:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z
-for(z=this.a,z=z.gA(z);z.G();)J.pP(z.lo).Rz(0,"polymer-unveil")},"call$1",null,2,0,null,240,"call"],
+for(z=this.a,z=z.gA(z);z.G();)J.pP(z.lo).Rz(0,"polymer-unveil")},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Bf:{
-"":"TR;I6,iU,Jq,dY,qP,ZY,xS,PB,eS,ay",
+"^":"TR;I6,iU,Jq,dY,qP,ZY,xS,PB,eS,ay",
 cO:[function(a){if(this.qP==null)return
 this.Jq.ed()
 X.TR.prototype.cO.call(this,this)},"call$0","gJK",0,0,null],
 EC:[function(a){this.dY=a
-this.I6.PU(this.iU,a)},"call$1","gH0",2,0,null,232],
+this.I6.PU(this.iU,a)},"call$1","gH0",2,0,null,226,[]],
 ho:[function(a){var z,y,x,w,v
 for(z=J.GP(a),y=this.iU;z.G();){x=z.gl()
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$isqI&&J.de(x.oc,y)){v=this.I6.tu(y,1,y.fN,[]).Ax
+if(typeof x==="object"&&x!==null&&!!w.$isqI&&J.de(x.oc,y)){v=this.I6.rN(y).gAx()
 z=this.dY
 if(z==null?v!=null:z!==v)J.ta(this.xS,v)
-return}}},"call$1","giz",2,0,587,256],
+return}}},"call$1","giz",2,0,580,251,[]],
 bw:function(a,b,c,d){this.Jq=J.xq(a).yI(this.giz())}},
 ir:{
-"":["Ao;AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-oX:function(a){this.Pa(a)},
+"^":["GN;AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+G6:function(a){this.Pa(a)},
 static:{oa:function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -20783,29 +21079,29 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Iv.ZL(a)
-C.Iv.oX(a)
+C.Iv.G6(a)
 return a}}},
-Sa:{
-"":["qE+zs;KM:ZQ=-357",function(){return[C.nJ]}],
+jpR:{
+"^":["qE+zs;KM:X0=-349",function(){return[C.nJ]}],
 $iszs:true,
 $ishs:true,
 $isd3:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true},
-Ao:{
-"":"Sa+Pi;",
+$isKV:true},
+GN:{
+"^":"jpR+Pi;",
 $isd3:true},
-k8:{
-"":"a;jL>,zZ*",
-$isk8:true},
+bS:{
+"^":"a;jL>,zZ*",
+$isbS:true},
 HJ:{
-"":"e9;nF"},
+"^":"e9;nF"},
 S0:{
-"":"a;M3,ih",
+"^":"a;M3,ih",
 Ws:function(){return this.M3.call$0()},
 TP:[function(a){var z=this.ih
 if(z!=null){z.ed()
@@ -20813,110 +21109,110 @@
 tZ:[function(a){if(this.ih!=null){this.TP(0)
 this.Ws()}},"call$0","gv6",0,0,107]},
 V3:{
-"":"a;ns",
+"^":"a;ns",
 $isV3:true},
 Bl:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=$.mC().MM
 if(z.Gv!==0)H.vh(new P.lj("Future already completed"))
 z.OH(null)
-return},"call$1",null,2,0,null,240,"call"],
+return},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Fn:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isRS},"call$1",null,2,0,null,588,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isRS},"call$1",null,2,0,null,581,[],"call"],
 $isEH:true},
 e3:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isMs},"call$1",null,2,0,null,588,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isMs},"call$1",null,2,0,null,581,[],"call"],
 $isEH:true},
 pM:{
-"":"Tp:229;",
-call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,586,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,579,[],"call"],
 $isEH:true},
 jh:{
-"":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{
-"":"",
+"^":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{
+"^":"",
 Zh:[function(a,b,c){var z,y,x
-z=J.UQ($.WJ(),c.gvd())
+z=J.UQ($.CT(),c.gUx())
 if(z!=null)return z.call$2(a,b)
-try{y=C.lM.kV(J.JA(a,"'","\""))
+try{y=C.xr.kV(J.JA(a,"'","\""))
 return y}catch(x){H.Ru(x)
-return a}},"call$3","nn",6,0,null,23,276,11],
+return a}},"call$3","nn",6,0,null,23,[],271,[],11,[]],
 W6:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){var z=P.L5(null,null,null,null,null)
 z.u(0,C.AZ,new Z.Lf())
 z.u(0,C.ok,new Z.fT())
 z.u(0,C.N4,new Z.pp())
-z.u(0,C.Ts,new Z.Nq())
-z.u(0,C.PC,new Z.nl())
-z.u(0,C.md,new Z.ik())
+z.u(0,C.Ts,new Z.nl())
+z.u(0,C.PC,new Z.ik())
+z.u(0,C.md,new Z.LfS())
 return z},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Lf:{
-"":"Tp:349;",
-call$2:[function(a,b){return a},"call$2",null,4,0,null,21,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 fT:{
-"":"Tp:349;",
-call$2:[function(a,b){return a},"call$2",null,4,0,null,21,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 pp:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){var z,y
 try{z=P.Gl(a)
 return z}catch(y){H.Ru(y)
-return b}},"call$2",null,4,0,null,21,589,"call"],
-$isEH:true},
-Nq:{
-"":"Tp:349;",
-call$2:[function(a,b){return!J.de(a,"false")},"call$2",null,4,0,null,21,240,"call"],
+return b}},"call$2",null,4,0,null,21,[],582,[],"call"],
 $isEH:true},
 nl:{
-"":"Tp:349;",
-call$2:[function(a,b){return H.BU(a,null,new Z.mf(b))},"call$2",null,4,0,null,21,589,"call"],
-$isEH:true},
-mf:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return!J.de(a,"false")},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 ik:{
-"":"Tp:349;",
-call$2:[function(a,b){return H.IH(a,new Z.HK(b))},"call$2",null,4,0,null,21,589,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return H.BU(a,null,new Z.mf(b))},"call$2",null,4,0,null,21,[],582,[],"call"],
+$isEH:true},
+mf:{
+"^":"Tp:223;a",
+call$1:[function(a){return this.a},"call$1",null,2,0,null,235,[],"call"],
+$isEH:true},
+LfS:{
+"^":"Tp:341;",
+call$2:[function(a,b){return H.IH(a,new Z.HK(b))},"call$2",null,4,0,null,21,[],582,[],"call"],
 $isEH:true},
 HK:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true}}],["polymer_expressions","package:polymer_expressions/polymer_expressions.dart",,T,{
-"":"",
+"^":"",
 ul:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)z=J.vo(z.gvc(a),new T.o8(a)).zV(0," ")
 else z=typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)?z.zV(a," "):a
-return z},"call$1","qP",2,0,187,277],
+return z},"call$1","qP",2,0,187,272,[]],
 PX:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)z=J.C0(z.gvc(a),new T.ex(a)).zV(0,";")
 else z=typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)?z.zV(a,";"):a
-return z},"call$1","Fx",2,0,187,277],
+return z},"call$1","Fx",2,0,187,272,[]],
 o8:{
-"":"Tp:229;a",
-call$1:[function(a){return J.de(this.a.t(0,a),!0)},"call$1",null,2,0,null,421,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.de(this.a.t(0,a),!0)},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 ex:{
-"":"Tp:229;a",
-call$1:[function(a){return H.d(a)+": "+H.d(this.a.t(0,a))},"call$1",null,2,0,null,421,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return H.d(a)+": "+H.d(this.a.t(0,a))},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 e9:{
-"":"T4;",
-yt:[function(a,b,c){var z,y,x
+"^":"T4;",
+cl:[function(a,b,c){var z,y,x
 if(a==null)return
 z=new Y.hc(H.VM([],[Y.Pn]),P.p9(""),new P.WU(a,0,0,null),null)
 y=new U.tc()
 y=new T.FX(y,z,null,null)
 z=z.zl()
-y.ku=z
+y.qM=z
 y.fL=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])
 y.w5()
 x=y.o9()
@@ -20924,41 +21220,41 @@
 if(z.n(b,"bind")||z.n(b,"repeat")){z=J.x(x)
 z=typeof x==="object"&&x!==null&&!!z.$isEZ}else z=!1}else z=!1
 if(z)return
-return new T.Xy(this,b,x)},"call$3","gca",6,0,590,266,12,265],
-CE:[function(a){return new T.uK(this)},"call$1","gb4",2,0,null,262]},
+return new T.Xy(this,b,x)},"call$3","gca",6,0,583,260,[],12,[],259,[]],
+CE:[function(a){return new T.G0(this)},"call$1","gb4",2,0,null,256,[]]},
 Xy:{
-"":"Tp:349;a,b,c",
+"^":"Tp:341;a,b,c",
 call$2:[function(a,b){var z=J.x(a)
 if(typeof a!=="object"||a===null||!z.$isz6){z=this.a.nF
 a=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}z=J.x(b)
 z=typeof b==="object"&&b!==null&&!!z.$iscv
 if(z&&J.de(this.b,"class"))return T.FL(this.c,a,T.qP())
 if(z&&J.de(this.b,"style"))return T.FL(this.c,a,T.Fx())
-return T.FL(this.c,a,null)},"call$2",null,4,0,null,285,265,"call"],
+return T.FL(this.c,a,null)},"call$2",null,4,0,null,280,[],259,[],"call"],
 $isEH:true},
-uK:{
-"":"Tp:229;a",
+G0:{
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isz6)z=a
 else{z=this.a.nF
-z=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}return z},"call$1",null,2,0,null,285,"call"],
+z=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}return z},"call$1",null,2,0,null,280,[],"call"],
 $isEH:true},
 mY:{
-"":"Pi;a9,Cu,uI,Y7,AP,fn",
+"^":"Pi;a9,Cu,uI,Y7,AP,fn",
 u0:function(a){return this.uI.call$1(a)},
 KX:[function(a){var z,y
 z=this.Y7
 y=J.x(a)
 if(typeof a==="object"&&a!==null&&!!y.$isfk){y=J.C0(a.bm,new T.mB(this,a)).tt(0,!1)
 this.Y7=y}else{y=this.uI==null?a:this.u0(a)
-this.Y7=y}F.Wi(this,C.ls,z,y)},"call$1","gUG",2,0,229,277],
-gP:[function(a){return this.Y7},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+this.Y7=y}F.Wi(this,C.ls,z,y)},"call$1","gUG",2,0,223,272,[]],
+gP:[function(a){return this.Y7},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:[function(a,b){var z,y,x,w
 try{K.jX(this.Cu,b,this.a9)}catch(y){x=H.Ru(y)
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$isB0){z=x
-$.eH().j2("Error evaluating expression '"+H.d(this.Cu)+"': "+J.yj(z))}else throw y}},null,null,3,0,229,277,"value",359],
+$.eH().j2("Error evaluating expression '"+H.d(this.Cu)+"': "+J.yj(z))}else throw y}},null,null,3,0,223,272,[],"value",351],
 yB:function(a,b,c){var z,y,x,w,v
 y=this.Cu
 y.gju().yI(this.gUG()).fm(0,new T.GX(this))
@@ -20968,51 +21264,45 @@
 v=J.x(w)
 if(typeof w==="object"&&w!==null&&!!v.$isB0){z=w
 $.eH().j2("Error evaluating expression '"+H.d(y)+"': "+J.yj(z))}else throw x}},
-static:{FL:function(a,b,c){var z=H.VM(new P.Sw(null,0,0,0),[null])
-z.Eo(null,null)
-z=new T.mY(b,a.RR(0,new K.G1(b,z)),c,null,null,null)
+static:{FL:function(a,b,c){var z=new T.mY(b,a.RR(0,new K.G1(b,P.NZ(null,null))),c,null,null,null)
 z.yB(a,b,c)
 return z}}},
 GX:{
-"":"Tp:229;a",
-call$1:[function(a){$.eH().j2("Error evaluating expression '"+H.d(this.a.Cu)+"': "+H.d(J.yj(a)))},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){$.eH().j2("Error evaluating expression '"+H.d(this.a.Cu)+"': "+H.d(J.yj(a)))},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 mB:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=P.L5(null,null,null,null,null)
 z.u(0,this.b.kF,a)
-return new K.z6(this.a.a9,null,V.WF(z,null,null),null)},"call$1",null,2,0,null,341,"call"],
+return new K.z6(this.a.a9,null,V.WF(z,null,null),null)},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true}}],["polymer_expressions.async","package:polymer_expressions/async.dart",,B,{
-"":"",
+"^":"",
 XF:{
-"":"xh;vq,L1,AP,fn",
-vb:function(a,b){this.vq.yI(new B.iH(b,this))},
+"^":"xh;vq,L1,AP,fn",
+vb:function(a,b){this.vq.yI(new B.bX(b,this))},
 $asxh:function(a){return[null]},
 static:{z4:function(a,b){var z=H.VM(new B.XF(a,null,null,null),[b])
 z.vb(a,b)
 return z}}},
-iH:{
-"":"Tp;a,b",
+bX:{
+"^":"Tp;a,b",
 call$1:[function(a){var z=this.b
-z.L1=F.Wi(z,C.ls,z.L1,a)},"call$1",null,2,0,null,341,"call"],
+z.L1=F.Wi(z,C.ls,z.L1,a)},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"CJ",args:[a]}},this.b,"XF")}}}],["polymer_expressions.eval","package:polymer_expressions/eval.dart",,K,{
-"":"",
-OH:[function(a,b){var z,y
-z=new P.Sw(null,0,0,0)
-z.$builtinTypeInfo=[null]
-z.Eo(null,null)
-y=J.UK(a,new K.G1(b,z))
-J.UK(y,new K.Ed(b))
-return y.gLv()},"call$2","Gk",4,0,null,278,270],
+"^":"",
+OH:[function(a,b){var z=J.UK(a,new K.G1(b,P.NZ(null,null)))
+J.UK(z,new K.Ed(b))
+return z.gLv()},"call$2","ly",4,0,null,273,[],265,[]],
 jX:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 z.a=a
 y=new K.c4(z)
 x=H.VM([],[U.hw])
 for(;w=z.a,v=J.RE(w),typeof w==="object"&&w!==null&&!!v.$isuk;){if(!J.de(v.gkp(w),"|"))break
-x.push(v.gT8(w))
-z.a=v.gBb(w)}w=z.a
+x.push(w.gT8())
+z.a=w.gBb()}w=z.a
 v=J.RE(w)
 if(typeof w==="object"&&w!==null&&!!v.$isw6){u=v.gP(w)
 t=C.OL
@@ -21022,141 +21312,137 @@
 t=z.a.ghP()
 u=J.Vm(z.a.gJn())
 s=!0}else{if(typeof w==="object"&&w!==null&&!!v.$isx9){t=w.ghP()
-u=J.O6(z.a)}else if(typeof w==="object"&&w!==null&&!!v.$isRW){t=w.ghP()
+u=J.O6(z.a)}else if(typeof w==="object"&&w!==null&&!!v.$isJy){t=w.ghP()
 if(J.vF(z.a)!=null){if(z.a.gre()!=null)y.call$0()
 u=J.vF(z.a)}else{y.call$0()
 u=null}}else{y.call$0()
 t=null
 u=null}s=!1}for(z=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);z.G();){r=z.lo
-y=new P.Sw(null,0,0,0)
-y.$builtinTypeInfo=[null]
-y.Eo(null,null)
-q=J.UK(r,new K.G1(c,y))
+q=J.UK(r,new K.G1(c,P.NZ(null,null)))
 J.UK(q,new K.Ed(c))
 q.gLv()
 throw H.b(K.kG("filter must implement Transformer: "+H.d(r)))}p=K.OH(t,c)
 if(p==null)throw H.b(K.kG("Can't assign to null: "+H.d(t)))
 if(s)J.kW(p,u,b)
-else H.vn(p).PU(new H.GD(H.le(u)),b)},"call$3","wA",6,0,null,278,23,270],
+else H.vn(p).PU(new H.GD(H.le(u)),b)},"call$3","wA",6,0,null,273,[],23,[],265,[]],
 ci:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isqh)return B.z4(a,null)
-return a},"call$1","Af",2,0,null,277],
+return a},"call$1","Af",2,0,null,272,[]],
+lP:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.WB(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
+Uf:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.xH(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
 Ra:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.WB(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.p0(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 wJY:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.xH(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.FW(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 zOQ:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.p0(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.de(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 W6o:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.FW(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return!J.de(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 MdQ:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.de(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.z8(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 YJG:{
-"":"Tp:349;",
-call$2:[function(a,b){return!J.de(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.J5(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 DOe:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.z8(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.u6(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 lPa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.J5(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.Hb(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 Ufa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.u6(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a===!0||b===!0},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 Raa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.Hb(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a===!0&&b===!0},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 w0:{
-"":"Tp:349;",
-call$2:[function(a,b){return a===!0||b===!0},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-w4:{
-"":"Tp:349;",
-call$2:[function(a,b){return a===!0&&b===!0},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-w5:{
-"":"Tp:349;",
-call$2:[function(a,b){var z=H.Og(P.a)
+"^":"Tp:341;",
+call$2:[function(a,b){var z=H.uK(P.a)
 z=H.KT(z,[z]).BD(b)
 if(z)return b.call$1(a)
-throw H.b(K.kG("Filters must be a one-argument function."))},"call$2",null,4,0,null,123,110,"call"],
+throw H.b(K.kG("Filters must be a one-argument function."))},"call$2",null,4,0,null,123,[],110,[],"call"],
+$isEH:true},
+w4:{
+"^":"Tp:223;",
+call$1:[function(a){return a},"call$1",null,2,0,null,123,[],"call"],
+$isEH:true},
+w5:{
+"^":"Tp:223;",
+call$1:[function(a){return J.Z7(a)},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 w7:{
-"":"Tp:229;",
-call$1:[function(a){return a},"call$1",null,2,0,null,123,"call"],
-$isEH:true},
-w9:{
-"":"Tp:229;",
-call$1:[function(a){return J.Z7(a)},"call$1",null,2,0,null,123,"call"],
-$isEH:true},
-w10:{
-"":"Tp:229;",
-call$1:[function(a){return a!==!0},"call$1",null,2,0,null,123,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a!==!0},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 c4:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return H.vh(K.kG("Expression is not assignable: "+H.d(this.a.a)))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 z6:{
-"":"a;eT>,k8,bq,G9",
+"^":"a;eT>,k8,bq,G9",
 gCH:function(){var z=this.G9
 if(z!=null)return z
 z=H.vn(this.k8)
 this.G9=z
 return z},
-t:[function(a,b){var z,y,x,w,v
+t:[function(a,b){var z,y,x,w
 if(J.de(b,"this"))return this.k8
 else{z=this.bq.Zp
 if(z.x4(b))return K.ci(z.t(0,b))
-else if(this.k8!=null){z=H.le(b)
-y=new H.GD(z)
+else if(this.k8!=null){y=new H.GD(H.le(b))
 x=Z.y1(H.jO(J.bB(this.gCH().Ax).LU),y)
-w=J.x(x)
-if(typeof x!=="object"||x===null||!w.$isRY)v=typeof x==="object"&&x!==null&&!!w.$isRS&&x.glT()
-else v=!0
-if(v)return K.ci(this.gCH().tu(y,1,z,[]).Ax)
-else if(typeof x==="object"&&x!==null&&!!w.$isRS)return new K.wL(this.gCH(),y)}}z=this.eT
+z=J.x(x)
+if(typeof x!=="object"||x===null||!z.$isRY)w=typeof x==="object"&&x!==null&&!!z.$isRS&&x.glT()
+else w=!0
+if(w)return K.ci(this.gCH().rN(y).gAx())
+else if(typeof x==="object"&&x!==null&&!!z.$isRS)return new K.wL(this.gCH(),y)}}z=this.eT
 if(z!=null)return K.ci(z.t(0,b))
-else throw H.b(K.kG("variable '"+H.d(b)+"' not found"))},"call$1","gIA",2,0,null,12],
+else throw H.b(K.kG("variable '"+H.d(b)+"' not found"))},"call$1","gIA",2,0,null,12,[]],
 tI:[function(a){var z
 if(J.de(a,"this"))return
 else{z=this.bq
 if(z.Zp.x4(a))return z
 else{z=H.le(a)
 if(Z.y1(H.jO(J.bB(this.gCH().Ax).LU),new H.GD(z))!=null)return this.k8}}z=this.eT
-if(z!=null)return z.tI(a)},"call$1","gXe",2,0,null,12],
+if(z!=null)return z.tI(a)},"call$1","gVy",2,0,null,12,[]],
 tg:[function(a,b){var z
 if(this.bq.Zp.x4(b))return!0
 else{z=H.le(b)
 if(Z.y1(H.jO(J.bB(this.gCH().Ax).LU),new H.GD(z))!=null)return!0}z=this.eT
 if(z!=null)return z.tg(0,b)
-return!1},"call$1","gdj",2,0,null,12],
+return!1},"call$1","gdj",2,0,null,12,[]],
 $isz6:true},
-dE:{
-"":"a;bO?,Lv<",
+Mb:{
+"^":"a;bO?,Lv<",
 gju:function(){var z=this.k6
 return H.VM(new P.Ik(z),[H.Kp(z,0)])},
 gLl:function(){return this.Lv},
-Qh:[function(a){},"call$1","gVj",2,0,null,270],
+Qh:[function(a){},"call$1","gVj",2,0,null,265,[]],
 DX:[function(a){var z
 this.yc(0,a)
 z=this.bO
-if(z!=null)z.DX(a)},"call$1","gFO",2,0,null,270],
+if(z!=null)z.DX(a)},"call$1","gFO",2,0,null,265,[]],
 yc:[function(a,b){var z,y,x
 z=this.tj
 if(z!=null){z.ed()
@@ -21165,30 +21451,30 @@
 z=this.Lv
 if(z==null?y!=null:z!==y){x=this.k6
 if(x.Gv>=4)H.vh(x.q7())
-x.Iv(z)}},"call$1","gcz",2,0,null,270],
+x.Iv(z)}},"call$1","gcz",2,0,null,265,[]],
 bu:[function(a){return this.KL.bu(0)},"call$0","gXo",0,0,null],
 $ishw:true},
 Ed:{
-"":"a0;Jd",
-xn:[function(a){a.yc(0,this.Jd)},"call$1","gBe",2,0,null,18],
-ky:[function(a){J.UK(a.gT8(a),this)
-a.yc(0,this.Jd)},"call$1","gXf",2,0,null,283]},
+"^":"cfS;Jd",
+xn:[function(a){a.yc(0,this.Jd)},"call$1","gBe",2,0,null,18,[]],
+ky:[function(a){J.UK(a.gT8(),this)
+a.yc(0,this.Jd)},"call$1","gXf",2,0,null,278,[]]},
 G1:{
-"":"fr;Jd,Le",
-W9:[function(a){return new K.Wh(a,null,null,null,P.bK(null,null,!1,null))},"call$1","glO",2,0,null,18],
-LT:[function(a){return a.wz.RR(0,this)},"call$1","gff",2,0,null,18],
+"^":"fr;Jd,Le",
+W9:[function(a){return new K.Wh(a,null,null,null,P.bK(null,null,!1,null))},"call$1","glO",2,0,null,18,[]],
+LT:[function(a){return a.wz.RR(0,this)},"call$1","gff",2,0,null,18,[]],
 co:[function(a){var z,y
 z=J.UK(a.ghP(),this)
 y=new K.vl(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(y)
-return y},"call$1","gfz",2,0,null,354],
+return y},"call$1","gEW",2,0,null,346,[]],
 CU:[function(a){var z,y,x
 z=J.UK(a.ghP(),this)
 y=J.UK(a.gJn(),this)
 x=new K.iT(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","gA2",2,0,null,341],
+return x},"call$1","gA2",2,0,null,383,[]],
 ZR:[function(a){var z,y,x,w,v
 z=J.UK(a.ghP(),this)
 y=a.gre()
@@ -21198,115 +21484,115 @@
 x=H.VM(new H.A8(y,w),[null,null]).tt(0,!1)}v=new K.fa(z,x,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(v)
 if(x!=null){x.toString
-H.bQ(x,new K.Os(v))}return v},"call$1","gZo",2,0,null,341],
-ti:[function(a){return new K.x5(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gXj",2,0,null,279],
+H.bQ(x,new K.Os(v))}return v},"call$1","gES",2,0,null,383,[]],
+ti:[function(a){return new K.x5(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gXj",2,0,null,274,[]],
 o0:[function(a){var z,y
 z=H.VM(new H.A8(a.gPu(a),this.gnG()),[null,null]).tt(0,!1)
 y=new K.ev(z,a,null,null,null,P.bK(null,null,!1,null))
 H.bQ(z,new K.B8(y))
-return y},"call$1","gX7",2,0,null,279],
+return y},"call$1","gX7",2,0,null,274,[]],
 YV:[function(a){var z,y,x
 z=J.UK(a.gG3(a),this)
 y=J.UK(a.gv4(),this)
-x=new K.jV(z,y,a,null,null,null,P.bK(null,null,!1,null))
+x=new K.qR(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","gbU",2,0,null,18],
-qv:[function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gFs",2,0,null,341],
+return x},"call$1","gbU",2,0,null,18,[]],
+qv:[function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gFs",2,0,null,383,[]],
 im:[function(a){var z,y,x
-z=J.UK(a.gBb(a),this)
-y=J.UK(a.gT8(a),this)
+z=J.UK(a.gBb(),this)
+y=J.UK(a.gT8(),this)
 x=new K.mG(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","glf",2,0,null,91],
+return x},"call$1","glf",2,0,null,91,[]],
 Hx:[function(a){var z,y
 z=J.UK(a.gwz(),this)
-y=new K.Jy(z,a,null,null,null,P.bK(null,null,!1,null))
+y=new K.mv(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(y)
-return y},"call$1","gKY",2,0,null,91],
+return y},"call$1","gKY",2,0,null,91,[]],
 ky:[function(a){var z,y,x
-z=J.UK(a.gBb(a),this)
-y=J.UK(a.gT8(a),this)
+z=J.UK(a.gBb(),this)
+y=J.UK(a.gT8(),this)
 x=new K.VA(z,y,a,null,null,null,P.bK(null,null,!1,null))
 y.sbO(x)
-return x},"call$1","gXf",2,0,null,341]},
+return x},"call$1","gXf",2,0,null,383,[]]},
 Os:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 a.sbO(z)
-return z},"call$1",null,2,0,null,123,"call"],
+return z},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 B8:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 a.sbO(z)
-return z},"call$1",null,2,0,null,18,"call"],
+return z},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Wh:{
-"":"dE;KL,bO,tj,Lv,k6",
-Qh:[function(a){this.Lv=a.k8},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.EZ]},
+"^":"Mb;KL,bO,tj,Lv,k6",
+Qh:[function(a){this.Lv=a.k8},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.EZ]},
 $isEZ:true,
 $ishw:true},
 x5:{
-"":"dE;KL,bO,tj,Lv,k6",
+"^":"Mb;KL,bO,tj,Lv,k6",
 gP:function(a){var z=this.KL
 return z.gP(z)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 Qh:[function(a){var z=this.KL
-this.Lv=z.gP(z)},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.no]},
+this.Lv=z.gP(z)},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.no]},
 $asno:function(){return[null]},
 $isno:true,
 $ishw:true},
 ev:{
-"":"dE;Pu>,KL,bO,tj,Lv,k6",
-Qh:[function(a){this.Lv=H.n3(this.Pu,P.L5(null,null,null,null,null),new K.ID())},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.kB]},
+"^":"Mb;Pu>,KL,bO,tj,Lv,k6",
+Qh:[function(a){this.Lv=H.n3(this.Pu,P.L5(null,null,null,null,null),new K.ID())},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.kB]},
 $iskB:true,
 $ishw:true},
 ID:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){J.kW(a,J.WI(b).gLv(),b.gv4().gLv())
-return a},"call$2",null,4,0,null,183,18,"call"],
+return a},"call$2",null,4,0,null,183,[],18,[],"call"],
 $isEH:true},
-jV:{
-"":"dE;G3>,v4<,KL,bO,tj,Lv,k6",
-RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.ae]},
+qR:{
+"^":"Mb;G3>,v4<,KL,bO,tj,Lv,k6",
+RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.ae]},
 $isae:true,
 $ishw:true},
 ek:{
-"":"dE;KL,bO,tj,Lv,k6",
+"^":"Mb;KL,bO,tj,Lv,k6",
 gP:function(a){var z=this.KL
 return z.gP(z)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 Qh:[function(a){var z,y,x
 z=this.KL
 this.Lv=a.t(0,z.gP(z))
 y=a.tI(z.gP(z))
 x=J.RE(y)
 if(typeof y==="object"&&y!==null&&!!x.$isd3){z=H.le(z.gP(z))
-this.tj=x.gUj(y).yI(new K.Qv(this,a,new H.GD(z)))}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.w6]},
+this.tj=x.gUj(y).yI(new K.Qv(this,a,new H.GD(z)))}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.w6]},
 $isw6:true,
 $ishw:true},
 Qv:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.Xm(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.Xm(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 Xm:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
-Jy:{
-"":"dE;wz<,KL,bO,tj,Lv,k6",
+mv:{
+"^":"Mb;wz<,KL,bO,tj,Lv,k6",
 gkp:function(a){var z=this.KL
 return z.gkp(z)},
 Qh:[function(a){var z,y
@@ -21314,13 +21600,13 @@
 y=$.ww().t(0,z.gkp(z))
 if(J.de(z.gkp(z),"!")){z=this.wz.gLv()
 this.Lv=y.call$1(z==null?!1:z)}else{z=this.wz
-this.Lv=z.gLv()==null?null:y.call$1(z.gLv())}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.jK]},
+this.Lv=z.gLv()==null?null:y.call$1(z.gLv())}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.jK]},
 $isjK:true,
 $ishw:true},
 mG:{
-"":"dE;Bb>,T8>,KL,bO,tj,Lv,k6",
+"^":"Mb;Bb<,T8<,KL,bO,tj,Lv,k6",
 gkp:function(a){var z=this.KL
 return z.gkp(z)},
 Qh:[function(a){var z,y,x,w
@@ -21337,17 +21623,17 @@
 w=typeof z==="object"&&z!==null&&!!w.$iswn
 z=w}else z=!1
 if(z)this.tj=H.Go(x.gLv(),"$iswn").gvp().yI(new K.uA(this,a))
-this.Lv=y.call$2(x.gLv(),this.T8.gLv())}}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.uk]},
+this.Lv=y.call$2(x.gLv(),this.T8.gLv())}}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.uk]},
 $isuk:true,
 $ishw:true},
 uA:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 vl:{
-"":"dE;hP<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,KL,bO,tj,Lv,k6",
 goc:function(a){var z=this.KL
 return z.goc(z)},
 Qh:[function(a){var z,y,x
@@ -21355,46 +21641,46 @@
 if(z==null){this.Lv=null
 return}y=this.KL
 x=new H.GD(H.le(y.goc(y)))
-this.Lv=H.vn(z).rN(x).Ax
+this.Lv=H.vn(z).rN(x).gAx()
 y=J.RE(z)
-if(typeof z==="object"&&z!==null&&!!y.$isd3)this.tj=y.gUj(z).yI(new K.Li(this,a,x))},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.x9]},
+if(typeof z==="object"&&z!==null&&!!y.$isd3)this.tj=y.gUj(z).yI(new K.Li(this,a,x))},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.x9]},
 $isx9:true,
 $ishw:true},
 Li:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.WK(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.WK(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 WK:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 iT:{
-"":"dE;hP<,Jn<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,Jn<,KL,bO,tj,Lv,k6",
 Qh:[function(a){var z,y,x
 z=this.hP.gLv()
 if(z==null){this.Lv=null
 return}y=this.Jn.gLv()
 x=J.U6(z)
 this.Lv=x.t(z,y)
-if(typeof z==="object"&&z!==null&&!!x.$isd3)this.tj=x.gUj(z).yI(new K.ja(this,a,y))},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.zX]},
+if(typeof z==="object"&&z!==null&&!!x.$isd3)this.tj=x.gUj(z).yI(new K.ja(this,a,y))},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.zX]},
 $iszX:true,
 $ishw:true},
 ja:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.zw(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.zw(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 zw:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isHA&&J.de(a.G3,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isHA&&J.de(a.G3,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 fa:{
-"":"dE;hP<,re<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,re<,KL,bO,tj,Lv,k6",
 gbP:function(a){var z=this.KL
 return z.gbP(z)},
 Qh:[function(a){var z,y,x,w
@@ -21408,26 +21694,26 @@
 this.Lv=K.ci(typeof x==="object"&&x!==null&&!!z.$iswL?x.lR.F2(x.ex,y,null).Ax:H.Ek(x,y,P.Te(null)))}else{w=new H.GD(H.le(z.gbP(z)))
 this.Lv=H.vn(x).F2(w,y,null).Ax
 z=J.RE(x)
-if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gUj(x).yI(new K.vQ(this,a,w))}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.RW]},
-$isRW:true,
+if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gUj(x).yI(new K.vQ(this,a,w))}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.Jy]},
+$isJy:true,
 $ishw:true},
 WW:{
-"":"Tp:229;",
-call$1:[function(a){return a.gLv()},"call$1",null,2,0,null,123,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a.gLv()},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 vQ:{
-"":"Tp:558;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.a9(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:559;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.a9(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 a9:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 VA:{
-"":"dE;Bb>,T8>,KL,bO,tj,Lv,k6",
+"^":"Mb;Bb<,T8<,KL,bO,tj,Lv,k6",
 Qh:[function(a){var z,y,x,w
 z=this.Bb
 y=this.T8.gLv()
@@ -21436,30 +21722,30 @@
 if(typeof y==="object"&&y!==null&&!!x.$iswn)this.tj=y.gvp().yI(new K.J1(this,a))
 x=J.Vm(z)
 w=y!=null?y:C.xD
-this.Lv=new K.fk(x,w)},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.K9]},
+this.Lv=new K.fk(x,w)},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.K9]},
 $isK9:true,
 $ishw:true},
 J1:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 fk:{
-"":"a;kF,bm",
+"^":"a;kF,bm",
 $isfk:true},
 wL:{
-"":"a:229;lR,ex",
-call$1:[function(a){return this.lR.F2(this.ex,[a],null).Ax},"call$1","gQl",2,0,null,591],
+"^":"a:223;lR,ex",
+call$1:[function(a){return this.lR.F2(this.ex,[a],null).Ax},"call$1","gtm",2,0,null,584,[]],
 $iswL:true,
 $isEH:true},
 B0:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"EvalException: "+this.G1},"call$0","gXo",0,0,null],
 $isB0:true,
 static:{kG:function(a){return new K.B0(a)}}}}],["polymer_expressions.expression","package:polymer_expressions/expression.dart",,U,{
-"":"",
-Om:[function(a,b){var z,y,x
+"^":"",
+Pu:[function(a,b){var z,y,x
 z=J.x(a)
 if(z.n(a,b))return!0
 if(a==null||b==null)return!1
@@ -21470,106 +21756,106 @@
 if(!(y<x))break
 x=z.t(a,y)
 if(y>=b.length)return H.e(b,y)
-if(!J.de(x,b[y]))return!1;++y}return!0},"call$2","Cb",4,0,null,123,180],
+if(!J.de(x,b[y]))return!1;++y}return!0},"call$2","OE",4,0,null,123,[],180,[]],
 au:[function(a){a.toString
-return U.Up(H.n3(a,0,new U.xs()))},"call$1","bT",2,0,null,279],
+return U.Up(H.n3(a,0,new U.xs()))},"call$1","bT",2,0,null,274,[]],
 Zm:[function(a,b){var z=J.WB(a,b)
 if(typeof z!=="number")return H.s(z)
 a=536870911&z
 a=536870911&a+((524287&a)<<10>>>0)
-return a^a>>>6},"call$2","uN",4,0,null,280,23],
+return a^a>>>6},"call$2","uN",4,0,null,275,[],23,[]],
 Up:[function(a){if(typeof a!=="number")return H.s(a)
 a=536870911&a+((67108863&a)<<3>>>0)
 a=(a^a>>>11)>>>0
-return 536870911&a+((16383&a)<<15>>>0)},"call$1","fM",2,0,null,280],
+return 536870911&a+((16383&a)<<15>>>0)},"call$1","fM",2,0,null,275,[]],
 tc:{
-"":"a;",
-Bf:[function(a,b,c){return new U.zX(b,c)},"call$2","gvH",4,0,592,18,123],
-F2:[function(a,b,c){return new U.RW(a,b,c)},"call$3","gb2",6,0,null,18,183,123]},
+"^":"a;",
+Bf:[function(a,b,c){return new U.zX(b,c)},"call$2","gvH",4,0,585,18,[],123,[]],
+F2:[function(a,b,c){return new U.Jy(a,b,c)},"call$3","gb2",6,0,null,18,[],183,[],123,[]]},
 hw:{
-"":"a;",
+"^":"a;",
 $ishw:true},
 EZ:{
-"":"hw;",
-RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;",
+RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,272,[]],
 $isEZ:true},
 no:{
-"":"hw;P>",
+"^":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
-RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,277],
+RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){var z=this.P
 return typeof z==="string"?"\""+H.d(z)+"\"":H.d(z)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=H.RB(b,"$isno",[H.Kp(this,0)],"$asno")
-return z&&J.de(J.Vm(b),this.P)},"call$1","gUJ",2,0,null,91],
+return z&&J.de(J.Vm(b),this.P)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.P)},
 $isno:true},
 kB:{
-"":"hw;Pu>",
-RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;Pu>",
+RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"{"+H.d(this.Pu)+"}"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$iskB&&U.Om(z.gPu(b),this.Pu)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$iskB&&U.Pu(z.gPu(b),this.Pu)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return U.au(this.Pu)},
 $iskB:true},
 ae:{
-"":"hw;G3>,v4<",
-RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;G3>,v4<",
+RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.G3)+": "+H.d(this.v4)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isae&&J.de(z.gG3(b),this.G3)&&J.de(b.gv4(),this.v4)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isae&&J.de(z.gG3(b),this.G3)&&J.de(b.gv4(),this.v4)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.G3.P)
 y=J.v1(this.v4)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isae:true},
 XC:{
-"":"hw;wz",
-RR:[function(a,b){return b.LT(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;wz",
+RR:[function(a,b){return b.LT(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.wz)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isXC&&J.de(b.wz,this.wz)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isXC&&J.de(b.wz,this.wz)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.wz)},
 $isXC:true},
 w6:{
-"":"hw;P>",
+"^":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
-RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,277],
+RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return this.P},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isw6&&J.de(z.gP(b),this.P)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isw6&&J.de(z.gP(b),this.P)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.P)},
 $isw6:true},
 jK:{
-"":"hw;kp>,wz<",
-RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;kp>,wz<",
+RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.kp)+" "+H.d(this.wz)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isjK&&J.de(z.gkp(b),this.kp)&&J.de(b.gwz(),this.wz)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isjK&&J.de(z.gkp(b),this.kp)&&J.de(b.gwz(),this.wz)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.kp)
 y=J.v1(this.wz)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isjK:true},
 uk:{
-"":"hw;kp>,Bb>,T8>",
-RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;kp>,Bb<,T8<",
+RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.Bb)+" "+H.d(this.kp)+" "+H.d(this.T8)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isuk&&J.de(z.gkp(b),this.kp)&&J.de(z.gBb(b),this.Bb)&&J.de(z.gT8(b),this.T8)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isuk&&J.de(z.gkp(b),this.kp)&&J.de(b.gBb(),this.Bb)&&J.de(b.gT8(),this.T8)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y,x
 z=J.v1(this.kp)
 y=J.v1(this.Bb)
@@ -21577,13 +21863,13 @@
 return U.Up(U.Zm(U.Zm(U.Zm(0,z),y),x))},
 $isuk:true},
 K9:{
-"":"hw;Bb>,T8>",
-RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;Bb<,T8<",
+RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.Bb)+" in "+H.d(this.T8)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
-z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isK9&&J.de(z.gBb(b),this.Bb)&&J.de(z.gT8(b),this.T8)},"call$1","gUJ",2,0,null,91],
+z=J.x(b)
+return typeof b==="object"&&b!==null&&!!z.$isK9&&J.de(b.gBb(),this.Bb)&&J.de(b.gT8(),this.T8)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=this.Bb
 z=z.giO(z)
@@ -21591,64 +21877,64 @@
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isK9:true},
 zX:{
-"":"hw;hP<,Jn<",
-RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;hP<,Jn<",
+RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"["+H.d(this.Jn)+"]"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iszX&&J.de(b.ghP(),this.hP)&&J.de(b.gJn(),this.Jn)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$iszX&&J.de(b.ghP(),this.hP)&&J.de(b.gJn(),this.Jn)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.hP)
 y=J.v1(this.Jn)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $iszX:true},
 x9:{
-"":"hw;hP<,oc>",
-RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;hP<,oc>",
+RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"."+H.d(this.oc)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isx9&&J.de(b.ghP(),this.hP)&&J.de(z.goc(b),this.oc)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isx9&&J.de(b.ghP(),this.hP)&&J.de(z.goc(b),this.oc)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.hP)
 y=J.v1(this.oc)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isx9:true},
-RW:{
-"":"hw;hP<,bP>,re<",
-RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,277],
+Jy:{
+"^":"hw;hP<,bP>,re<",
+RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"."+H.d(this.bP)+"("+H.d(this.re)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isRW&&J.de(b.ghP(),this.hP)&&J.de(z.gbP(b),this.bP)&&U.Om(b.gre(),this.re)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isJy&&J.de(b.ghP(),this.hP)&&J.de(z.gbP(b),this.bP)&&U.Pu(b.gre(),this.re)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y,x
 z=J.v1(this.hP)
 y=J.v1(this.bP)
 x=U.au(this.re)
 return U.Up(U.Zm(U.Zm(U.Zm(0,z),y),x))},
-$isRW:true},
+$isJy:true},
 xs:{
-"":"Tp:349;",
-call$2:[function(a,b){return U.Zm(a,J.v1(b))},"call$2",null,4,0,null,593,594,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return U.Zm(a,J.v1(b))},"call$2",null,4,0,null,586,[],587,[],"call"],
 $isEH:true}}],["polymer_expressions.parser","package:polymer_expressions/parser.dart",,T,{
-"":"",
+"^":"",
 FX:{
-"":"a;Sk,ks,ku,fL",
+"^":"a;Sk,GP,qM,fL",
 XJ:[function(a,b){var z
 if(!(a!=null&&!J.de(J.Iz(this.fL.lo),a)))z=b!=null&&!J.de(J.Vm(this.fL.lo),b)
 else z=!0
 if(z)throw H.b(Y.RV("Expected "+b+": "+H.d(this.fL.lo)))
-this.fL.G()},function(){return this.XJ(null,null)},"w5","call$2",null,"gnp",0,4,null,77,77,530,23],
+this.fL.G()},function(){return this.XJ(null,null)},"w5","call$2",null,"gXO",0,4,null,77,77,588,[],23,[]],
 o9:[function(){if(this.fL.lo==null){this.Sk.toString
 return C.OL}var z=this.Dl()
 return z==null?null:this.BH(z,0)},"call$0","gKx",0,0,null],
 BH:[function(a,b){var z,y,x,w,v
 for(z=this.Sk;y=this.fL.lo,y!=null;)if(J.de(J.Iz(y),9))if(J.de(J.Vm(this.fL.lo),"(")){x=this.qj()
 z.toString
-a=new U.RW(a,null,x)}else if(J.de(J.Vm(this.fL.lo),"[")){w=this.eY()
+a=new U.Jy(a,null,x)}else if(J.de(J.Vm(this.fL.lo),"[")){w=this.eY()
 z.toString
 a=new U.zX(a,w)}else break
 else if(J.de(J.Iz(this.fL.lo),3)){this.w5()
@@ -21659,18 +21945,18 @@
 z.toString
 a=new U.K9(a,v)}else if(J.de(J.Iz(this.fL.lo),8)&&J.J5(this.fL.lo.gG8(),b))a=this.Tw(a)
 else break
-return a},"call$2","gHr",4,0,null,126,595],
+return a},"call$2","gHr",4,0,null,126,[],589,[]],
 qL:[function(a,b){var z,y
 if(typeof b==="object"&&b!==null&&!!b.$isw6){z=b.gP(b)
 this.Sk.toString
-return new U.x9(a,z)}else{if(typeof b==="object"&&b!==null&&!!b.$isRW){z=b.ghP()
+return new U.x9(a,z)}else{if(typeof b==="object"&&b!==null&&!!b.$isJy){z=b.ghP()
 y=J.x(z)
 y=typeof z==="object"&&z!==null&&!!y.$isw6
 z=y}else z=!1
 if(z){z=J.Vm(b.ghP())
 y=b.gre()
 this.Sk.toString
-return new U.RW(a,z,y)}else throw H.b(Y.RV("expected identifier: "+H.d(b)))}},"call$2","gE5",4,0,null,126,127],
+return new U.Jy(a,z,y)}else throw H.b(Y.RV("expected identifier: "+H.d(b)))}},"call$2","gE5",4,0,null,126,[],127,[]],
 Tw:[function(a){var z,y,x
 z=this.fL.lo
 this.w5()
@@ -21681,7 +21967,7 @@
 if(!x)break
 y=this.BH(y,this.fL.lo.gG8())}x=J.Vm(z)
 this.Sk.toString
-return new U.uk(x,a,y)},"call$1","gvB",2,0,null,126],
+return new U.uk(x,a,y)},"call$1","gvB",2,0,null,126,[]],
 Dl:[function(){var z,y,x,w
 if(J.de(J.Iz(this.fL.lo),8)){z=J.Vm(this.fL.lo)
 y=J.x(z)
@@ -21750,7 +22036,7 @@
 y=new U.w6(z)
 x=this.qj()
 if(x==null)return y
-else return new U.RW(y,null,x)},"call$0","gbc",0,0,null],
+else return new U.Jy(y,null,x)},"call$0","gbc",0,0,null],
 qj:[function(){var z,y
 z=this.fL.lo
 if(z!=null&&J.de(J.Iz(z),9)&&J.de(J.Vm(this.fL.lo),"(")){y=[]
@@ -21759,7 +22045,7 @@
 y.push(this.o9())
 z=this.fL.lo}while(z!=null&&J.de(J.Vm(z),","))
 this.XJ(9,")")
-return y}return},"call$0","gwm",0,0,null],
+return y}return},"call$0","gxZ",0,0,null],
 eY:[function(){var z,y
 z=this.fL.lo
 if(z!=null&&J.de(J.Iz(z),9)&&J.de(J.Vm(this.fL.lo),"[")){this.w5()
@@ -21777,31 +22063,31 @@
 this.Sk.toString
 y=H.VM(new U.no(z),[null])
 this.w5()
-return y},function(){return this.pT("")},"Ud","call$1",null,"gwo",0,2,null,334,596],
-yj:[function(a){var z,y
+return y},function(){return this.pT("")},"Ud","call$1",null,"gwo",0,2,null,328,590,[]],
+Fj:[function(a){var z,y
 z=H.IH(H.d(a)+H.d(J.Vm(this.fL.lo)),null)
 this.Sk.toString
 y=H.VM(new U.no(z),[null])
 this.w5()
-return y},function(){return this.yj("")},"tw","call$1",null,"gSE",0,2,null,334,596]}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{
-"":"",
-Dc:[function(a){return H.VM(new K.Bt(a),[null])},"call$1","UM",2,0,281,109],
+return y},function(){return this.Fj("")},"tw","call$1",null,"gSE",0,2,null,328,590,[]]}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{
+"^":"",
+Dc:[function(a){return H.VM(new K.Bt(a),[null])},"call$1","UM",2,0,276,109,[]],
 Ae:{
-"":"a;vH>-476,P>-597",
+"^":"a;vH>-475,P>-591",
 r6:function(a,b){return this.P.call$1(b)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isAe&&J.de(b.vH,this.vH)&&J.de(b.P,this.P)},"call$1","gUJ",2,0,229,91,"=="],
-giO:[function(a){return J.v1(this.P)},null,null,1,0,478,"hashCode"],
-bu:[function(a){return"("+H.d(this.vH)+", "+H.d(this.P)+")"},"call$0","gXo",0,0,369,"toString"],
+return typeof b==="object"&&b!==null&&!!z.$isAe&&J.de(b.vH,this.vH)&&J.de(b.P,this.P)},"call$1","gUJ",2,0,223,91,[],"=="],
+giO:[function(a){return J.v1(this.P)},null,null,1,0,482,"hashCode"],
+bu:[function(a){return"("+H.d(this.vH)+", "+H.d(this.P)+")"},"call$0","gXo",0,0,362,"toString"],
 $isAe:true,
 "@":function(){return[C.nJ]},
 "<>":[3],
-static:{i0:[function(a,b,c){return H.VM(new K.Ae(a,b),[c])},null,null,4,0,function(){return H.IG(function(a){return{func:"GR",args:[J.im,a]}},this.$receiver,"Ae")},47,23,"new IndexedValue" /* new IndexedValue:2:0 */]}},
+static:{i0:[function(a,b,c){return H.VM(new K.Ae(a,b),[c])},null,null,4,0,function(){return H.IG(function(a){return{func:"GR",args:[J.im,a]}},this.$receiver,"Ae")},47,[],23,[],"new IndexedValue"]}},
 "+IndexedValue":[0],
 Bt:{
-"":"mW;YR",
+"^":"mW;YR",
 gA:function(a){var z=new K.vR(J.GP(this.YR),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
@@ -21815,11 +22101,11 @@
 return z},
 Zv:[function(a,b){var z=new K.Ae(b,J.i4(this.YR,b))
 z.$builtinTypeInfo=this.$builtinTypeInfo
-return z},"call$1","goY",2,0,null,47],
+return z},"call$1","goY",2,0,null,47,[]],
 $asmW:function(a){return[[K.Ae,a]]},
 $ascX:function(a){return[[K.Ae,a]]}},
 vR:{
-"":"Yl;WS,wX,CD",
+"^":"Yl;WS,wX,CD",
 gl:function(){return this.CD},
 G:[function(){var z,y
 z=this.WS
@@ -21827,33 +22113,33 @@
 this.wX=y+1
 this.CD=H.VM(new K.Ae(y,z.gl()),[null])
 return!0}this.CD=null
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 $asYl:function(a){return[[K.Ae,a]]}}}],["polymer_expressions.src.mirrors","package:polymer_expressions/src/mirrors.dart",,Z,{
-"":"",
+"^":"",
 y1:[function(a,b){var z,y,x
 if(a.gYK().nb.x4(b))return a.gYK().nb.t(0,b)
 z=a.gAY()
-if(z!=null&&!J.de(z.gvd(),C.PU)){y=Z.y1(a.gAY(),b)
+if(z!=null&&!J.de(z.gUx(),C.PU)){y=Z.y1(a.gAY(),b)
 if(y!=null)return y}for(x=J.GP(a.gkZ());x.G();){y=Z.y1(x.lo,b)
-if(y!=null)return y}return},"call$2","tm",4,0,null,282,12]}],["polymer_expressions.tokenizer","package:polymer_expressions/tokenizer.dart",,Y,{
-"":"",
+if(y!=null)return y}return},"call$2","tm",4,0,null,277,[],12,[]]}],["polymer_expressions.tokenizer","package:polymer_expressions/tokenizer.dart",,Y,{
+"^":"",
 aK:[function(a){switch(a){case 102:return 12
 case 110:return 10
 case 114:return 13
 case 116:return 9
 case 118:return 11
-default:return a}},"call$1","aN",2,0,null,283],
+default:return a}},"call$1","aN",2,0,null,278,[]],
 Pn:{
-"":"a;fY>,P>,G8<",
+"^":"a;fY>,P>,G8<",
 r6:function(a,b){return this.P.call$1(b)},
 bu:[function(a){return"("+this.fY+", '"+this.P+"')"},"call$0","gXo",0,0,null],
 $isPn:true},
 hc:{
-"":"a;MV,zy,jI,x0",
+"^":"a;MV,zy,jI,VQ",
 zl:[function(){var z,y,x,w,v,u,t,s,r
 z=this.jI
-this.x0=z.G()?z.Wn:null
-for(y=this.MV;x=this.x0,x!=null;)if(x===32||x===9||x===160)this.x0=z.G()?z.Wn:null
+this.VQ=z.G()?z.Wn:null
+for(y=this.MV;x=this.VQ,x!=null;)if(x===32||x===9||x===160)this.VQ=z.G()?z.Wn:null
 else if(x===34||x===39)this.DS()
 else{if(typeof x!=="number")return H.s(x)
 if(!(97<=x&&x<=122))w=65<=x&&x<=90||x===95||x===36||x>127
@@ -21861,44 +22147,44 @@
 if(w)this.zI()
 else if(48<=x&&x<=57)this.jj()
 else if(x===46){x=z.G()?z.Wn:null
-this.x0=x
+this.VQ=x
 if(typeof x!=="number")return H.s(x)
 if(48<=x&&x<=57)this.e1()
-else y.push(new Y.Pn(3,".",11))}else if(x===44){this.x0=z.G()?z.Wn:null
-y.push(new Y.Pn(4,",",0))}else if(x===58){this.x0=z.G()?z.Wn:null
-y.push(new Y.Pn(5,":",0))}else if(C.Nm.tg(C.xu,x)){v=this.x0
+else y.push(new Y.Pn(3,".",11))}else if(x===44){this.VQ=z.G()?z.Wn:null
+y.push(new Y.Pn(4,",",0))}else if(x===58){this.VQ=z.G()?z.Wn:null
+y.push(new Y.Pn(5,":",0))}else if(C.Nm.tg(C.xu,x)){v=this.VQ
 x=z.G()?z.Wn:null
-this.x0=x
-if(C.Nm.tg(C.xu,x)){x=this.x0
+this.VQ=x
+if(C.Nm.tg(C.xu,x)){x=this.VQ
 u=H.eT([v,x])
-if(C.Nm.tg(C.u0,u)){this.x0=z.G()?z.Wn:null
+if(C.Nm.tg(C.u0,u)){this.VQ=z.G()?z.Wn:null
 t=u}else{s=P.O8(1,v,J.im)
 t=H.eT(s)}}else{s=P.O8(1,v,J.im)
-t=H.eT(s)}y.push(new Y.Pn(8,t,C.dj.t(0,t)))}else if(C.Nm.tg(C.iq,this.x0)){s=P.O8(1,this.x0,J.im)
+t=H.eT(s)}y.push(new Y.Pn(8,t,C.dj.t(0,t)))}else if(C.Nm.tg(C.iq,this.VQ)){s=P.O8(1,this.VQ,J.im)
 r=H.eT(s)
 y.push(new Y.Pn(9,r,C.dj.t(0,r)))
-this.x0=z.G()?z.Wn:null}else this.x0=z.G()?z.Wn:null}return y},"call$0","gty",0,0,null],
+this.VQ=z.G()?z.Wn:null}else this.VQ=z.G()?z.Wn:null}return y},"call$0","gty",0,0,null],
 DS:[function(){var z,y,x,w,v
-z=this.x0
+z=this.VQ
 y=this.jI
 x=y.G()?y.Wn:null
-this.x0=x
+this.VQ=x
 for(w=this.zy;x==null?z!=null:x!==z;){if(x==null)throw H.b(Y.RV("unterminated string"))
 if(x===92){x=y.G()?y.Wn:null
-this.x0=x
+this.VQ=x
 if(x==null)throw H.b(Y.RV("unterminated string"))
 v=P.O8(1,Y.aK(x),J.im)
 x=H.eT(v)
 w.vM=w.vM+x}else{v=P.O8(1,x,J.im)
 x=H.eT(v)
 w.vM=w.vM+x}x=y.G()?y.Wn:null
-this.x0=x}this.MV.push(new Y.Pn(1,w.vM,0))
+this.VQ=x}this.MV.push(new Y.Pn(1,w.vM,0))
 w.vM=""
-this.x0=y.G()?y.Wn:null},"call$0","gxs",0,0,null],
+this.VQ=y.G()?y.Wn:null},"call$0","gxs",0,0,null],
 zI:[function(){var z,y,x,w,v,u
 z=this.jI
 y=this.zy
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 if(!(97<=x&&x<=122))if(!(65<=x&&x<=90))w=48<=x&&x<=57||x===95||x===36||x>127
 else w=!0
@@ -21907,7 +22193,7 @@
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 y.vM=y.vM+x
-this.x0=z.G()?z.Wn:null}u=y.vM
+this.VQ=z.G()?z.Wn:null}u=y.vM
 z=this.MV
 if(C.Nm.tg(C.Qy,u))z.push(new Y.Pn(10,u,0))
 else z.push(new Y.Pn(2,u,0))
@@ -21915,15 +22201,15 @@
 jj:[function(){var z,y,x,w,v
 z=this.jI
 y=this.zy
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 w=48<=x&&x<=57}else w=!1
 if(!w)break
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 y.vM=y.vM+x
-this.x0=z.G()?z.Wn:null}if(x===46){z=z.G()?z.Wn:null
-this.x0=z
+this.VQ=z.G()?z.Wn:null}if(x===46){z=z.G()?z.Wn:null
+this.VQ=z
 if(typeof z!=="number")return H.s(z)
 if(48<=z&&z<=57)this.e1()
 else this.MV.push(new Y.Pn(3,".",11))}else{this.MV.push(new Y.Pn(6,y.vM,0))
@@ -21932,57 +22218,57 @@
 z=this.zy
 z.KF(P.fc(46))
 y=this.jI
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 w=48<=x&&x<=57}else w=!1
 if(!w)break
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 z.vM=z.vM+x
-this.x0=y.G()?y.Wn:null}this.MV.push(new Y.Pn(7,z.vM,0))
+this.VQ=y.G()?y.Wn:null}this.MV.push(new Y.Pn(7,z.vM,0))
 z.vM=""},"call$0","gba",0,0,null]},
 hA:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"ParseException: "+this.G1},"call$0","gXo",0,0,null],
 static:{RV:function(a){return new Y.hA(a)}}}}],["polymer_expressions.visitor","package:polymer_expressions/visitor.dart",,S,{
-"":"",
+"^":"",
 fr:{
-"":"a;",
-DV:[function(a){return J.UK(a,this)},"call$1","gnG",2,0,598,86]},
-a0:{
-"":"fr;",
-W9:[function(a){return this.xn(a)},"call$1","glO",2,0,null,18],
+"^":"a;",
+DV:[function(a){return J.UK(a,this)},"call$1","gnG",2,0,592,86,[]]},
+cfS:{
+"^":"fr;",
+W9:[function(a){return this.xn(a)},"call$1","glO",2,0,null,18,[]],
 LT:[function(a){a.wz.RR(0,this)
-this.xn(a)},"call$1","gff",2,0,null,18],
+this.xn(a)},"call$1","gff",2,0,null,18,[]],
 co:[function(a){J.UK(a.ghP(),this)
-this.xn(a)},"call$1","gfz",2,0,null,341],
+this.xn(a)},"call$1","gEW",2,0,null,383,[]],
 CU:[function(a){J.UK(a.ghP(),this)
 J.UK(a.gJn(),this)
-this.xn(a)},"call$1","gA2",2,0,null,341],
+this.xn(a)},"call$1","gA2",2,0,null,383,[]],
 ZR:[function(a){var z
 J.UK(a.ghP(),this)
 z=a.gre()
 if(z!=null)for(z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.UK(z.lo,this)
-this.xn(a)},"call$1","gZo",2,0,null,341],
-ti:[function(a){return this.xn(a)},"call$1","gXj",2,0,null,279],
+this.xn(a)},"call$1","gES",2,0,null,383,[]],
+ti:[function(a){return this.xn(a)},"call$1","gXj",2,0,null,274,[]],
 o0:[function(a){var z
 for(z=a.gPu(a),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.UK(z.lo,this)
-this.xn(a)},"call$1","gX7",2,0,null,279],
+this.xn(a)},"call$1","gX7",2,0,null,274,[]],
 YV:[function(a){J.UK(a.gG3(a),this)
 J.UK(a.gv4(),this)
-this.xn(a)},"call$1","gbU",2,0,null,18],
-qv:[function(a){return this.xn(a)},"call$1","gFs",2,0,null,341],
-im:[function(a){J.UK(a.gBb(a),this)
-J.UK(a.gT8(a),this)
-this.xn(a)},"call$1","glf",2,0,null,91],
+this.xn(a)},"call$1","gbU",2,0,null,18,[]],
+qv:[function(a){return this.xn(a)},"call$1","gFs",2,0,null,383,[]],
+im:[function(a){J.UK(a.gBb(),this)
+J.UK(a.gT8(),this)
+this.xn(a)},"call$1","glf",2,0,null,91,[]],
 Hx:[function(a){J.UK(a.gwz(),this)
-this.xn(a)},"call$1","gKY",2,0,null,91],
-ky:[function(a){J.UK(a.gBb(a),this)
-J.UK(a.gT8(a),this)
-this.xn(a)},"call$1","gXf",2,0,null,283]}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{
-"":"",
-NQ:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+this.xn(a)},"call$1","gKY",2,0,null,91,[]],
+ky:[function(a){J.UK(a.gBb(),this)
+J.UK(a.gT8(),this)
+this.xn(a)},"call$1","gXf",2,0,null,278,[]]}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{
+"^":"",
+JG:{
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.Is]},
 static:{Zo:[function(a){var z,y,x,w
 z=$.Nd()
@@ -21992,44 +22278,69 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Cc.ZL(a)
-C.Cc.oX(a)
-return a},null,null,0,0,108,"new ResponseViewerElement$created" /* new ResponseViewerElement$created:0:0 */]}},
-"+ResponseViewerElement":[475]}],["script_ref_element","package:observatory/src/observatory_elements/script_ref.dart",,A,{
-"":"",
+C.Cc.G6(a)
+return a},null,null,0,0,108,"new ResponseViewerElement$created"]}},
+"+ResponseViewerElement":[474]}],["script_ref_element","package:observatory/src/observatory_elements/script_ref.dart",,A,{
+"^":"",
 knI:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-"@":function(){return[C.h9]},
+"^":["qe;zw%-475,AP,fn,tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gRd:[function(a){return a.zw},null,null,1,0,482,"line",351,352],
+sRd:[function(a,b){a.zw=this.ct(a,C.Cv,a.zw,b)},null,null,3,0,385,23,[],"line",351],
+gO3:[function(a){var z
+if(a.hm!=null&&a.tY!=null){z=this.Mq(a,J.UQ(a.tY,"id"))
+if(J.u6(a.zw,0))return z
+else return z+"?line="+H.d(a.zw)}return""},null,null,1,0,362,"url"],
+gJp:[function(a){var z,y
+if(a.tY==null)return""
+z=J.u6(a.zw,0)
+y=a.tY
+if(z)return J.UQ(y,"user_name")
+else return H.d(J.UQ(y,"user_name"))+":"+H.d(a.zw)},null,null,1,0,362,"hoverText"],
+goc:[function(a){var z,y,x
+z=a.tY
+if(z==null)return""
+y=J.UQ(z,"user_name")
+z=J.U6(y)
+x=z.yn(y,J.WB(z.cn(y,"/"),1))
+if(J.u6(a.zw,0))return x
+else return x+":"+H.d(a.zw)},null,null,1,0,362,"name"],
+"@":function(){return[C.Ur]},
 static:{Th:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
+a.zw=-1
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.c0.ZL(a)
-C.c0.oX(a)
-return a},null,null,0,0,108,"new ScriptRefElement$created" /* new ScriptRefElement$created:0:0 */]}},
-"+ScriptRefElement":[364]}],["script_view_element","package:observatory/src/observatory_elements/script_view.dart",,U,{
-"":"",
+C.c0.G6(a)
+return a},null,null,0,0,108,"new ScriptRefElement$created"]}},
+"+ScriptRefElement":[593],
+qe:{
+"^":"xI+Pi;",
+$isd3:true}}],["script_view_element","package:observatory/src/observatory_elements/script_view.dart",,U,{
+"^":"",
 fI:{
-"":["V12;Uz%-599,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gMU:[function(a){return a.Uz},null,null,1,0,600,"script",359,360],
-sMU:[function(a,b){a.Uz=this.ct(a,C.fX,a.Uz,b)},null,null,3,0,601,23,"script",359],
+"^":["V13;Uz%-594,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNl:[function(a){return a.Uz},null,null,1,0,595,"script",351,352],
+sNl:[function(a,b){a.Uz=this.ct(a,C.fX,a.Uz,b)},null,null,3,0,596,23,[],"script",351],
 PQ:[function(a,b){if(J.de(b.gu9(),-1))return"min-width:32px;"
 else if(J.de(b.gu9(),0))return"min-width:32px;background-color:red"
-return"min-width:32px;background-color:green"},"call$1","gXa",2,0,602,173,"hitsStyle"],
+return"min-width:32px;background-color:green"},"call$1","gXa",2,0,597,173,[],"hitsStyle"],
 wH:[function(a,b,c,d){var z,y,x
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null){N.Jx("").To("No isolate found.")
 return}x="/"+z+"/coverage"
-a.hm.glw().fB(x).ml(new U.qq(a,y)).OA(new U.FC())},"call$3","gWp",6,0,376,18,307,74,"refreshCoverage"],
-"@":function(){return[C.Er]},
+a.hm.gDF().fB(x).ml(new U.qq(a,y)).OA(new U.FC())},"call$3","gWp",6,0,369,18,[],301,[],74,[],"refreshCoverage"],
+"@":function(){return[C.I3]},
 static:{Ry:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -22038,53 +22349,60 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.cJ.ZL(a)
-C.cJ.oX(a)
-return a},null,null,0,0,108,"new ScriptViewElement$created" /* new ScriptViewElement$created:0:0 */]}},
-"+ScriptViewElement":[603],
-V12:{
-"":"uL+Pi;",
+C.cJ.G6(a)
+return a},null,null,0,0,108,"new ScriptViewElement$created"]}},
+"+ScriptViewElement":[598],
+V13:{
+"^":"uL+Pi;",
 $isd3:true},
 qq:{
-"":"Tp:361;a-77,b-77",
+"^":"Tp:353;a-77,b-77",
 call$1:[function(a){var z,y
 this.b.oe(J.UQ(a,"coverage"))
 z=this.a
 y=J.RE(z)
-y.ct(z,C.YH,"",y.gXa(z))},"call$1",null,2,0,361,604,"call"],
+y.ct(z,C.YH,"",y.gXa(z))},"call$1",null,2,0,353,599,[],"call"],
 $isEH:true},
-"+ScriptViewElement_refreshCoverage_closure":[471],
+"+ScriptViewElement_refreshCoverage_closure":[467],
 FC:{
-"":"Tp:349;",
-call$2:[function(a,b){P.JS("refreshCoverage "+H.d(a)+" "+H.d(b))},"call$2",null,4,0,349,18,472,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){P.JS("refreshCoverage "+H.d(a)+" "+H.d(b))},"call$2",null,4,0,341,18,[],468,[],"call"],
 $isEH:true},
-"+ScriptViewElement_refreshCoverage_closure":[471]}],["service_ref_element","package:observatory/src/observatory_elements/service_ref.dart",,Q,{
-"":"",
+"+ScriptViewElement_refreshCoverage_closure":[467]}],["service_ref_element","package:observatory/src/observatory_elements/service_ref.dart",,Q,{
+"^":"",
 xI:{
-"":["Ds;tY%-355,Pe%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gnv:[function(a){return a.tY},null,null,1,0,358,"ref",359,360],
-snv:[function(a,b){a.tY=this.ct(a,C.kY,a.tY,b)},null,null,3,0,361,23,"ref",359],
-gtb:[function(a){return a.Pe},null,null,1,0,373,"internal",359,360],
-stb:[function(a,b){a.Pe=this.ct(a,C.zD,a.Pe,b)},null,null,3,0,374,23,"internal",359],
+"^":["Ds;tY%-347,Pe%-355,m0%-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gnv:[function(a){return a.tY},null,null,1,0,350,"ref",351,352],
+snv:[function(a,b){a.tY=this.ct(a,C.kY,a.tY,b)},null,null,3,0,353,23,[],"ref",351],
+gjT:[function(a){return a.Pe},null,null,1,0,366,"internal",351,352],
+sjT:[function(a,b){a.Pe=this.ct(a,C.zD,a.Pe,b)},null,null,3,0,367,23,[],"internal",351],
+gAq:[function(a){return a.m0},null,null,1,0,493,"isolate",351,352],
+sAq:[function(a,b){a.m0=this.ct(a,C.Z8,a.m0,b)},null,null,3,0,494,23,[],"isolate",351],
 aZ:[function(a,b){this.ct(a,C.Fh,"",this.gO3(a))
 this.ct(a,C.YS,[],this.goc(a))
-this.ct(a,C.bA,"",this.gJp(a))},"call$1","gma",2,0,152,231,"refChanged"],
-gO3:[function(a){var z=a.hm
-if(z!=null&&a.tY!=null)return z.gZ6().kP(J.UQ(a.tY,"id"))
-return""},null,null,1,0,369,"url"],
+this.ct(a,C.bA,"",this.gJp(a))},"call$1","gma",2,0,150,225,[],"refChanged"],
+gO3:[function(a){var z=a.tY
+if(z!=null)return this.Mq(a,J.UQ(z,"id"))
+return""},null,null,1,0,362,"url"],
 gJp:[function(a){var z,y
 z=a.tY
 if(z==null)return""
 y=J.UQ(z,"name")
-return y!=null?y:""},null,null,1,0,369,"hoverText"],
+return y!=null?y:""},null,null,1,0,362,"hoverText"],
 goc:[function(a){var z,y
 z=a.tY
 if(z==null)return""
 y=a.Pe===!0?"name":"user_name"
 if(J.UQ(z,y)!=null)return J.UQ(a.tY,y)
 else if(J.UQ(a.tY,"name")!=null)return J.UQ(a.tY,"name")
-return""},null,null,1,0,369,"name"],
+return""},null,null,1,0,362,"name"],
+tx:[function(a,b){this.ct(a,C.bD,0,1)},"call$1","gQ1",2,0,150,225,[],"isolateChanged"],
+Mq:[function(a,b){var z=a.hm
+if(z==null)return""
+else if(a.m0==null)return z.gZ6().kP(b)
+else return J.uY(z.gZ6(),J.F8(a.m0),b)},"call$1","gLc",2,0,504,505,[],"relativeLink",365],
 "@":function(){return[C.JD]},
 static:{lK:[function(a){var z,y,x,w
 z=$.Nd()
@@ -22093,22 +22411,27 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.ep.ZL(a)
-C.ep.oX(a)
-return a},null,null,0,0,108,"new ServiceRefElement$created" /* new ServiceRefElement$created:0:0 */]}},
-"+ServiceRefElement":[605],
+a.X0=w
+C.wU.ZL(a)
+C.wU.G6(a)
+return a},null,null,0,0,108,"new ServiceRefElement$created"]}},
+"+ServiceRefElement":[600],
 Ds:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["stack_frame_element","package:observatory/src/observatory_elements/stack_frame.dart",,K,{
-"":"",
+"^":"",
 nm:{
-"":["V13;Va%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gz1:[function(a){return a.Va},null,null,1,0,358,"frame",359,360],
-sz1:[function(a,b){a.Va=this.ct(a,C.rE,a.Va,b)},null,null,3,0,361,23,"frame",359],
-"@":function(){return[C.Xv]},
+"^":["V14;Va%-347,Mt%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gz1:[function(a){return a.Va},null,null,1,0,350,"frame",351,352],
+sz1:[function(a,b){a.Va=this.ct(a,C.rE,a.Va,b)},null,null,3,0,353,23,[],"frame",351],
+goE:[function(a){return a.Mt},null,null,1,0,366,"expanded",351,352],
+soE:[function(a,b){a.Mt=this.ct(a,C.mr,a.Mt,b)},null,null,3,0,367,23,[],"expanded",351],
+AZ:[function(a,b,c,d){var z=a.Mt
+a.Mt=this.ct(a,C.mr,z,z!==!0)},"call$3","ghM",6,0,470,123,[],180,[],278,[],"toggleExpand"],
+"@":function(){return[C.pE]},
 static:{an:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -22118,23 +22441,26 @@
 v=W.cv
 v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
 a.Va=z
+a.Mt=!1
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.dX.ZL(a)
-C.dX.oX(a)
-return a},null,null,0,0,108,"new StackFrameElement$created" /* new StackFrameElement$created:0:0 */]}},
-"+StackFrameElement":[606],
-V13:{
-"":"uL+Pi;",
+C.dX.G6(a)
+return a},null,null,0,0,108,"new StackFrameElement$created"]}},
+"+StackFrameElement":[601],
+V14:{
+"^":"uL+Pi;",
 $isd3:true}}],["stack_trace_element","package:observatory/src/observatory_elements/stack_trace.dart",,X,{
-"":"",
+"^":"",
 Vu:{
-"":["V14;V4%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtN:[function(a){return a.V4},null,null,1,0,358,"trace",359,360],
-stN:[function(a,b){a.V4=this.ct(a,C.kw,a.V4,b)},null,null,3,0,361,23,"trace",359],
+"^":["V15;V4%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtN:[function(a){return a.V4},null,null,1,0,350,"trace",351,352],
+stN:[function(a,b){a.V4=this.ct(a,C.kw,a.V4,b)},null,null,3,0,353,23,[],"trace",351],
+Ak:[function(a,b,c,d){var z=a.hm.gZ6().kP("stacktrace")
+a.hm.gDF().fB(z).ml(new X.At(a)).OA(new X.Sb())},"call$3","gBq",6,0,369,18,[],301,[],74,[],"refresh"],
 "@":function(){return[C.js]},
-static:{bV:[function(a){var z,y,x,w,v
+static:{B4:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
 y=$.Nd()
@@ -22145,20 +22471,33 @@
 a.V4=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.bg.ZL(a)
-C.bg.oX(a)
-return a},null,null,0,0,108,"new StackTraceElement$created" /* new StackTraceElement$created:0:0 */]}},
-"+StackTraceElement":[607],
-V14:{
-"":"uL+Pi;",
-$isd3:true}}],["template_binding","package:template_binding/template_binding.dart",,M,{
-"":"",
+C.bg.G6(a)
+return a},null,null,0,0,108,"new StackTraceElement$created"]}},
+"+StackTraceElement":[602],
+V15:{
+"^":"uL+Pi;",
+$isd3:true},
+At:{
+"^":"Tp:223;a-77",
+call$1:[function(a){var z,y
+z=this.a
+y=J.RE(z)
+y.sV4(z,y.ct(z,C.kw,y.gV4(z),a))},"call$1",null,2,0,223,144,[],"call"],
+$isEH:true},
+"+StackTraceElement_refresh_closure":[467],
+Sb:{
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while reloading stack trace: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,341,18,[],472,[],"call"],
+$isEH:true},
+"+StackTraceElement_refresh_closure":[467]}],["template_binding","package:template_binding/template_binding.dart",,M,{
+"^":"",
 IP:[function(a){var z=J.RE(a)
 if(typeof a==="object"&&a!==null&&!!z.$isQl)return C.i3.f0(a)
 switch(z.gt5(a)){case"checkbox":return $.FF().aM(a)
 case"radio":case"select-multiple":case"select-one":return z.gi9(a)
-default:return z.gLm(a)}},"call$1","IU",2,0,null,124],
+default:return z.gLm(a)}},"call$1","nc",2,0,null,124,[]],
 iX:[function(a,b){var z,y,x,w,v,u,t,s
 z=M.pN(a,b)
 y=J.x(a)
@@ -22170,7 +22509,7 @@
 if(s==null)continue
 if(u==null)u=P.Py(null,null,null,null,null)
 u.u(0,t,s)}if(z==null&&u==null&&w==null)return
-return new M.XI(z,u,w,t)},"call$2","Nc",4,0,null,265,284],
+return new M.XI(z,u,w,t)},"call$2","Nc",4,0,null,259,[],279,[]],
 HP:[function(a,b,c,d,e){var z,y,x
 if(b==null)return
 if(b.gN2()!=null){z=b.gN2()
@@ -22180,16 +22519,16 @@
 if(z.gwd(b)==null)return
 y=b.gTe()-a.childNodes.length
 for(x=a.firstChild;x!=null;x=x.nextSibling,++y){if(y<0)continue
-M.HP(x,J.UQ(z.gwd(b),y),c,d,e)}},"call$5","Yy",10,0,null,265,144,285,284,286],
+M.HP(x,J.UQ(z.gwd(b),y),c,d,e)}},"call$5","Yy",10,0,null,259,[],144,[],280,[],279,[],281,[]],
 bM:[function(a){var z
 for(;z=J.RE(a),z.gKV(a)!=null;)a=z.gKV(a)
 if(typeof a==="object"&&a!==null&&!!z.$isQF||typeof a==="object"&&a!==null&&!!z.$isI0||typeof a==="object"&&a!==null&&!!z.$ishy)return a
-return},"call$1","ay",2,0,null,265],
+return},"call$1","ay",2,0,null,259,[]],
 pN:[function(a,b){var z,y
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$iscv)return M.F5(a,b)
 if(typeof a==="object"&&a!==null&&!!z.$iskJ){y=M.F4(a.textContent,"text",a,b)
-if(y!=null)return["text",y]}return},"call$2","vw",4,0,null,265,284],
+if(y!=null)return["text",y]}return},"call$2","SG",4,0,null,259,[],279,[]],
 F5:[function(a,b){var z,y,x
 z={}
 z.a=null
@@ -22200,7 +22539,7 @@
 if(y==null){x=[]
 z.a=x
 y=x}y.push("bind")
-y.push(M.F4("{{}}","bind",a,b))}return z.a},"call$2","OT",4,0,null,124,284],
+y.push(M.F4("{{}}","bind",a,b))}return z.a},"call$2","OT",4,0,null,124,[],279,[]],
 Iu:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 for(z=J.U6(a),y=d!=null,x=J.x(b),x=typeof b==="object"&&b!==null&&!!x.$ishs,w=0;w<z.gB(a);w+=2){v=z.t(a,w)
 u=z.t(a,w+1)
@@ -22230,7 +22569,7 @@
 t.push(L.ao(j,l,null))}o.wE(0)
 p=o
 s="value"}i=J.Jj(x?b:M.Ky(b),v,p,s)
-if(y)d.push(i)}},"call$4","S5",6,2,null,77,291,265,285,286],
+if(y)d.push(i)}},"call$4","S5",6,2,null,77,286,[],259,[],280,[],281,[]],
 F4:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r
 z=a.length
 if(z===0)return
@@ -22248,15 +22587,15 @@
 v=t+2}if(v===z)w.push("")
 z=new M.HS(w,null)
 z.Yn(w)
-return z},"call$4","nG",8,0,null,86,12,265,284],
+return z},"call$4","jF",8,0,null,86,[],12,[],259,[],279,[]],
 SH:[function(a,b){var z,y
 z=a.firstChild
 if(z==null)return
 y=new M.yp(z,a.lastChild,b)
 for(;z!=null;){M.Ky(z).sCk(y)
-z=z.nextSibling}},"call$2","KQ",4,0,null,201,285],
+z=z.nextSibling}},"call$2","KQ",4,0,null,199,[],280,[]],
 Ky:[function(a){var z,y,x,w
-z=$.cm()
+z=$.rw()
 z.toString
 y=H.of(a,"expando$values")
 x=y==null?null:H.of(y,z.Qz())
@@ -22269,14 +22608,14 @@
 else w=!0
 x=w?new M.DT(null,null,null,!1,null,null,null,null,null,a,null,null):new M.V2(a,null,null)}else x=typeof a==="object"&&a!==null&&!!w.$iskJ?new M.XT(a,null,null):new M.hs(a,null,null)
 z.u(0,a,x)
-return x},"call$1","La",2,0,null,265],
+return x},"call$1","La",2,0,null,259,[]],
 wR:[function(a){var z=J.RE(a)
 if(typeof a==="object"&&a!==null&&!!z.$iscv)if(z.gqn(a)!=="template")z=z.gQg(a).MW.hasAttribute("template")===!0&&C.uE.x4(z.gqn(a))===!0
 else z=!0
 else z=!1
-return z},"call$1","xS",2,0,null,292],
+return z},"call$1","xS",2,0,null,287,[]],
 V2:{
-"":"hs;N1,mD,Ck",
+"^":"hs;N1,mD,Ck",
 Z1:[function(a,b,c,d){var z,y,x,w,v
 J.MV(this.glN(),b)
 z=this.gN1()
@@ -22297,21 +22636,21 @@
 z=d!=null?d:""
 x=new M.D8(w,y,c,null,null,v,z)
 x.Og(y,v,c,d)}this.gCd(this).u(0,b,x)
-return x},"call$3","gDT",4,2,null,77,12,285,266]},
+return x},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 D8:{
-"":"TR;Y0,qP,ZY,xS,PB,eS,ay",
+"^":"TR;Y0,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z,y
 if(this.Y0){z=null!=a&&!1!==a
 y=this.eS
 if(z)J.Vs(X.TR.prototype.gH.call(this)).MW.setAttribute(y,"")
 else J.Vs(X.TR.prototype.gH.call(this)).Rz(0,y)}else{z=J.Vs(X.TR.prototype.gH.call(this))
 y=a==null?"":H.d(a)
-z.MW.setAttribute(this.eS,y)}},"call$1","gH0",2,0,null,23]},
+z.MW.setAttribute(this.eS,y)}},"call$1","gH0",2,0,null,23,[]]},
 jY:{
-"":"NP;Ca,qP,ZY,xS,PB,eS,ay",
+"^":"NP;Ca,qP,ZY,xS,PB,eS,ay",
 gH:function(){return M.NP.prototype.gH.call(this)},
 EC:[function(a){var z,y,x,w,v,u
-z=J.Lp(M.NP.prototype.gH.call(this))
+z=J.u3(M.NP.prototype.gH.call(this))
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$islp){x=J.UQ(J.QE(M.Ky(z)),"value")
 w=J.x(x)
@@ -22319,49 +22658,49 @@
 u=x}else{v=null
 u=null}}else{v=null
 u=null}M.NP.prototype.EC.call(this,a)
-if(u!=null&&u.gqP()!=null&&!J.de(y.gP(z),v))u.FC(null)},"call$1","gH0",2,0,null,232]},
+if(u!=null&&u.gqP()!=null&&!J.de(y.gP(z),v))u.FC(null)},"call$1","gH0",2,0,null,226,[]]},
 H2:{
-"":"TR;",
+"^":"TR;",
 cO:[function(a){if(this.qP==null)return
 this.Ca.ed()
 X.TR.prototype.cO.call(this,this)},"call$0","gJK",0,0,null]},
-lP:{
-"":"Tp:108;",
+YJ:{
+"^":"Tp:108;",
 call$0:[function(){var z,y,x,w,v
 z=document.createElement("div",null).appendChild(W.ED(null))
 y=J.RE(z)
 y.st5(z,"checkbox")
 x=[]
 w=y.gVl(z)
-H.VM(new W.Ov(0,w.uv,w.Ph,W.aF(new M.LfS(x)),w.Sg),[H.Kp(w,0)]).Zz()
+H.VM(new W.Ov(0,w.uv,w.Ph,W.aF(new M.fTP(x)),w.Sg),[H.Kp(w,0)]).Zz()
 y=y.gi9(z)
-H.VM(new W.Ov(0,y.uv,y.Ph,W.aF(new M.fTP(x)),y.Sg),[H.Kp(y,0)]).Zz()
+H.VM(new W.Ov(0,y.uv,y.Ph,W.aF(new M.ppY(x)),y.Sg),[H.Kp(y,0)]).Zz()
 y=window
 v=document.createEvent("MouseEvent")
 J.e2(v,"click",!0,!0,y,0,0,0,0,0,!1,!1,!1,!1,0,null)
 z.dispatchEvent(v)
 return x.length===1?C.mt:C.Nm.gtH(x)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-LfS:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.push(C.T1)},"call$1",null,2,0,null,18,"call"],
-$isEH:true},
 fTP:{
-"":"Tp:229;b",
-call$1:[function(a){this.b.push(C.mt)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.push(C.pi)},"call$1",null,2,0,null,18,[],"call"],
+$isEH:true},
+ppY:{
+"^":"Tp:223;b",
+call$1:[function(a){this.b.push(C.mt)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 NP:{
-"":"H2;Ca,qP,ZY,xS,PB,eS,ay",
+"^":"H2;Ca,qP,ZY,xS,PB,eS,ay",
 gH:function(){return X.TR.prototype.gH.call(this)},
 EC:[function(a){var z=this.gH()
-J.ta(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,232],
+J.ta(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,226,[]],
 FC:[function(a){var z=J.Vm(this.gH())
 J.ta(this.xS,z)
-O.Y3()},"call$1","gqf",2,0,152,18]},
-Vh:{
-"":"H2;Ca,qP,ZY,xS,PB,eS,ay",
+O.Y3()},"call$1","gqf",2,0,150,18,[]]},
+jt:{
+"^":"H2;Ca,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z=X.TR.prototype.gH.call(this)
-J.rP(z,null!=a&&!1!==a)},"call$1","gH0",2,0,null,232],
+J.rP(z,null!=a&&!1!==a)},"call$1","gH0",2,0,null,226,[]],
 FC:[function(a){var z,y,x,w
 z=J.Hf(X.TR.prototype.gH.call(this))
 J.ta(this.xS,z)
@@ -22370,7 +22709,7 @@
 if(typeof z==="object"&&z!==null&&!!y.$isMi&&J.de(J.zH(X.TR.prototype.gH.call(this)),"radio"))for(z=J.GP(M.kv(X.TR.prototype.gH.call(this)));z.G();){x=z.gl()
 y=J.x(x)
 w=J.UQ(J.QE(typeof x==="object"&&x!==null&&!!y.$ishs?x:M.Ky(x)),"checked")
-if(w!=null)J.ta(w,!1)}O.Y3()},"call$1","gqf",2,0,152,18],
+if(w!=null)J.ta(w,!1)}O.Y3()},"call$1","gqf",2,0,150,18,[]],
 static:{kv:[function(a){var z,y,x
 z=J.RE(a)
 if(z.gMB(a)!=null){z=z.gMB(a)
@@ -22379,9 +22718,9 @@
 return z.ev(z,new M.r0(a))}else{y=M.bM(a)
 if(y==null)return C.xD
 x=J.MK(y,"input[type=\"radio\"][name=\""+H.d(z.goc(a))+"\"]")
-return x.ev(x,new M.jz(a))}},"call$1","VE",2,0,null,124]}},
+return x.ev(x,new M.jz(a))}},"call$1","VE",2,0,null,124,[]]}},
 r0:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y
 z=this.a
 y=J.x(a)
@@ -22390,21 +22729,21 @@
 z=y==null?z==null:y===z}else z=!1
 else z=!1
 else z=!1
-return z},"call$1",null,2,0,null,288,"call"],
+return z},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true},
 jz:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){var z=J.x(a)
-return!z.n(a,this.b)&&z.gMB(a)==null},"call$1",null,2,0,null,288,"call"],
+return!z.n(a,this.b)&&z.gMB(a)==null},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true},
 SA:{
-"":"H2;Dh,Ca,qP,ZY,xS,PB,eS,ay",
+"^":"H2;Dh,Ca,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z
 this.C7()
 if(this.Gh(a)===!0)return
-z=new (window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver)(H.tR(W.Iq(new M.hB(this)),2))
+z=new (window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver)(H.tR(W.K2(new M.hB(this)),2))
 C.S2.yN(z,X.TR.prototype.gH.call(this),!0,!0)
-this.Dh=z},"call$1","gH0",2,0,null,232],
+this.Dh=z},"call$1","gH0",2,0,null,226,[]],
 Gh:[function(a){var z,y,x
 z=this.eS
 y=J.x(z)
@@ -22413,7 +22752,7 @@
 z=J.m4(X.TR.prototype.gH.call(this))
 return z==null?x==null:z===x}else if(y.n(z,"value")){z=X.TR.prototype.gH.call(this)
 J.ta(z,a==null?"":H.d(a))
-return J.de(J.Vm(X.TR.prototype.gH.call(this)),a)}},"call$1","gdZ",2,0,null,232],
+return J.de(J.Vm(X.TR.prototype.gH.call(this)),a)}},"call$1","goz",2,0,null,226,[]],
 C7:[function(){var z=this.Dh
 if(z!=null){z.disconnect()
 this.Dh=null}},"call$0","gln",0,0,null],
@@ -22423,21 +22762,21 @@
 y=J.x(z)
 if(y.n(z,"selectedIndex")){z=J.m4(X.TR.prototype.gH.call(this))
 J.ta(this.xS,z)}else if(y.n(z,"value")){z=J.Vm(X.TR.prototype.gH.call(this))
-J.ta(this.xS,z)}},"call$1","gqf",2,0,152,18],
+J.ta(this.xS,z)}},"call$1","gqf",2,0,150,18,[]],
 $isSA:true,
 static:{qb:[function(a){if(typeof a==="string")return H.BU(a,null,new M.nv())
-return typeof a==="number"&&Math.floor(a)===a?a:0},"call$1","v7",2,0,null,23]}},
+return typeof a==="number"&&Math.floor(a)===a?a:0},"call$1","v7",2,0,null,23,[]]}},
 hB:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=this.a
-if(z.Gh(J.Vm(z.xS))===!0)z.C7()},"call$2",null,4,0,null,21,608,"call"],
+if(z.Gh(J.Vm(z.xS))===!0)z.C7()},"call$2",null,4,0,null,21,[],603,[],"call"],
 $isEH:true},
 nv:{
-"":"Tp:229;",
-call$1:[function(a){return 0},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return 0},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 ee:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 z=J.x(b)
@@ -22454,25 +22793,25 @@
 x.Ca=M.IP(z).yI(x.gqf())
 z=x}else{z=this.N1
 x=d!=null?d:""
-x=new M.Vh(null,z,c,null,null,"checked",x)
+x=new M.jt(null,z,c,null,null,"checked",x)
 x.Og(z,"checked",c,d)
 x.Ca=M.IP(z).yI(x.gqf())
 z=x}y.u(0,b,z)
-return z},"call$3","gDT",4,2,null,77,12,285,266]},
+return z},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 XI:{
-"":"a;Cd>,wd>,N2<,Te<"},
+"^":"a;Cd>,wd>,N2<,Te<"},
 hs:{
-"":"a;N1<,mD,Ck?",
+"^":"a;N1<,mD,Ck?",
 Z1:[function(a,b,c,d){var z,y
 window
 z=$.pl()
 y="Unhandled binding to Node: "+H.d(this)+" "+H.d(b)+" "+H.d(c)+" "+H.d(d)
 z.toString
-if(typeof console!="undefined")console.error(y)},"call$3","gDT",4,2,null,77,12,285,266],
+if(typeof console!="undefined")console.error(y)},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 Ih:[function(a,b){var z
 if(this.mD==null)return
 z=this.gCd(this).Rz(0,b)
-if(z!=null)J.wC(z)},"call$1","gV0",2,0,null,12],
+if(z!=null)J.wC(z)},"call$1","gC8",2,0,null,12,[]],
 GB:[function(a){var z,y
 if(this.mD==null)return
 for(z=this.gCd(this),z=z.gUQ(z),z=P.F(z,!0,H.ip(z,"mW",0)),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();){y=z.lo
@@ -22486,9 +22825,9 @@
 return typeof z==="object"&&z!==null&&!!y.$ishs?z:this},
 $ishs:true},
 yp:{
-"":"a;KO,qW,k8"},
+"^":"a;KO,qW,k8"},
 ug:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 if(J.de(b,"selectedindex"))b="selectedIndex"
@@ -22505,9 +22844,9 @@
 y.Og(x,b,c,d)
 y.Ca=M.IP(x).yI(y.gqf())
 z.u(0,b,y)
-return y},"call$3","gDT",4,2,null,77,12,285,266]},
+return y},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 DT:{
-"":"V2;lr,xT?,kr<,Ds,QO?,jH?,mj?,IT,dv@,N1,mD,Ck",
+"^":"V2;lr,xT?,kr<,Mf,QO?,jH?,mj?,IT,dv@,N1,mD,Ck",
 gN1:function(){return this.N1},
 glN:function(){var z,y
 z=this.N1
@@ -22538,7 +22877,7 @@
 z=new M.p8(this,c,b,d)
 this.gCd(this).u(0,b,z)
 return z
-default:return M.V2.prototype.Z1.call(this,this,b,c,d)}},"call$3","gDT",4,2,null,77,12,285,266],
+default:return M.V2.prototype.Z1.call(this,this,b,c,d)}},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 Ih:[function(a,b){var z
 switch(b){case"bind":z=this.kr
 if(z==null)return
@@ -22565,10 +22904,10 @@
 this.gCd(this).Rz(0,b)
 return
 default:M.hs.prototype.Ih.call(this,this,b)
-return}},"call$1","gV0",2,0,null,12],
+return}},"call$1","gC8",2,0,null,12,[]],
 jq:[function(){var z=this.kr
 if(!z.t9){z.t9=!0
-P.rb(z.gjM())}},"call$0","goz",0,0,null],
+P.rb(z.gjM())}},"call$0","gvj",0,0,null],
 a5:[function(a,b,c){var z,y,x,w,v,u,t
 z=this.gnv(this)
 y=J.x(z)
@@ -22585,7 +22924,7 @@
 y=u}t=M.Fz(x,y)
 M.HP(t,w,a,b,c)
 M.SH(t,a)
-return t},function(a,b){return this.a5(a,b,null)},"ZK","call$3",null,"gmJ",0,6,null,77,77,77,285,284,286],
+return t},function(a,b){return this.a5(a,b,null)},"ZK","call$3",null,"gmJ",0,6,null,77,77,77,280,[],279,[],281,[]],
 gzH:function(){return this.xT},
 gnv:function(a){var z,y,x,w,v
 this.Sy()
@@ -22612,7 +22951,7 @@
 y=J.RE(z)
 z=y.gQg(z).MW.hasAttribute("template")===!0&&C.uE.x4(y.gqn(z))===!0}else z=!1
 if(z){if(a!=null)throw H.b(new P.AT("instanceRef should not be supplied for attribute templates."))
-v=M.eX(this.N1)
+v=M.pZ(this.N1)
 z=J.x(v)
 v=typeof v==="object"&&v!==null&&!!z.$ishs?v:M.Ky(v)
 v.smj(!0)
@@ -22624,23 +22963,23 @@
 if(a!=null)v.sQO(a)
 else if(w)M.KE(v,this.N1,u)
 else M.GM(J.nX(v))
-return!0},function(){return this.wh(null)},"Sy","call$1",null,"gv8",0,2,null,77,609],
+return!0},function(){return this.wh(null)},"Sy","call$1",null,"ga6",0,2,null,77,604,[]],
 $isDT:true,
-static:{"":"mn,EW,Sf,To",Fz:[function(a,b){var z,y,x
+static:{"^":"mn,EW,Sf,To",Fz:[function(a,b){var z,y,x
 z=J.Lh(b,a,!1)
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$iscv)if(y.gqn(z)!=="template")y=y.gQg(z).MW.hasAttribute("template")===!0&&C.uE.x4(y.gqn(z))===!0
 else y=!0
 else y=!1
 if(y)return z
-for(x=J.vi(a);x!=null;x=x.nextSibling)z.appendChild(M.Fz(x,b))
-return z},"call$2","G0",4,0,null,265,287],TA:[function(a){var z,y,x,w
+for(x=J.cO(a);x!=null;x=x.nextSibling)z.appendChild(M.Fz(x,b))
+return z},"call$2","Tkw",4,0,null,259,[],282,[]],TA:[function(a){var z,y,x,w
 z=J.VN(a)
 if(W.Pv(z.defaultView)==null)return z
 y=$.LQ().t(0,z)
 if(y==null){y=z.implementation.createHTMLDocument("")
 for(;x=y.lastChild,x!=null;){w=x.parentNode
-if(w!=null)w.removeChild(x)}$.LQ().u(0,z,y)}return y},"call$1","nt",2,0,null,262],eX:[function(a){var z,y,x,w,v,u
+if(w!=null)w.removeChild(x)}$.LQ().u(0,z,y)}return y},"call$1","nt",2,0,null,256,[]],pZ:[function(a){var z,y,x,w,v,u
 z=J.RE(a)
 y=z.gM0(a).createElement("template",null)
 z.gKV(a).insertBefore(y,a)
@@ -22655,32 +22994,32 @@
 v.removeAttribute(w)
 y.setAttribute(w,u)
 break
-default:}}return y},"call$1","LH",2,0,null,288],KE:[function(a,b,c){var z,y,x,w
+default:}}return y},"call$1","fo",2,0,null,283,[]],KE:[function(a,b,c){var z,y,x,w
 z=J.nX(a)
 if(c){J.Kv(z,b)
-return}for(y=J.RE(b),x=J.RE(z);w=y.gq6(b),w!=null;)x.jx(z,w)},"call$3","BZ",6,0,null,262,288,289],GM:[function(a){var z,y
+return}for(y=J.RE(b),x=J.RE(z);w=y.gq6(b),w!=null;)x.jx(z,w)},"call$3","BZ",6,0,null,256,[],283,[],284,[]],GM:[function(a){var z,y
 z=new M.OB()
 y=J.MK(a,$.cz())
 if(M.wR(a))z.call$1(a)
-y.aN(y,z)},"call$1","DR",2,0,null,290],oR:[function(){if($.To===!0)return
+y.aN(y,z)},"call$1","DR",2,0,null,285,[]],oR:[function(){if($.To===!0)return
 $.To=!0
 var z=document.createElement("style",null)
 z.textContent=$.cz()+" { display: none; }"
 document.head.appendChild(z)},"call$0","Lv",0,0,null]}},
 OB:{
-"":"Tp:152;",
+"^":"Tp:150;",
 call$1:[function(a){var z
 if(!M.Ky(a).wh(null)){z=J.x(a)
-M.GM(J.nX(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a)))}},"call$1",null,2,0,null,262,"call"],
+M.GM(J.nX(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a)))}},"call$1",null,2,0,null,256,[],"call"],
 $isEH:true},
-Uf:{
-"":"Tp:229;",
-call$1:[function(a){return H.d(a)+"[template]"},"call$1",null,2,0,null,421,"call"],
+DO:{
+"^":"Tp:223;",
+call$1:[function(a){return H.d(a)+"[template]"},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 p8:{
-"":"a;ud,lr,eS,ay",
+"^":"a;ud,lr,eS,ay",
 gP:function(a){return J.Vm(this.gND())},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:function(a,b){J.ta(this.gND(),b)},
 gND:function(){var z,y
 z=this.lr
@@ -22694,7 +23033,7 @@
 this.ud=null},"call$0","gJK",0,0,null],
 $isTR:true},
 NW:{
-"":"Tp:349;a,b,c,d",
+"^":"Tp:341;a,b,c,d",
 call$2:[function(a,b){var z,y,x,w
 for(;z=J.U6(a),J.de(z.t(a,0),"_");)a=z.yn(a,1)
 if(this.d)if(z.n(a,"if")){this.a.b=!0
@@ -22706,10 +23045,10 @@
 z.a=w
 z=w}else z=x
 z.push(a)
-z.push(y)}},"call$2",null,4,0,null,12,23,"call"],
+z.push(y)}},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 HS:{
-"":"a;EJ<,bX",
+"^":"a;EJ<,bX",
 gqz:function(){return this.EJ.length===4},
 gaW:function(){var z,y
 z=this.EJ
@@ -22725,7 +23064,7 @@
 if(0>=z.length)return H.e(z,0)
 y=H.d(z[0])+H.d(a)
 if(3>=z.length)return H.e(z,3)
-return y+H.d(z[3])},"call$1","gBg",2,0,610,23],
+return y+H.d(z[3])},"call$1","gBg",2,0,605,23,[]],
 DJ:[function(a){var z,y,x,w,v,u,t
 z=this.EJ
 if(0>=z.length)return H.e(z,0)
@@ -22736,10 +23075,10 @@
 if(t>=z.length)return H.e(z,t)
 u=z[t]
 u=typeof u==="string"?u:H.d(u)
-y.vM=y.vM+u}return y.vM},"call$1","gqD",2,0,611,612],
+y.vM=y.vM+u}return y.vM},"call$1","gqD",2,0,606,607,[]],
 Yn:function(a){this.bX=this.EJ.length===4?this.gBg():this.gqD()}},
 TG:{
-"":"a;e9,YC,xG,pq,t9,A7,js,Q3,JM,d6,rV,yO,XV,eD,FS,IY,U9,DO,Fy",
+"^":"a;e9,YC,xG,pq,t9,A7,js,Q3,JM,d6,rV,yO,XV,eD,FS,IY,U9,DO,Fy",
 Mv:function(a){return this.DO.call$1(a)},
 XS:[function(){var z,y,x,w,v,u
 this.t9=!1
@@ -22770,7 +23109,7 @@
 x=this.xG
 x=x!=null?x:[]
 w=G.jj(x,0,J.q8(x),y,0,J.q8(y))
-if(w.length!==0)this.El(w)},"call$1","ghC",2,0,null,232],
+if(w.length!==0)this.El(w)},"call$1","ghC",2,0,null,226,[]],
 wx:[function(a){var z,y,x,w
 z=J.x(a)
 if(z.n(a,-1))return this.e9.N1
@@ -22783,7 +23122,7 @@
 if(z)return x
 w=M.Ky(x).gkr()
 if(w==null)return x
-return w.wx(C.jn.cU(w.YC.length,2)-1)},"call$1","gzm",2,0,null,47],
+return w.wx(C.jn.cU(w.YC.length,2)-1)},"call$1","gzm",2,0,null,47,[]],
 lP:[function(a,b,c,d){var z,y,x,w,v,u
 z=J.Wx(a)
 y=this.wx(z.W(a,1))
@@ -22796,10 +23135,10 @@
 v=J.TZ(this.e9.N1)
 u=J.tx(y)
 if(x)v.insertBefore(b,u)
-else if(c!=null)for(z=J.GP(c);z.G();)v.insertBefore(z.gl(),u)},"call$4","gaF",8,0,null,47,201,613,286],
+else if(c!=null)for(z=J.GP(c);z.G();)v.insertBefore(z.gl(),u)},"call$4","gaF",8,0,null,47,[],199,[],608,[],281,[]],
 MC:[function(a){var z,y,x,w,v,u,t,s
 z=[]
-z.$builtinTypeInfo=[W.uH]
+z.$builtinTypeInfo=[W.KV]
 y=J.Wx(a)
 x=this.wx(y.W(a,1))
 w=this.wx(a)
@@ -22813,7 +23152,7 @@
 if(s==null?w==null:s===w)w=x
 v=s.parentNode
 if(v!=null)v.removeChild(s)
-z.push(s)}return new M.Ya(z,t)},"call$1","gtx",2,0,null,47],
+z.push(s)}return new M.Ya(z,t)},"call$1","gLu",2,0,null,47,[]],
 El:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
 if(this.pq)return
 z=this.e9
@@ -22839,9 +23178,9 @@
 k=null}else{m=[]
 if(this.DO!=null)o=this.Mv(o)
 k=o!=null?z.a5(o,v,m):null
-l=null}this.lP(p,k,l,m)}}for(z=u.gUQ(u),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)this.uS(J.AB(z.lo))},"call$1","gZX",2,0,614,255],
+l=null}this.lP(p,k,l,m)}}for(z=u.gUQ(u),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)this.uS(J.AB(z.lo))},"call$1","gZX",2,0,609,250,[]],
 uS:[function(a){var z
-for(z=J.GP(a);z.G();)J.wC(z.gl())},"call$1","gZC",2,0,null,286],
+for(z=J.GP(a);z.G();)J.wC(z.gl())},"call$1","gZC",2,0,null,281,[]],
 Gb:[function(){var z=this.IY
 if(z==null)return
 z.ed()
@@ -22856,27 +23195,27 @@
 this.FS=null}this.e9.kr=null
 this.pq=!0},"call$0","gJK",0,0,null]},
 ts:{
-"":"Tp:229;",
-call$1:[function(a){return[a]},"call$1",null,2,0,null,21,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return[a]},"call$1",null,2,0,null,21,[],"call"],
 $isEH:true},
 Kj:{
-"":"Tp:480;a",
+"^":"Tp:484;a",
 call$1:[function(a){var z,y,x
 z=J.U6(a)
 y=z.t(a,0)
 x=z.t(a,1)
 if(!(null!=x&&!1!==x))return
-return this.a?y:[y]},"call$1",null,2,0,null,612,"call"],
+return this.a?y:[y]},"call$1",null,2,0,null,607,[],"call"],
 $isEH:true},
 VU:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b.Az(J.iZ(J.MQ(a)))},"call$1",null,2,0,null,375,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b.Az(J.iZ(J.MQ(a)))},"call$1",null,2,0,null,368,[],"call"],
 $isEH:true},
 Ya:{
-"":"a;yT>,kU>",
+"^":"a;yT>,kU>",
 $isYa:true},
 XT:{
-"":"hs;N1,mD,Ck",
+"^":"hs;N1,mD,Ck",
 Z1:[function(a,b,c,d){var z,y,x
 if(!J.de(b,"text"))return M.hs.prototype.Z1.call(this,this,b,c,d)
 this.Ih(0,b)
@@ -22886,13 +23225,13 @@
 x=new M.ic(y,c,null,null,"text",x)
 x.Og(y,"text",c,d)
 z.u(0,b,x)
-return x},"call$3","gDT",4,2,null,77,12,285,266]},
+return x},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 ic:{
-"":"TR;qP,ZY,xS,PB,eS,ay",
+"^":"TR;qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z=this.qP
-J.c9(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,232]},
+J.c9(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,226,[]]},
 wl:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 if(!J.de(b,"value"))return M.V2.prototype.Z1.call(this,this,b,c,d)
@@ -22907,16 +23246,16 @@
 y.Og(x,"value",c,d)
 y.Ca=M.IP(x).yI(y.gqf())
 z.u(0,b,y)
-return y},"call$3","gDT",4,2,null,77,12,285,266]}}],["template_binding.src.binding_delegate","package:template_binding/src/binding_delegate.dart",,O,{
-"":"",
+return y},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]}}],["template_binding.src.binding_delegate","package:template_binding/src/binding_delegate.dart",,O,{
+"^":"",
 T4:{
-"":"a;"}}],["template_binding.src.node_binding","package:template_binding/src/node_binding.dart",,X,{
-"":"",
+"^":"a;"}}],["template_binding.src.node_binding","package:template_binding/src/node_binding.dart",,X,{
+"^":"",
 TR:{
-"":"a;qP<",
+"^":"a;qP<",
 gH:function(){return this.qP},
 gP:function(a){return J.Vm(this.xS)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:function(a,b){J.ta(this.xS,b)},
 cO:[function(a){var z
 if(this.qP==null)return
@@ -22937,9 +23276,9 @@
 this.EC(J.Vm(this.xS))},
 $isTR:true},
 VD:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
-return z.EC(J.Vm(z.xS))},"call$1",null,2,0,null,375,"call"],
+return z.EC(J.Vm(z.xS))},"call$1",null,2,0,null,368,[],"call"],
 $isEH:true}}],])
 I.$finishClasses($$,$,null)
 $$=null
@@ -22964,9 +23303,9 @@
 J.GW.$isfR=true
 J.GW.$asfR=[J.P]
 J.GW.$isa=true
-W.uH.$isuH=true
-W.uH.$isD0=true
-W.uH.$isa=true
+W.KV.$isKV=true
+W.KV.$isD0=true
+W.KV.$isa=true
 W.M5.$isa=true
 N.qV.$isfR=true
 N.qV.$asfR=[N.qV]
@@ -22981,15 +23320,15 @@
 J.Q.$isa=true
 P.a.$isa=true
 W.cv.$iscv=true
-W.cv.$isuH=true
+W.cv.$isKV=true
 W.cv.$isD0=true
 W.cv.$isD0=true
 W.cv.$isa=true
 P.qv.$isa=true
 U.EZ.$ishw=true
 U.EZ.$isa=true
-U.RW.$ishw=true
-U.RW.$isa=true
+U.Jy.$ishw=true
+U.Jy.$isa=true
 U.zX.$iszX=true
 U.zX.$ishw=true
 U.zX.$isa=true
@@ -23021,7 +23360,7 @@
 W.OJ.$isa=true
 A.XP.$isXP=true
 A.XP.$iscv=true
-A.XP.$isuH=true
+A.XP.$isKV=true
 A.XP.$isD0=true
 A.XP.$isD0=true
 A.XP.$isa=true
@@ -23044,11 +23383,14 @@
 P.ej.$isa=true
 P.RY.$isej=true
 P.RY.$isa=true
-P.tg.$isej=true
-P.tg.$isa=true
+P.ac.$isX9=true
+P.ac.$isej=true
+P.ac.$isa=true
+P.X9.$isX9=true
 P.X9.$isej=true
 P.X9.$isa=true
 P.Ms.$isMs=true
+P.Ms.$isX9=true
 P.Ms.$isej=true
 P.Ms.$isej=true
 P.Ms.$isa=true
@@ -23064,8 +23406,8 @@
 W.ea.$isa=true
 P.qh.$isqh=true
 P.qh.$isa=true
-W.Aj.$isea=true
-W.Aj.$isa=true
+W.Oq.$isea=true
+W.Oq.$isa=true
 G.DA.$isDA=true
 G.DA.$isa=true
 M.Ya.$isa=true
@@ -23073,15 +23415,16 @@
 U.hw.$ishw=true
 U.hw.$isa=true
 A.zs.$iscv=true
-A.zs.$isuH=true
+A.zs.$isKV=true
 A.zs.$isD0=true
 A.zs.$isD0=true
 A.zs.$isa=true
-A.k8.$isa=true
+A.bS.$isa=true
+L.Y2.$isa=true
 P.uq.$isa=true
 P.iD.$isiD=true
 P.iD.$isa=true
-W.QF.$isuH=true
+W.QF.$isKV=true
 W.QF.$isD0=true
 W.QF.$isa=true
 N.HV.$isHV=true
@@ -23089,7 +23432,7 @@
 H.yo.$isa=true
 H.IY.$isa=true
 H.aX.$isa=true
-W.I0.$isuH=true
+W.I0.$isKV=true
 W.I0.$isD0=true
 W.I0.$isa=true
 W.DD.$isea=true
@@ -23104,6 +23447,11 @@
 L.kx.$iskx=true
 L.kx.$isa=true
 L.rj.$isa=true
+W.tV.$iscv=true
+W.tV.$isKV=true
+W.tV.$isD0=true
+W.tV.$isD0=true
+W.tV.$isa=true
 P.MN.$isMN=true
 P.MN.$isa=true
 P.KA.$isKA=true
@@ -23127,10 +23475,10 @@
 P.e4.$isa=true
 P.JB.$isJB=true
 P.JB.$isa=true
-L.N8.$isN8=true
-L.N8.$isa=true
 P.Z0.$isZ0=true
 P.Z0.$isa=true
+L.Vi.$isVi=true
+L.Vi.$isa=true
 P.jp.$isjp=true
 P.jp.$isa=true
 W.D0.$isD0=true
@@ -23139,23 +23487,22 @@
 P.fR.$isa=true
 P.aY.$isaY=true
 P.aY.$isa=true
-P.tU.$istU=true
-P.tU.$isa=true
+P.lO.$islO=true
+P.lO.$isa=true
 P.cX.$iscX=true
 P.cX.$isa=true
-P.b8.$isb8=true
-P.b8.$isa=true
-P.lx.$islx=true
-P.lx.$isa=true
 P.nP.$isnP=true
 P.nP.$isa=true
 P.iP.$isiP=true
 P.iP.$isfR=true
 P.iP.$asfR=[null]
 P.iP.$isa=true
+P.lx.$islx=true
+P.lx.$isa=true
+P.b8.$isb8=true
+P.b8.$isa=true
 P.EH.$isEH=true
 P.EH.$isa=true
-$.$signature_X0={func:"X0",void:true}
 $.$signature_bh={func:"bh",args:[null,null]}
 $.$signature_HB={func:"HB",ret:P.a,args:[P.a]}
 $.$signature_Dv={func:"Dv",args:[null]}
@@ -23189,7 +23536,7 @@
 return J.ks(a)}
 J.x=function(a){if(typeof a=="number"){if(Math.floor(a)==a)return J.im.prototype
 return J.GW.prototype}if(typeof a=="string")return J.O.prototype
-if(a==null)return J.PE.prototype
+if(a==null)return J.ht.prototype
 if(typeof a=="boolean")return J.kn.prototype
 if(a.constructor==Array)return J.Q.prototype
 if(typeof a!="object")return a
@@ -23201,6 +23548,7 @@
 J.C0=function(a,b){return J.w1(a).ez(a,b)}
 J.CC=function(a){return J.RE(a).gmH(a)}
 J.CJ=function(a,b){return J.RE(a).sB1(a,b)}
+J.Co=function(a){return J.RE(a).gcC(a)}
 J.EC=function(a){return J.RE(a).giC(a)}
 J.EY=function(a,b){return J.RE(a).od(a,b)}
 J.Eg=function(a,b){return J.rY(a).Tc(a,b)}
@@ -23212,7 +23560,6 @@
 J.GJ=function(a,b,c,d){return J.RE(a).Y9(a,b,c,d)}
 J.GL=function(a){return J.RE(a).gfN(a)}
 J.GP=function(a){return J.w1(a).gA(a)}
-J.Gn=function(a,b){return J.rY(a).Fr(a,b)}
 J.H4=function(a,b){return J.RE(a).wR(a,b)}
 J.Hb=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<=b
 return J.Wx(a).E(a,b)}
@@ -23229,27 +23576,26 @@
 J.Jr=function(a,b){return J.RE(a).Id(a,b)}
 J.K3=function(a,b){return J.RE(a).Kb(a,b)}
 J.KM=function(a){return J.RE(a).zr(a)}
-J.KV=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a&b)>>>0
-return J.Wx(a).i(a,b)}
 J.Kv=function(a,b){return J.RE(a).jx(a,b)}
+J.LH=function(a,b){return J.w1(a).GT(a,b)}
 J.LL=function(a){return J.Wx(a).HG(a)}
 J.Lh=function(a,b,c){return J.RE(a).ek(a,b,c)}
-J.Lp=function(a){return J.RE(a).geT(a)}
+J.Lp=function(a,b){return J.RE(a).st5(a,b)}
 J.MK=function(a,b){return J.RE(a).Md(a,b)}
 J.MQ=function(a){return J.w1(a).grZ(a)}
 J.MV=function(a,b){return J.RE(a).Ih(a,b)}
 J.Mu=function(a,b){return J.RE(a).sig(a,b)}
 J.Mz=function(a){return J.rY(a).hc(a)}
 J.N5=function(a,b){return J.RE(a).RP(a,b)}
+J.NQ=function(a,b){return J.RE(a).bA(a,b)}
 J.Ng=function(a){return J.RE(a).gxX(a)}
 J.Nj=function(a,b,c){return J.rY(a).Nj(a,b,c)}
+J.Nv=function(a,b,c){return J.w1(a).xe(a,b,c)}
 J.O2=function(a,b){return J.RE(a).Ch(a,b)}
 J.O6=function(a){return J.RE(a).goc(a)}
-J.ON=function(a){return J.RE(a).gcC(a)}
 J.Or=function(a){return J.RE(a).yx(a)}
 J.Pr=function(a,b){return J.w1(a).eR(a,b)}
 J.Pw=function(a,b){return J.RE(a).sxr(a,b)}
-J.Pz=function(a,b){return J.RE(a).szZ(a,b)}
 J.QC=function(a){return J.w1(a).wg(a)}
 J.QE=function(a){return J.RE(a).gCd(a)}
 J.QM=function(a,b){return J.RE(a).Rg(a,b)}
@@ -23260,12 +23606,15 @@
 J.Tv=function(a){return J.RE(a).gB1(a)}
 J.U2=function(a){return J.w1(a).V1(a)}
 J.UK=function(a,b){return J.RE(a).RR(a,b)}
+J.UN=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a^b)>>>0
+return J.Wx(a).w(a,b)}
 J.UQ=function(a,b){if(a.constructor==Array||typeof a=="string"||H.wV(a,a[init.dispatchPropertyName]))if(b>>>0===b&&b<a.length)return a[b]
 return J.U6(a).t(a,b)}
 J.UU=function(a,b){return J.U6(a).u8(a,b)}
 J.Ut=function(a,b,c,d){return J.RE(a).rJ(a,b,c,d)}
 J.V1=function(a,b){return J.w1(a).Rz(a,b)}
 J.VN=function(a){return J.RE(a).gM0(a)}
+J.VZ=function(a,b,c,d,e){return J.w1(a).YW(a,b,c,d,e)}
 J.Vm=function(a){return J.RE(a).gP(a)}
 J.Vq=function(a){return J.RE(a).xo(a)}
 J.Vs=function(a){return J.RE(a).gQg(a)}
@@ -23274,33 +23623,36 @@
 return J.Qc(a).g(a,b)}
 J.WI=function(a){return J.RE(a).gG3(a)}
 J.We=function(a,b){return J.RE(a).scC(a,b)}
-J.Wy=function(a){return J.RE(a).gbG(a)}
 J.XS=function(a,b){return J.w1(a).zV(a,b)}
 J.Xf=function(a,b){return J.RE(a).oo(a,b)}
 J.Y5=function(a){return J.RE(a).gyT(a)}
 J.YP=function(a){return J.RE(a).gQ7(a)}
+J.YV=function(a){return J.RE(a).goE(a)}
 J.Z7=function(a){if(typeof a=="number")return-a
 return J.Wx(a).J(a)}
 J.ZP=function(a,b){return J.RE(a).Tk(a,b)}
 J.ZZ=function(a,b){return J.rY(a).yn(a,b)}
 J.ak=function(a){return J.RE(a).gNF(a)}
 J.bB=function(a){return J.x(a).gbx(a)}
+J.bY=function(a,b){return J.Wx(a).Y(a,b)}
 J.bi=function(a,b){return J.w1(a).h(a,b)}
 J.bj=function(a,b){return J.w1(a).FV(a,b)}
 J.bs=function(a){return J.RE(a).JP(a)}
 J.c1=function(a,b){return J.Wx(a).O(a,b)}
 J.c9=function(a,b){return J.RE(a).sa4(a,b)}
-J.cW=function(a,b){return J.RE(a).st5(a,b)}
+J.cO=function(a){return J.RE(a).gq6(a)}
 J.cZ=function(a,b,c,d){return J.RE(a).On(a,b,c,d)}
 J.co=function(a,b){return J.rY(a).nC(a,b)}
 J.de=function(a,b){if(a==null)return b==null
 if(typeof a!="object")return b!=null&&a===b
 return J.x(a).n(a,b)}
 J.e2=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){return J.RE(a).nH(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)}
-J.eI=function(a,b){return J.RE(a).bA(a,b)}
+J.eh=function(a,b){return J.RE(a).Ne(a,b)}
 J.f5=function(a){return J.RE(a).gI(a)}
-J.fo=function(a,b){return J.RE(a).oC(a,b)}
+J.ff=function(a,b,c){return J.U6(a).Pk(a,b,c)}
+J.hf=function(a,b,c){return J.U6(a).XU(a,b,c)}
 J.i4=function(a,b){return J.w1(a).Zv(a,b)}
+J.iG=function(a,b){return J.RE(a).szZ(a,b)}
 J.iZ=function(a){return J.RE(a).gzZ(a)}
 J.jf=function(a,b){return J.x(a).T(a,b)}
 J.kE=function(a,b){return J.U6(a).tg(a,b)}
@@ -23312,9 +23664,12 @@
 J.lB=function(a){return J.RE(a).gP1(a)}
 J.lE=function(a,b){return J.rY(a).j(a,b)}
 J.m4=function(a){return J.RE(a).gig(a)}
+J.mQ=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a&b)>>>0
+return J.Wx(a).i(a,b)}
 J.nX=function(a){return J.RE(a).gjb(a)}
 J.oE=function(a,b){return J.Qc(a).iM(a,b)}
 J.og=function(a,b){return J.RE(a).sIt(a,b)}
+J.on=function(a){return J.RE(a).gtT(a)}
 J.p0=function(a,b){if(typeof a=="number"&&typeof b=="number")return a*b
 return J.Wx(a).U(a,b)}
 J.pO=function(a){return J.U6(a).gor(a)}
@@ -23327,19 +23682,24 @@
 J.rP=function(a,b){return J.RE(a).sTq(a,b)}
 J.rr=function(a){return J.rY(a).bS(a)}
 J.t8=function(a,b){return J.RE(a).FL(a,b)}
+J.tH=function(a,b){return J.w1(a).KI(a,b)}
 J.ta=function(a,b){return J.RE(a).sP(a,b)}
+J.td=function(a){return J.RE(a).gng(a)}
 J.tx=function(a){return J.RE(a).guD(a)}
 J.u1=function(a,b){return J.Wx(a).WZ(a,b)}
+J.u3=function(a){return J.RE(a).geT(a)}
 J.u6=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<b
 return J.Wx(a).C(a,b)}
+J.uH=function(a,b){return J.rY(a).Fr(a,b)}
+J.uY=function(a,b,c){return J.RE(a).r4(a,b,c)}
 J.uf=function(a){return J.RE(a).gxr(a)}
 J.v1=function(a){return J.x(a).giO(a)}
 J.vF=function(a){return J.RE(a).gbP(a)}
-J.vi=function(a){return J.RE(a).gq6(a)}
 J.vo=function(a,b){return J.w1(a).ev(a,b)}
 J.w8=function(a){return J.RE(a).gkc(a)}
 J.wC=function(a){return J.RE(a).cO(a)}
 J.wX=function(a){return J.RE(a).gGd(a)}
+J.wc=function(a){return J.RE(a).gbG(a)}
 J.wg=function(a,b){return J.U6(a).sB(a,b)}
 J.xH=function(a,b){if(typeof a=="number"&&typeof b=="number")return a-b
 return J.Wx(a).W(a,b)}
@@ -23358,17 +23718,17 @@
 C.Fm=new J.kn()
 C.yX=new J.GW()
 C.wq=new J.im()
+C.x0=new J.ht()
 C.oD=new J.P()
 C.Kn=new J.O()
-C.lM=new P.by()
 C.mI=new K.nd()
 C.Us=new A.yL()
 C.nJ=new K.vly()
 C.Wj=new P.JF()
 C.za=new A.jh()
 C.NU=new P.R8()
-C.v8=new P.W5()
-C.YZ=Q.kf.prototype
+C.v8=new P.nU()
+C.YZ=Q.Tg.prototype
 C.kk=Z.Ps.prototype
 C.WA=new L.WAE("Collected")
 C.l8=new L.WAE("Dart")
@@ -23380,59 +23740,59 @@
 C.Vy=new A.V3("disassembly-entry")
 C.Br=new A.V3("observatory-element")
 C.dA=new A.V3("heap-profile")
-C.Er=new A.V3("script-view")
+C.I3=new A.V3("script-view")
 C.E6=new A.V3("field-ref")
 C.aM=new A.V3("isolate-summary")
 C.Is=new A.V3("response-viewer")
 C.nu=new A.V3("function-view")
-C.bp=new A.V3("isolate-profile")
+C.jR=new A.V3("isolate-profile")
 C.xW=new A.V3("code-view")
 C.aQ=new A.V3("class-view")
-C.Ob=new A.V3("library-view")
+C.Gg=new A.V3("library-view")
 C.U8=new A.V3("code-ref")
 C.rc=new A.V3("message-viewer")
 C.js=new A.V3("stack-trace")
-C.h9=new A.V3("script-ref")
+C.Ur=new A.V3("script-ref")
 C.OS=new A.V3("class-ref")
-C.jF=new A.V3("isolate-list")
-C.PT=new A.V3("breakpoint-list")
+C.jFV=new A.V3("isolate-list")
+C.lT=new A.V3("breakpoint-list")
 C.KG=new A.V3("navigation-bar")
 C.VW=new A.V3("instance-ref")
 C.Gu=new A.V3("collapsible-content")
-C.Xv=new A.V3("stack-frame")
+C.pE=new A.V3("stack-frame")
 C.y2=new A.V3("observatory-application")
 C.uW=new A.V3("error-view")
 C.KH=new A.V3("json-view")
 C.YQ=new A.V3("function-ref")
-C.uy=new A.V3("library-ref")
+C.QU=new A.V3("library-ref")
 C.Tq=new A.V3("field-view")
 C.JD=new A.V3("service-ref")
 C.be=new A.V3("instance-view")
-C.Tl=E.FvP.prototype
-C.RT=new P.a6(0)
-C.OD=F.Ir.prototype
+C.er=E.Fv.prototype
+C.ny=new P.a6(0)
+C.OD=F.E9.prototype
 C.mt=H.VM(new W.e0("change"),[W.ea])
-C.T1=H.VM(new W.e0("click"),[W.Aj])
+C.pi=H.VM(new W.e0("click"),[W.Oq])
 C.MD=H.VM(new W.e0("error"),[W.ew])
 C.PP=H.VM(new W.e0("hashchange"),[W.ea])
 C.i3=H.VM(new W.e0("input"),[W.ea])
 C.fK=H.VM(new W.e0("load"),[W.ew])
 C.ph=H.VM(new W.e0("message"),[W.DD])
 C.MC=D.m8.prototype
-C.LT=A.jM.prototype
-C.Xo=U.DKl.prototype
-C.PJ=N.mk.prototype
+C.LT=A.Gk.prototype
+C.Xo=U.GG.prototype
+C.Yu=N.yb.prototype
 C.Vc=K.NM.prototype
 C.W3=W.zU.prototype
 C.cp=B.pR.prototype
 C.yK=Z.hx.prototype
 C.b9=L.u7.prototype
 C.XH=X.E7.prototype
-C.nM=D.St.prototype
+C.Qt=D.St.prototype
 C.Nm=J.Q.prototype
-C.YI=J.GW.prototype
+C.ON=J.GW.prototype
 C.jn=J.im.prototype
-C.jN=J.PE.prototype
+C.jN=J.ht.prototype
 C.CD=J.P.prototype
 C.xB=J.O.prototype
 C.Mc=function(hooks) {
@@ -23565,42 +23925,43 @@
   hooks.getTag = getTagFixed;
   hooks.prototypeForTag = prototypeForTagFixed;
 }
+C.xr=new P.by(null,null)
 C.A3=new P.Cf(null)
-C.Ap=new P.pD(null)
+C.Ap=new P.dI(null)
 C.GB=Z.vj.prototype
 C.Ab=new N.qV("FINER",400)
 C.R5=new N.qV("FINE",500)
 C.IF=new N.qV("INFO",800)
-C.xl=new N.qV("SEVERE",1000)
+C.cV=new N.qV("SEVERE",1000)
 C.UP=new N.qV("WARNING",900)
 C.Z3=R.LU.prototype
-C.MG=M.CX.prototype
+C.MG=M.T2.prototype
 I.makeConstantList = function(list) {
   list.immutable$list = init;
   list.fixed$length = init;
   return list;
 };
-C.Gb=H.VM(I.makeConstantList([127,2047,65535,1114111]),[J.im])
 C.HE=I.makeConstantList([0,0,26624,1023,0,0,65534,2047])
 C.mK=I.makeConstantList([0,0,26624,1023,65534,2047,65534,2047])
 C.yD=I.makeConstantList([0,0,26498,1023,65534,34815,65534,18431])
+C.PQ=I.makeConstantList(["active","success","warning","danger","info"])
 C.xu=I.makeConstantList([43,45,42,47,33,38,60,61,62,63,94,124])
 C.u0=I.makeConstantList(["==","!=","<=",">=","||","&&"])
-C.Fv=H.VM(I.makeConstantList([]),[J.O])
 C.Me=H.VM(I.makeConstantList([]),[P.Ms])
-C.dn=H.VM(I.makeConstantList([]),[P.tg])
+C.dn=H.VM(I.makeConstantList([]),[P.ac])
 C.hU=H.VM(I.makeConstantList([]),[P.X9])
+C.iH=H.VM(I.makeConstantList([]),[J.im])
 C.xD=I.makeConstantList([])
 C.Qy=I.makeConstantList(["in","this"])
 C.kg=I.makeConstantList([0,0,24576,1023,65534,34815,65534,18431])
 C.Wd=I.makeConstantList([0,0,32722,12287,65535,34815,65534,18431])
 C.iq=I.makeConstantList([40,41,91,93,123,125])
-C.jH=I.makeConstantList(["caption","col","colgroup","option","optgroup","tbody","td","tfoot","th","thead","tr"])
-C.uE=new H.LPe(11,{caption:null,col:null,colgroup:null,option:null,optgroup:null,tbody:null,td:null,tfoot:null,th:null,thead:null,tr:null},C.jH)
+C.zJ=I.makeConstantList(["caption","col","colgroup","option","optgroup","tbody","td","tfoot","th","thead","tr"])
+C.uE=new H.LPe(11,{caption:null,col:null,colgroup:null,option:null,optgroup:null,tbody:null,td:null,tfoot:null,th:null,thead:null,tr:null},C.zJ)
 C.uS=I.makeConstantList(["webkitanimationstart","webkitanimationend","webkittransitionend","domfocusout","domfocusin","animationend","animationiteration","animationstart","doubleclick","fullscreenchange","fullscreenerror","keyadded","keyerror","keymessage","needkey","speechchange"])
 C.FS=new H.LPe(16,{webkitanimationstart:"webkitAnimationStart",webkitanimationend:"webkitAnimationEnd",webkittransitionend:"webkitTransitionEnd",domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn",animationend:"webkitAnimationEnd",animationiteration:"webkitAnimationIteration",animationstart:"webkitAnimationStart",doubleclick:"dblclick",fullscreenchange:"webkitfullscreenchange",fullscreenerror:"webkitfullscreenerror",keyadded:"webkitkeyadded",keyerror:"webkitkeyerror",keymessage:"webkitkeymessage",needkey:"webkitneedkey",speechchange:"webkitSpeechChange"},C.uS)
-C.NI=I.makeConstantList(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
-C.dj=new H.LPe(27,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.NI)
+C.p5=I.makeConstantList(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
+C.dj=new H.LPe(27,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.p5)
 C.paX=I.makeConstantList(["name","extends","constructor","noscript","attributes"])
 C.kr=new H.LPe(5,{name:1,extends:1,constructor:1,noscript:1,attributes:1},C.paX)
 C.MEG=I.makeConstantList(["enumerate"])
@@ -23614,10 +23975,10 @@
 C.Pf=Z.uL.prototype
 C.xk=A.XP.prototype
 C.Iv=A.ir.prototype
-C.Cc=Q.NQ.prototype
+C.Cc=Q.JG.prototype
 C.c0=A.knI.prototype
 C.cJ=U.fI.prototype
-C.ep=Q.xI.prototype
+C.wU=Q.xI.prototype
 C.dX=K.nm.prototype
 C.bg=X.Vu.prototype
 C.PU=new H.GD("dart.core.Object")
@@ -23638,6 +23999,7 @@
 C.nN=new H.GD("dynamic")
 C.tP=new H.GD("entry")
 C.YU=new H.GD("error")
+C.mr=new H.GD("expanded")
 C.WQ=new H.GD("field")
 C.SK=new H.GD("fileAndLine")
 C.Aq=new H.GD("formattedAverage")
@@ -23658,15 +24020,16 @@
 C.zD=new H.GD("internal")
 C.ai=new H.GD("isEmpty")
 C.nZ=new H.GD("isNotEmpty")
-C.Y2=new H.GD("isolate")
+C.Z8=new H.GD("isolate")
 C.Gd=new H.GD("json")
 C.fy=new H.GD("kind")
 C.Wn=new H.GD("length")
 C.EV=new H.GD("library")
 C.cg=new H.GD("libraryRef")
+C.Cv=new H.GD("line")
 C.AX=new H.GD("links")
 C.PC=new H.GD("dart.core.int")
-C.wt=new H.GD("members")
+C.zu=new H.GD("members")
 C.US=new H.GD("messageType")
 C.fQ=new H.GD("methodCountSelected")
 C.UX=new H.GD("msg")
@@ -23675,12 +24038,13 @@
 C.OV=new H.GD("noSuchMethod")
 C.ap=new H.GD("oldHeapUsed")
 C.tI=new H.GD("percent")
-C.NA=new H.GD("prefix")
+C.qb3=new H.GD("prefix")
 C.vb=new H.GD("profile")
 C.kY=new H.GD("ref")
 C.c8=new H.GD("registerCallback")
+C.bD=new H.GD("relativeLink")
 C.wH=new H.GD("responses")
-C.iG=new H.GD("rootLib")
+C.iF=new H.GD("rootLib")
 C.ok=new H.GD("dart.core.Null")
 C.md=new H.GD("dart.core.double")
 C.fX=new H.GD("script")
@@ -23690,85 +24054,92 @@
 C.p1=new H.GD("ticks")
 C.jI=new H.GD("topExclusiveCodes")
 C.ch=new H.GD("topFrame")
-C.Yn=new H.GD("topInclusiveCodes")
 C.kw=new H.GD("trace")
+C.ep=new H.GD("tree")
 C.Fh=new H.GD("url")
-C.wj=new H.GD("user_name")
+C.ct=new H.GD("userName")
 C.ls=new H.GD("value")
 C.eR=new H.GD("valueType")
 C.z9=new H.GD("void")
 C.SX=H.mm('qC')
 C.WP=new H.Lm(C.SX,"K",0)
-C.brK=H.mm('Ae')
-C.xC=new H.Lm(C.brK,"V",0)
+C.SL=H.mm('Ae')
+C.xC=new H.Lm(C.SL,"V",0)
 C.QJ=H.mm('xh')
 C.wW=new H.Lm(C.QJ,"T",0)
 C.Gsc=H.mm('wn')
 C.io=new H.Lm(C.Gsc,"E",0)
 C.nz=new H.Lm(C.SX,"V",0)
 C.Ye=H.mm('hx')
+C.q0=H.mm('Dg')
+C.z6Y=H.mm('Tg')
 C.Dl=H.mm('F1')
-C.MZ=H.mm('ue')
-C.XoM=H.mm('DKl')
+C.eY=H.mm('n6')
+C.Vh=H.mm('Pz')
+C.RJ=H.mm('JG')
 C.z7=H.mm('G6')
 C.nY=H.mm('a')
 C.Yc=H.mm('iP')
 C.Qa=H.mm('u7')
-C.KI=H.mm('CX')
-C.Op=H.mm('G8')
-C.q4=H.mm('NQ')
+C.PT=H.mm('I2')
+C.Wup=H.mm('LZ')
+C.T1=H.mm('Wy')
 C.hG=H.mm('ir')
 C.aj=H.mm('fI')
+C.Qw=H.mm('Fv')
+C.la=H.mm('ZX')
 C.G4=H.mm('CN')
 C.O4=H.mm('double')
-C.nx=H.mm('fbd')
 C.yw=H.mm('int')
-C.KJ=H.mm('mk')
-C.pa=H.mm('jM')
-C.yiu=H.mm('knI')
-C.CO=H.mm('iY')
-C.eh=H.mm('xI')
-C.nA=H.mm('LU')
-C.uue=H.mm('kf')
+C.nW=H.mm('knI')
+C.iN=H.mm('yc')
+C.HI=H.mm('Pg')
+C.ila=H.mm('xI')
+C.lk=H.mm('mJ')
+C.KI=H.mm('LU')
+C.jV=H.mm('rF')
 C.JZ=H.mm('E7')
 C.wd=H.mm('vj')
 C.Oi=H.mm('Xd')
-C.CT=H.mm('St')
+C.Pa=H.mm('St')
+C.Rg=H.mm('yb')
 C.cx5=H.mm('m8')
-C.YV=H.mm('uL')
-C.nW=H.mm('GG')
+C.l49=H.mm('uL')
 C.yQ=H.mm('EH')
+C.Im=H.mm('X6')
 C.vW6=H.mm('PF')
-C.HMu=H.mm('vc')
+C.nG=H.mm('zt')
+C.Xb=H.mm('vc')
 C.yG=H.mm('nm')
+C.ow=H.mm('E9')
 C.Db=H.mm('String')
-C.Rg=H.mm('NM')
+C.EP=H.mm('NM')
 C.bh=H.mm('i6')
 C.Bm=H.mm('XP')
-C.MY=H.mm('hd')
+C.Tn=H.mm('T2')
+C.hg=H.mm('hd')
 C.dd=H.mm('pR')
 C.Ud8=H.mm('Ps')
+C.zy=H.mm('GG')
 C.pn=H.mm('qT')
 C.HL=H.mm('bool')
-C.Qf=H.mm('PE')
+C.Qf=H.mm('Null')
 C.HH=H.mm('dynamic')
 C.Gp=H.mm('cw')
 C.ri=H.mm('yy')
-C.X0=H.mm('Ir')
 C.CS=H.mm('vm')
-C.Rt=H.mm('Vu')
-C.SM=H.mm('FvP')
+C.Hk=H.mm('Gk')
+C.hN=H.mm('oI')
+C.IWi=H.mm('Vu')
 C.vB=J.is.prototype
 C.xM=new P.z0(!1)
 C.ol=W.u9.prototype
-C.hi=H.VM(new W.hP(W.pq()),[W.OJ])
+C.hi=H.VM(new W.bO(W.pq()),[W.OJ])
 $.libraries_to_load = {}
-$.D5=null
-$.ty=1
 $.te="$cachedFunction"
 $.eb="$cachedInvocation"
 $.OK=0
-$.mJ=null
+$.bf=null
 $.P4=null
 $.Ot=!1
 $.NF=null
@@ -23779,7 +24150,8 @@
 $.Bv=null
 $.oK=null
 $.tY=null
-$.TH=!1
+$.S6=null
+$.k8=null
 $.X3=C.NU
 $.Ss=0
 $.L4=null
@@ -23795,8 +24167,8 @@
 $.Bh=0
 $.uP=!0
 $.To=null
-$.Dq=["A8","Ak","B2","BN","BT","BX","Ba","Bf","C","C0","C8","Ch","D","D3","D6","Dd","De","E","Ec","F","FL","FV","Fr","GB","GG","HG","Hn","Hs","IW","Id","Ih","Im","Is","J","J3","JP","JV","Ja","Jk","Kb","KdI","M8","Md","Mi","Mu","NC","NZ","Nj","O","Om","On","PM","PQ","Pa","Pk","Pv","Pz","Q0","Qi","R3","R4","RB","RP","RR","Rg","Rz","SS","Se","So","T","T2","TP","TW","Tc","Tk","Tp","U","UD","UH","UZ","Ub","Uc","V","V1","Vk","Vr","W","W3","W4","WL","WO","WZ","Wt","X6","XG","XU","Xl","Y","Y9","YU","YW","Z","Z1","Z2","ZL","Ze","Zv","aC","aN","aZ","aq","bA","bS","bj","br","bu","cO","cU","cn","cp","ct","d0","dR","dd","du","eR","ea","ek","eo","er","es","ev","ez","f6","fk","fm","g","gA","gAq","gAy","gB","gB1","gBA","gBb","gCO","gCd","gCj","gDD","gF0","gG0","gG1","gG3","gGQ","gGd","gGj","gHX","gHu","gI","gJ0","gJS","gJf","gJp","gKE","gKM","gKV","gLA","gLm","gM0","gMB","gMU","gMj","gN","gN7","gNF","gNI","gNa","gNh","gO3","gOc","gOl","gP","gP1","gPe","gPu","gPw","gPy","gQ7","gQW","gQg","gQr","gRA","gRn","gRu","gT8","gTq","gUQ","gUV","gUj","gUy","gUz","gV4","gVa","gVl","gW0","gX3","gXc","gXh","gXt","gZ8","gZf","gZm","ga4","gaK","gai","gan","gbG","gbP","gbx","gcC","ge6","geE","geJ","geT","geb","gey","gfN","gfY","gfb","ghf","ghm","gi9","giC","giO","giZ","gig","gjL","gjO","gjb","gk5","gkG","gkU","gkc","gkf","gkp","gl0","gl7","glc","gm0","gmH","gmW","gmm","gnv","goc","gor","gpQ","gpo","gq6","gqY","gqn","grK","grZ","grs","gt0","gt5","gtD","gtH","gtK","gtN","gtT","gtY","gtb","gtgn","gtp","guD","guw","gvH","gvL","gvc","gvt","gwd","gx8","gxX","gxj","gxr","gyP","gyT","gys","gz1","gzP","gzZ","gzh","gzj","h","h8","hZ","hc","hr","i","i4","iA","iM","iw","j","jT","jh","jp","jx","k0","kO","l5","lJ","lj","m","mK","mv","n","n8","nB","nC","nH","nN","ni","nq","oB","oC","oP","oW","oX","od","oo","pM","pZ","pr","ps","q1","qA","qC","qZ","r6","rJ","sAq","sB","sB1","sBA","sCO","sF0","sG1","sGQ","sGj","sHX","sHu","sIt","sJ0","sMU","sMj","sN7","sNI","sNa","sNh","sOc","sOl","sP","sPe","sPw","sPy","sQr","sRu","sTq","sUy","sUz","sV4","sVa","sX3","sXc","sXh","sZ8","sa4","sai","san","scC","se6","seE","seJ","seb","sfY","shm","siZ","sig","sjO","sk5","skc","skf","sl7","sm0","snv","soc","sqY","srK","srs","st0","st5","stD","stK","stN","stT","stY","stb","suw","svL","svt","sxj","sxr","sz1","szZ","szh","szj","t","tX","tZ","te","tg","tt","u","u8","uB","uq","wE","wH","wL","wR","wW","wY","wg","x3","xc","xe","xo","y0","yC","yG","yM","yN","yc","ym","yn","yq","yu","yx","yy","z2","zV","zr"]
-$.Au=[C.Ye,Z.hx,{created:Z.Co},C.Dl,V.F1,{created:V.fv},C.MZ,P.ue,{"":P.q3},C.XoM,U.DKl,{created:U.v9},C.z7,B.G6,{created:B.Dw},C.Qa,L.u7,{created:L.Cu},C.KI,M.CX,{created:M.SP},C.Op,P.G8,{},C.q4,Q.NQ,{created:Q.Zo},C.hG,A.ir,{created:A.oa},C.aj,U.fI,{created:U.Ry},C.G4,O.CN,{created:O.On},C.nx,P.fbd,{},C.KJ,N.mk,{created:N.N0},C.pa,A.jM,{created:A.cY},C.yiu,A.knI,{created:A.Th},C.CO,P.iY,{"":P.am},C.eh,Q.xI,{created:Q.lK},C.nA,R.LU,{created:R.rA},C.uue,Q.kf,{created:Q.rt},C.JZ,X.E7,{created:X.jD},C.wd,Z.vj,{created:Z.mA},C.Oi,F.Xd,{created:F.L1},C.CT,D.St,{created:D.JR},C.cx5,D.m8,{created:D.Tt},C.YV,Z.uL,{created:Z.Hx},C.nW,P.GG,{"":P.l6},C.vW6,L.PF,{created:L.A5},C.HMu,F.vc,{created:F.Fe},C.yG,K.nm,{created:K.an},C.Rg,K.NM,{created:K.op},C.bh,R.i6,{created:R.Hv},C.Bm,A.XP,{created:A.XL},C.MY,W.hd,{},C.dd,B.pR,{created:B.lu},C.Ud8,Z.Ps,{created:Z.zg},C.pn,Q.qT,{created:Q.BW},C.ri,W.yy,{},C.X0,F.Ir,{created:F.TW},C.Rt,X.Vu,{created:X.bV},C.SM,E.FvP,{created:E.AH}]
+$.Dq=["AZ","Ak","B2","BN","BT","BX","Ba","Bf","Bk","C","C0","C4","CL","Ch","D","D3","D6","Dd","De","E","Ec","F","FL","FV","Fr","G6","GB","GG","GT","HG","Hn","Hs","IW","Id","Ih","Is","J","J2","J3","JG","JP","JV","Ja","Jk","KI","Kb","LV","LZ","M8","Md","Mi","Mq","Mu","NC","NZ","Ne","Nj","O","Om","On","PM","PQ","PZ","Pa","Pk","Pv","Pz","Q0","Qi","Qq","R3","R4","RB","RP","RR","Rg","Rz","SS","Se","T","TJ","TP","TW","Ta","Tc","Tk","Tp","U","UD","UH","UZ","Ub","Uc","V","V1","VR","Vk","Vr","W","W3","W4","WL","WO","WZ","Wt","X6","XG","XL","XU","Xl","Y","Y9","YF","YU","YW","Z","Z1","Z2","ZB","ZL","Zc","Ze","Zv","aC","aN","aZ","bA","bS","bj","br","bu","cO","cU","cn","cp","ct","d0","dR","dd","du","eR","ea","ek","eo","er","es","ev","ez","f6","f9","fk","fm","fz","g","gA","gAq","gAy","gB","gB1","gBA","gBW","gCO","gCY","gCd","gCj","gDD","gEh","gF0","gF8","gG0","gG1","gG3","gGQ","gGd","gGj","gHX","gHm","gHu","gI","gIF","gIt","gJ0","gJS","gJf","gJp","gKE","gKM","gKV","gLA","gLm","gLx","gM0","gMB","gMj","gMt","gN","gN7","gNF","gNI","gNa","gNh","gNl","gO3","gOc","gOl","gP","gP1","gPe","gPu","gPw","gPy","gQ7","gQW","gQg","gQr","gRA","gRd","gRn","gRu","gTq","gUQ","gUV","gUj","gUy","gUz","gV4","gVa","gVl","gW0","gWT","gX3","gXc","gXh","gXt","gZ8","gZf","ga4","gaK","gai","gan","gbG","gbP","gbx","gcC","ge6","geJ","geT","geb","gey","gfN","gfY","gfb","gfc","ghU","ghf","ghm","gi9","giC","giO","gig","gjL","gjO","gjT","gjb","gk5","gkG","gkU","gkc","gkf","gkp","gl0","gl7","glc","gm0","gm2","gmH","gmW","gmm","gng","gnv","goE","goc","gor","gpQ","gpo","gq6","gqO","gqX","gqY","gqn","grK","grZ","grj","grs","gt0","gt5","gtD","gtH","gtN","gtT","gtY","gtp","guD","guw","gvH","gvL","gvc","gvt","gwd","gx8","gxX","gxj","gxr","gyH","gyT","gys","gz1","gzP","gzZ","gzh","gzj","gzw","h","h8","hZ","hc","hr","i","i4","iM","iw","j","jh","jp","jx","k0","kO","ka","l5","lj","m","mK","n","nB","nC","nH","ni","nq","nt","oB","oC","oP","oW","oZ","od","oo","pM","pZ","pr","ps","q1","qA","qC","qH","qZ","r4","r6","rJ","sAq","sAy","sB","sB1","sBA","sBW","sCO","sCY","sCd","sCj","sEh","sF0","sF8","sG1","sG3","sGQ","sGd","sGj","sHX","sHm","sHu","sIF","sIt","sJ0","sJS","sKM","sKV","sLA","sLx","sM0","sMB","sMj","sMt","sN","sN7","sNF","sNI","sNa","sNh","sNl","sO3","sOc","sOl","sP","sPe","sPu","sPw","sPy","sQ7","sQr","sRA","sRd","sRn","sRu","sTq","sUQ","sUy","sUz","sV4","sVa","sWT","sX3","sXc","sXh","sXt","sZ8","sa4","saK","sai","san","sbG","sbP","scC","se6","seJ","seT","seb","sfN","sfY","sfb","sfc","shU","shf","shm","siC","sig","sjL","sjO","sjT","sjb","sk5","skG","skU","skc","skf","skp","sl7","sm0","sm2","smH","sng","snv","soE","soc","spQ","spo","sq6","sqO","sqX","sqY","srK","srs","st0","st5","stD","stN","stT","stY","suD","suw","svH","svL","svt","swd","sxX","sxj","sxr","syH","syT","sys","sz1","szZ","szh","szj","szw","t","tZ","tg","tt","tx","u","u8","uB","w","wE","wH","wL","wR","wW","wg","x3","xc","xe","xo","y0","yC","yF","yG","yM","yN","yc","ym","yn","yq","yu","yx","yy","z2","zV","zr"]
+$.Au=[C.Ye,Z.hx,{created:Z.HC},C.q0,H.Dg,{"":H.bu},C.z6Y,Q.Tg,{created:Q.rt},C.Dl,V.F1,{created:V.fv},C.RJ,Q.JG,{created:Q.Zo},C.z7,B.G6,{created:B.Dw},C.Qa,L.u7,{created:L.Cu},C.Wup,H.LZ,{"":H.UI},C.hG,A.ir,{created:A.oa},C.aj,U.fI,{created:U.Ry},C.Qw,E.Fv,{created:E.AH},C.G4,O.CN,{created:O.On},C.nW,A.knI,{created:A.Th},C.HI,H.Pg,{"":H.aR},C.ila,Q.xI,{created:Q.lK},C.KI,R.LU,{created:R.rA},C.JZ,X.E7,{created:X.jD},C.wd,Z.vj,{created:Z.mA},C.Oi,F.Xd,{created:F.L1},C.Pa,D.St,{created:D.JR},C.Rg,N.yb,{created:N.N0},C.cx5,D.m8,{created:D.Tt},C.l49,Z.uL,{created:Z.Hx},C.vW6,L.PF,{created:L.A5},C.Xb,F.vc,{created:F.Fe},C.yG,K.nm,{created:K.an},C.ow,F.E9,{created:F.TW},C.EP,K.NM,{created:K.op},C.bh,R.i6,{created:R.Hv},C.Bm,A.XP,{created:A.XL},C.Tn,M.T2,{created:M.SP},C.hg,W.hd,{},C.dd,B.pR,{created:B.b4},C.Ud8,Z.Ps,{created:Z.zg},C.zy,U.GG,{created:U.v9},C.pn,Q.qT,{created:Q.BW},C.ri,W.yy,{},C.Hk,A.Gk,{created:A.cY},C.IWi,X.Vu,{created:X.B4}]
 I.$lazy($,"globalThis","DX","jk",function(){return function() { return this; }()})
 I.$lazy($,"globalWindow","pG","Qm",function(){return $.jk().window})
 I.$lazy($,"globalWorker","zA","Nl",function(){return $.jk().Worker})
@@ -23842,24 +24214,21 @@
 I.$lazy($,"customElementsReady","xp","ax",function(){return new B.wJ().call$0()})
 I.$lazy($,"_toStringList","Ml","RM",function(){return[]})
 I.$lazy($,"validationPattern","zP","R0",function(){return new H.VR(H.v4("^(?:[a-zA-Z$][a-zA-Z$0-9_]*\\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|-|unary-|\\[\\]=|~|==|\\[\\]|\\*|/|%|~/|\\+|<<|>>|>=|>|<=|<|&|\\^|\\|)$",!1,!0,!1),null,null)})
-I.$lazy($,"_dynamicType","QG","Cr",function(){return new H.EE(C.nN)})
+I.$lazy($,"_dynamicType","QG","P8",function(){return new H.EE(C.nN)})
 I.$lazy($,"_voidType","Q3","oj",function(){return new H.EE(C.z9)})
 I.$lazy($,"librariesByName","Ct","vK",function(){return H.dF()})
 I.$lazy($,"currentJsMirrorSystem","GR","Cm",function(){return new H.Sn(null,new H.Lj(init.globalState.N0))})
 I.$lazy($,"mangledNames","tj","bx",function(){return H.hY(init.mangledNames,!1)})
 I.$lazy($,"reflectiveNames","DE","I6",function(){return H.YK($.bx())})
 I.$lazy($,"mangledGlobalNames","iC","Sl",function(){return H.hY(init.mangledGlobalNames,!0)})
-I.$lazy($,"_asyncCallbacks","r1","P8",function(){var z,y
-z={func:"X0",void:true}
-y=H.VM(new P.Sw(null,0,0,0),[z])
-y.Eo(null,z)
-return y})
 I.$lazy($,"_toStringVisiting","xg","xb",function(){return P.yv(null)})
 I.$lazy($,"_toStringList","yu","tw",function(){return[]})
-I.$lazy($,"_splitRe","Um","cO",function(){return new H.VR(H.v4("^(?:([^:/?#]+):)?(?://(?:([^/?#]*)@)?(?:([\\w\\d\\-\\u0100-\\uffff.%]*)|\\[([A-Fa-f0-9:.]*)\\])(?::([0-9]+))?)?([^?#[]+)?(?:\\?([^#]*))?(?:#(.*))?$",!1,!0,!1),null,null)})
+I.$lazy($,"_splitRe","Um","qG",function(){return new H.VR(H.v4("^(?:([^:/?#]+):)?(?://(?:([^/?#]*)@)?(?:([\\w\\d\\-\\u0100-\\uffff.%]*)|\\[([A-Fa-f0-9:.]*)\\])(?::([0-9]+))?)?([^?#[]+)?(?:\\?([^#]*))?(?:#(.*))?$",!1,!0,!1),null,null)})
 I.$lazy($,"_safeConsole","wk","pl",function(){return new W.QZ()})
 I.$lazy($,"webkitEvents","fD","Vp",function(){return H.B7(["animationend","webkitAnimationEnd","animationiteration","webkitAnimationIteration","animationstart","webkitAnimationStart","fullscreenchange","webkitfullscreenchange","fullscreenerror","webkitfullscreenerror","keyadded","webkitkeyadded","keyerror","webkitkeyerror","keymessage","webkitkeymessage","needkey","webkitneedkey","pointerlockchange","webkitpointerlockchange","pointerlockerror","webkitpointerlockerror","resourcetimingbufferfull","webkitresourcetimingbufferfull","transitionend","webkitTransitionEnd","speechchange","webkitSpeechChange"],P.L5(null,null,null,null,null))})
 I.$lazy($,"context","eo","cM",function(){return P.ND(function() { return this; }())})
+I.$lazy($,"_DART_OBJECT_PROPERTY_NAME","kt","Iq",function(){return init.getIsolateTag("_$dart_dartObject")})
+I.$lazy($,"_DART_CLOSURE_PROPERTY_NAME","Ri","Dp",function(){return init.getIsolateTag("_$dart_dartClosure")})
 I.$lazy($,"_loggers","DY","U0",function(){return H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,N.TJ])})
 I.$lazy($,"currentIsolateMatcher","qY","oy",function(){return new H.VR(H.v4("#/isolates/\\d+",!1,!0,!1),null,null)})
 I.$lazy($,"currentIsolateProfileMatcher","HT","wf",function(){return new H.VR(H.v4("#/isolates/\\d+/profile",!1,!0,!1),null,null)})
@@ -23872,22 +24241,13 @@
 I.$lazy($,"_pathRegExp","Jm","tN",function(){return new L.Md().call$0()})
 I.$lazy($,"_spacesRegExp","JV","c3",function(){return new H.VR(H.v4("\\s",!1,!0,!1),null,null)})
 I.$lazy($,"_logger","y7","aT",function(){return N.Jx("observe.PathObserver")})
-I.$lazy($,"url","As","jo",function(){var z,y
-z=$.wE()
-y=z==null?B.ab():"."
-if(z==null)z=$.Ur()
-return new F.lI(z,y)})
-I.$lazy($,"posix","yr","KL",function(){return new Z.OF("posix","/",new H.VR(H.v4("/",!1,!0,!1),null,null),new H.VR(H.v4("[^/]$",!1,!0,!1),null,null),new H.VR(H.v4("^/",!1,!0,!1),null,null),null)})
-I.$lazy($,"windows","ho","CE",function(){return new T.IV("windows","\\",new H.VR(H.v4("[/\\\\]",!1,!0,!1),null,null),new H.VR(H.v4("[^/\\\\]$",!1,!0,!1),null,null),new H.VR(H.v4("^(\\\\\\\\[^\\\\]+\\\\[^\\\\/]+|[a-zA-Z]:[/\\\\])",!1,!0,!1),null,null),new H.VR(H.v4("^[/\\\\](?![/\\\\])",!1,!0,!1),null,null),null)})
-I.$lazy($,"url","aC","wE",function(){return new E.rM("url","/",new H.VR(H.v4("/",!1,!0,!1),null,null),new H.VR(H.v4("(^[a-zA-Z][-+.a-zA-Z\\d]*://|[^/])$",!1,!0,!1),null,null),new H.VR(H.v4("[a-zA-Z][-+.a-zA-Z\\d]*://[^/]*",!1,!0,!1),null,null),new H.VR(H.v4("^/",!1,!0,!1),null,null),null)})
-I.$lazy($,"platform","Uc","Ur",function(){return S.Rh()})
 I.$lazy($,"_typesByName","Hi","Ej",function(){return P.L5(null,null,null,J.O,P.uq)})
 I.$lazy($,"_waitType","Mp","p2",function(){return P.L5(null,null,null,J.O,A.XP)})
 I.$lazy($,"_waitSuper","uv","xY",function(){return P.L5(null,null,null,J.O,[J.Q,A.XP])})
 I.$lazy($,"_declarations","EJ","cd",function(){return P.L5(null,null,null,J.O,A.XP)})
 I.$lazy($,"_objectType","Cy","Tf",function(){return P.re(C.nY)})
 I.$lazy($,"_sheetLog","Fa","vM",function(){return N.Jx("polymer.stylesheet")})
-I.$lazy($,"_reverseEventTranslations","fp","pT",function(){return new A.w11().call$0()})
+I.$lazy($,"_reverseEventTranslations","fp","QX",function(){return new A.w9().call$0()})
 I.$lazy($,"bindPattern","ZA","VC",function(){return new H.VR(H.v4("\\{\\{([^{}]*)}}",!1,!0,!1),null,null)})
 I.$lazy($,"_polymerSyntax","Df","Nd",function(){var z=P.L5(null,null,null,J.O,P.a)
 z.FV(0,C.va)
@@ -23902,23 +24262,19 @@
 I.$lazy($,"_librariesToLoad","x2","nT",function(){return A.GA(document,J.CC(C.ol.gmW(window)),null,null)})
 I.$lazy($,"_libs","D9","UG",function(){return $.Cm().gvU()})
 I.$lazy($,"_rootUri","aU","RQ",function(){return $.Cm().Aq.gcZ().gFP()})
-I.$lazy($,"_packageRoot","Po","rw",function(){var z,y
-z=$.jo()
-y=J.CC(C.ol.gmW(window))
-return z.tX(0,z.tM(P.r6($.cO().ej(y)).r0),"packages")+"/"})
 I.$lazy($,"_loaderLog","ha","M7",function(){return N.Jx("polymer.loader")})
-I.$lazy($,"_typeHandlers","FZ","WJ",function(){return new Z.W6().call$0()})
+I.$lazy($,"_typeHandlers","lq","CT",function(){return new Z.W6().call$0()})
 I.$lazy($,"_logger","m0","eH",function(){return N.Jx("polymer_expressions")})
-I.$lazy($,"_BINARY_OPERATORS","AM","e6",function(){return H.B7(["+",new K.Ra(),"-",new K.wJY(),"*",new K.zOQ(),"/",new K.W6o(),"==",new K.MdQ(),"!=",new K.YJG(),">",new K.DOe(),">=",new K.lPa(),"<",new K.Ufa(),"<=",new K.Raa(),"||",new K.w0(),"&&",new K.w4(),"|",new K.w5()],P.L5(null,null,null,null,null))})
-I.$lazy($,"_UNARY_OPERATORS","ju","ww",function(){return H.B7(["+",new K.w7(),"-",new K.w9(),"!",new K.w10()],P.L5(null,null,null,null,null))})
-I.$lazy($,"_checkboxEventType","S8","FF",function(){return new M.lP().call$0()})
+I.$lazy($,"_BINARY_OPERATORS","AM","e6",function(){return H.B7(["+",new K.lP(),"-",new K.Uf(),"*",new K.Ra(),"/",new K.wJY(),"==",new K.zOQ(),"!=",new K.W6o(),">",new K.MdQ(),">=",new K.YJG(),"<",new K.DOe(),"<=",new K.lPa(),"||",new K.Ufa(),"&&",new K.Raa(),"|",new K.w0()],P.L5(null,null,null,null,null))})
+I.$lazy($,"_UNARY_OPERATORS","ju","ww",function(){return H.B7(["+",new K.w4(),"-",new K.w5(),"!",new K.w7()],P.L5(null,null,null,null,null))})
+I.$lazy($,"_checkboxEventType","S8","FF",function(){return new M.YJ().call$0()})
 I.$lazy($,"_contentsOwner","mn","LQ",function(){return H.VM(new P.kM(null),[null])})
 I.$lazy($,"_ownerStagingDocument","EW","JM",function(){return H.VM(new P.kM(null),[null])})
-I.$lazy($,"_allTemplatesSelectors","Sf","cz",function(){return"template, "+J.C0(C.uE.gvc(C.uE),new M.Uf()).zV(0,", ")})
-I.$lazy($,"_expando","fF","cm",function(){return H.VM(new P.kM("template_binding"),[null])})
+I.$lazy($,"_allTemplatesSelectors","Sf","cz",function(){return"template, "+J.C0(C.uE.gvc(C.uE),new M.DO()).zV(0,", ")})
+I.$lazy($,"_expando","fF","rw",function(){return H.VM(new P.kM("template_binding"),[null])})
 
 init.functionAliases={}
-init.metadata=[P.a,C.WP,C.nz,C.xC,C.io,C.wW,"object","interceptor","proto","extension","indexability","type","name","codeUnit","isolate","function","entry","sender","e","msg","message","x","record","value","memberName",{func:"pL",args:[J.O]},"string","source","radix","handleError","array","codePoints","charCodes","years","month","day","hours","minutes","seconds","milliseconds","isUtc","receiver","key","positionalArguments","namedArguments","className","argument","index","ex","expression","keyValuePairs","result","closure","numberOfArguments","arg1","arg2","arg3","arg4","arity","functions","reflectionInfo","isStatic","jsArguments","propertyName","isIntercepted","fieldName","property","staticName","list","returnType","parameterTypes","optionalParameterTypes","rti","typeArguments","target","typeInfo","substitutionName",,"onTypeVariable","types","startIndex","substitution","arguments","isField","checks","asField","s","t","signature","context","contextName","o","allowShorter","obj","tag","interceptorClass","transformer","hooks","pattern","multiLine","caseSensitive","global","needle","haystack","other","from","to",{func:"X0",void:true},{func:"NT"},"iterable","f","initialValue","combine","leftDelimiter","rightDelimiter","start","end","skipCount","src","srcStart","dst","dstStart","count","a","element","endIndex","left","right","compare","symbol",{func:"pB",ret:P.vr,args:[P.a]},"reflectee","mangledName","methods","variables","mixinNames","code","typeVariables","owner","simpleName","victim","fieldSpecification","jsMangledNames","isGlobal","map","errorHandler","error","stackTrace","zone","listeners","callback","notificationHandler",{func:"G5",void:true,args:[null]},{func:"Vx",void:true,args:[null],opt:[P.MN]},"userCode","onSuccess","onError","subscription","future","duration",{func:"cX",void:true,args:[P.JB,P.e4,P.JB,null,P.MN]},"self","parent",{func:"aD",args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"wD",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]},null]},"arg",{func:"ta",args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]},null,null]},{func:"HQ",ret:{func:"NT"},args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"v7",ret:{func:"Dv",args:[null]},args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"IU",ret:{func:"bh",args:[null,null]},args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]}]},{func:"qH",void:true,args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"zo",ret:P.tU,args:[P.JB,P.e4,P.JB,P.a6,{func:"X0",void:true}]},{func:"Zb",void:true,args:[P.JB,P.e4,P.JB,J.O]},"line",{func:"xM",void:true,args:[J.O]},{func:"Nf",ret:P.JB,args:[P.JB,P.e4,P.JB,P.aY,[P.Z0,P.wv,null]]},"specification","zoneValues","table",{func:"Ib",ret:J.kn,args:[null,null]},"b",{func:"Re",ret:J.im,args:[null]},"parts","m","number","json","reviver",{func:"uJ",ret:P.a,args:[null]},"toEncodable","sb",{func:"xh",ret:J.im,args:[P.fR,P.fR]},"formattedString",{func:"E0",ret:J.kn,args:[P.a,P.a]},{func:"DZ",ret:J.im,args:[P.a]},{func:"K4",ret:J.im,args:[J.O],named:{onError:{func:"jK",ret:J.im,args:[J.O]},radix:J.im}},"segments","argumentError","host","scheme","query","queryParameters","fragment","component","val","val1","val2",{func:"zs",ret:J.O,args:[J.O]},"encodedComponent",C.xM,!1,"canonicalTable","text","encoding","spaceToPlus","pos","plusToSpace",{func:"Tf",ret:J.O,args:[W.D0]},"typeExtension","url","onProgress","withCredentials","method","mimeType","requestHeaders","responseType","sendData","thing","win","constructor",{func:"Dv",args:[null]},{func:"jn",args:[null,null,null,null]},"oldValue","newValue","document","extendsTagName","w","captureThis","data","createProxy","mustCopy","_","id","members",{func:"qE",ret:J.O,args:[J.im,J.im]},"pad","current","currentStart","currentEnd","old","oldStart","oldEnd","distances","arr1","arr2","searchLength","splices","records","field","args","cls","props","getter","template","extendee","sheet","node","path","originalPrepareBinding","methodName","style","scope","doc","baseUri","seen","scripts","uriString","currentValue","v","expr","l","hash",{func:"qq",ret:[P.cX,K.Ae],args:[P.cX]},"classMirror","c","delegate","model","bound","stagingDocument","el","useRoot","content","bindings","n","elementId","importedNode","deep","selectors","relativeSelectors","listener","useCapture","async","password","user","timestamp","canBubble","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","attributeFilter","attributeOldValue","attributes","characterData","characterDataOldValue","childList","subtree","otherNode","newChild","refChild","oldChild","targetOrigin","messagePorts","length","invocation","collection","","separator",0,!0,"growable","fractionDigits","str","i","portId","port","dataEvent","onData","cancelOnError","onDone","info",{func:"bh",args:[null,null]},"parameter","jsConstructor",{func:"Za",args:[J.O,null]},{func:"TS",args:[null,J.O]},"g",P.Z0,L.mL,[P.Z0,J.O,W.cv],{func:"qo",ret:P.Z0},C.nJ,C.Us,{func:"Hw",args:[P.Z0]},B.Vf,J.kn,Q.xI,Z.pv,L.kx,{func:"bR",ret:L.kx},{func:"VI",args:[L.kx]},{func:"I0",ret:J.O},F.Vfx,J.O,C.mI,{func:"Uf",ret:J.kn},{func:"zk",args:[J.kn]},"r",{func:"Np",void:true,args:[W.ea,null,W.uH]},R.Dsd,"action","test","library",{func:"h0",args:[H.Uz]},{func:"rm",args:[P.wv,P.ej]},"reflectiveName",{func:"lv",args:[P.wv,null]},"typeArgument","tv","methodOwner","fieldOwner",{func:"qe",ret:P.Ms,args:[J.im]},{func:"Z5",args:[J.im]},{func:"Pt",ret:J.O,args:[J.im]},{func:"ag",args:[J.O,J.O]},"eventId",{func:"uu",void:true,args:[P.a],opt:[P.MN]},{func:"YP",void:true,opt:[null]},{func:"BG",args:[null],opt:[null]},"ignored","convert","isMatch",{func:"rt",ret:P.b8},"pendingEvents","handleData","handleDone","resumeSignal","event","wasInputPaused",{func:"wN",void:true,args:[P.MO]},"dispatch",{func:"ha",args:[null,P.MN]},"sink",{func:"aR",void:true,args:[null,P.MN]},"inputEvent","otherZone","runGuarded","bucket","each","ifAbsent","cell","objects","orElse","k","elements","offset","comp","key1","key2",{func:"Q5",ret:J.kn,args:[P.jp]},{func:"ES",args:[J.O,P.a]},"leadingSurrogate","nextCodeUnit","codeUnits","matched",{func:"jK",ret:J.im,args:[J.O]},{func:"Zh",ret:J.GW,args:[J.O]},"factor","quotient","pathSegments","base","reference","windows","segment","ch",{func:"cd",ret:J.kn,args:[J.im]},"digit",{func:"Dt",ret:J.im,args:[J.im]},"part",{func:"wJ",ret:J.im,args:[null,null]},"byteString",{func:"BC",ret:J.im,args:[J.im,J.im]},"byte","buffer",{func:"YI",void:true,args:[P.a]},"title","xhr","header","prevValue","selector","stream",L.DP,{func:"JA",ret:L.DP},{func:"Qs",args:[L.DP]},E.tuj,F.Vct,A.D13,N.WZq,{func:"Xb",args:[P.Z0,J.im]},{func:"hN",ret:J.O,args:[J.kn]},"newSpace",K.pva,"response",H.Tp,"st",{func:"iR",args:[J.im,null]},Z.cda,Z.uL,J.im,J.Q,{func:"cH",ret:J.im},{func:"r5",ret:J.Q},{func:"mR",args:[J.Q]},{func:"ub",void:true,args:[L.bv,J.im,P.Z0]},"totalSamples",{func:"F9",void:true,args:[L.bv]},{func:"Jh",ret:J.O,args:[L.kx,J.kn]},"inclusive",{func:"Nu",ret:J.O,args:[L.kx]},X.waa,"profile",L.bv,{func:"Wy",ret:L.bv},{func:"Gt",args:[L.bv]},D.V0,Z.V4,M.V6,"logLevel","rec",{func:"IM",args:[N.HV]},{func:"cr",ret:[J.Q,P.Z0]},[J.Q,J.O],{func:"he",ret:[J.Q,J.O]},{func:"ZD",args:[[J.Q,J.O]]},"link",F.V10,L.dZ,L.R2,L.pt,"label","row",[P.Z0,J.O,L.rj],[J.Q,L.kx],[P.Z0,J.O,J.GW],{func:"Jm",ret:L.CM},{func:"Ve",args:[L.CM]},"address","coverages","trace","timer",[P.Z0,J.O,L.bv],"E",{func:"AU",ret:P.iD},{func:"Y4",args:[P.iD]},"scriptURL",{func:"jN",ret:J.O,args:[J.O,J.O]},"isolateId",{func:"fP",ret:J.GW},{func:"mV",args:[J.GW]},[J.Q,L.DP],"instructionList","dartCode","kind","otherCode","profileCode","tick",{func:"Ce",args:[L.N8]},{func:"VL",args:[L.kx,L.kx]},[J.Q,L.c2],{func:"dt",ret:P.cX},"lineNumber","hits",{func:"D8",args:[[J.Q,P.Z0]]},"responseString","requestString",{func:"Tz",void:true,args:[null,null]},V.V11,{func:"AG",void:true,args:[J.O,J.O,J.O]},{func:"ru",ret:L.mL},{func:"pu",args:[L.mL]},{func:"nxg",ret:J.O,args:[J.GW]},"time","bytes",{func:"kX",ret:J.O,args:[P.Z0]},"frame",Z.LP,{func:"Aa",args:[P.e4,P.JB]},{func:"TB",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"jc",ret:J.kn,args:[P.a]},{func:"Gm",args:[[J.Q,G.DA]]},{func:"mRV",args:[[J.Q,T.z2]]},"part1","part2","part3","part4","part5","part6","part7","part8","superDecl","delegates","matcher","scopeDescriptor","cssText","properties","onName","eventType","declaration","elementElement","root",{func:"qk",void:true,args:[J.O,J.O]},"preventCascade",{func:"KT",void:true,args:[[P.cX,T.z2]]},"changes","events",{func:"WW",void:true,args:[W.ea]},"callbackOrMethod","pair","p",{func:"YT",void:true,args:[[J.Q,T.z2]]},"d","def",{func:"Zu",args:[J.O,null,null]},"arg0",{func:"pp",ret:U.zX,args:[U.hw,U.hw]},"h","item","precedence","prefix",3,{func:"Nt",args:[U.hw]},L.rj,{func:"YE",ret:L.rj},{func:"PF",args:[L.rj]},{func:"Yg",ret:J.O,args:[L.c2]},U.V12,"coverage",Q.Ds,K.V13,X.V14,"y","instanceRef",{func:"en",ret:J.O,args:[P.a]},{func:"IK",ret:J.O,args:[[J.Q,P.a]]},"values","instanceNodes",{func:"K7",void:true,args:[[J.Q,G.DA]]},];$=null
+init.metadata=[P.a,C.WP,C.nz,C.xC,C.io,C.wW,"object","interceptor","proto","extension","indexability","type","name","codeUnit","isolate","function","entry","sender","e","msg","message","x","record","value","memberName",{func:"pL",args:[J.O]},"string","source","radix","handleError","array","codePoints","charCodes","years","month","day","hours","minutes","seconds","milliseconds","isUtc","receiver","key","positionalArguments","namedArguments","className","argument","index","ex","expression","keyValuePairs","result","closure","numberOfArguments","arg1","arg2","arg3","arg4","arity","functions","reflectionInfo","isStatic","jsArguments","propertyName","isIntercepted","fieldName","property","staticName","list","returnType","parameterTypes","optionalParameterTypes","rti","typeArguments","target","typeInfo","substitutionName",,"onTypeVariable","types","startIndex","substitution","arguments","isField","checks","asField","s","t","signature","context","contextName","o","allowShorter","obj","tag","interceptorClass","transformer","hooks","pattern","multiLine","caseSensitive","global","needle","haystack","other","from","to",{func:"kl",void:true},{func:"NT"},"iterable","f","initialValue","combine","leftDelimiter","rightDelimiter","start","end","skipCount","src","srcStart","dst","dstStart","count","a","element","endIndex","left","right","compare","symbol",{func:"pB",ret:P.vr,args:[P.a]},"reflectee","mangledName","methods","variables","mixinNames","code","typeVariables","owner","simpleName","victim","fieldSpecification","jsMangledNames","isGlobal","map","errorHandler","zone","listeners","callback","notificationHandler",{func:"G5",void:true,args:[null]},{func:"Vx",void:true,args:[null],opt:[P.MN]},"error","stackTrace","userCode","onSuccess","onError","subscription","future","duration",{func:"cX",void:true,args:[P.JB,P.e4,P.JB,null,P.MN]},"self","parent",{func:"aD",args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"wD",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]},null]},"arg",{func:"ta",args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]},null,null]},{func:"HQ",ret:{func:"NT"},args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"v7",ret:{func:"Dv",args:[null]},args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"IU",ret:{func:"bh",args:[null,null]},args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]}]},{func:"iV",void:true,args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"zo",ret:P.lO,args:[P.JB,P.e4,P.JB,P.a6,{func:"kl",void:true}]},{func:"Zb",void:true,args:[P.JB,P.e4,P.JB,J.O]},"line",{func:"xM",void:true,args:[J.O]},{func:"Nf",ret:P.JB,args:[P.JB,P.e4,P.JB,P.aY,[P.Z0,P.wv,null]]},"specification","zoneValues","table",{func:"Ib",ret:J.kn,args:[null,null]},"b",{func:"Re",ret:J.im,args:[null]},"parts","m","number","json","reviver",{func:"uJ",ret:P.a,args:[null]},"toEncodable","sb",{func:"xh",ret:J.im,args:[P.fR,P.fR]},"formattedString",{func:"E0",ret:J.kn,args:[P.a,P.a]},{func:"DZ",ret:J.im,args:[P.a]},{func:"K4",ret:J.im,args:[J.O],named:{onError:{func:"Tl",ret:J.im,args:[J.O]},radix:J.im}},"host","scheme","query","queryParameters","fragment","component","val","val1","val2",C.xM,!1,"canonicalTable","text","encoding","spaceToPlus",{func:"Tf",ret:J.O,args:[W.D0]},"typeExtension","url","onProgress","withCredentials","method","mimeType","requestHeaders","responseType","sendData","thing","win","constructor",{func:"Dv",args:[null]},{func:"jn",args:[null,null,null,null]},"oldValue","newValue","document","extendsTagName","w","captureThis","data","createProxy","mustCopy","total","_","id","members",{func:"qE",ret:J.O,args:[J.im,J.im]},"pad","current","currentStart","currentEnd","old","oldStart","oldEnd","distances","arr1","arr2","searchLength","splices","records","field","cls","props","getter","template","extendee","sheet","node","path","originalPrepareBinding","methodName","args","style","scope","doc","baseUri","seen","scripts","uriString","currentValue","v","expr","l","hash",{func:"qq",ret:[P.cX,K.Ae],args:[P.cX]},"classMirror","c","delegate","model","bound","stagingDocument","el","useRoot","content","bindings","n","elementId","deep","selectors","relativeSelectors","listener","useCapture","async","password","user","timestamp","canBubble","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","attributeFilter","attributeOldValue","attributes","characterData","characterDataOldValue","childList","subtree","otherNode","newChild","refChild","oldChild","targetOrigin","messagePorts","length","invocation","collection","","separator",0,!0,"growable","fractionDigits","str","authentification","resume","portId","port","dataEvent","info",{func:"bh",args:[null,null]},"parameter","jsConstructor",{func:"Za",args:[J.O,null]},{func:"TS",args:[null,J.O]},"g",P.Z0,L.mL,[P.Z0,J.O,W.cv],{func:"qo",ret:P.Z0},C.nJ,C.Us,{func:"Hw",args:[P.Z0]},B.Vf,J.kn,L.bv,Q.xI,Z.pv,L.kx,{func:"bR",ret:L.kx},{func:"VI",args:[L.kx]},{func:"I0",ret:J.O},F.Vfx,J.O,C.mI,{func:"Uf",ret:J.kn},{func:"zk",args:[J.kn]},"r",{func:"Np",void:true,args:[W.ea,null,W.KV]},R.Dsd,"action","test","library",{func:"h0",args:[H.Uz]},{func:"rm",args:[P.wv,P.ej]},"reflectiveName","useEval",{func:"lv",args:[P.wv,null]},"typeArgument","tv","methodOwner","fieldOwner","i",{func:"qe",ret:P.Ms,args:[J.im]},{func:"Z5",args:[J.im]},{func:"K6",ret:P.X9,args:[J.im]},{func:"Pt",ret:J.O,args:[J.im]},{func:"ag",args:[J.O,J.O]},"eventId",{func:"uu",void:true,args:[P.a],opt:[P.MN]},{func:"YP",void:true,opt:[null]},{func:"BG",args:[null],opt:[null]},"ignored","convert","isMatch","cancelOnError","handleData","handleDone","resumeSignal","event","wasInputPaused","onData","onDone","dispatch",{func:"ha",args:[null,P.MN]},"sink",{func:"aR",void:true,args:[null,P.MN]},"inputEvent","otherZone","runGuarded","bucket","each","ifAbsent","cell","objects","orElse","k","elements","offset","comp","key1","key2",{func:"Q5",ret:J.kn,args:[P.jp]},{func:"dc",args:[J.O,P.a]},"leadingSurrogate","nextCodeUnit","matched",{func:"Tl",ret:J.im,args:[J.O]},{func:"Zh",ret:J.GW,args:[J.O]},"factor","quotient","pathSegments","base","reference","ss","ch",{func:"cd",ret:J.kn,args:[J.im]},"digit",{func:"Dt",ret:J.im,args:[J.im]},"part",{func:"wJ",ret:J.im,args:[null,null]},"byteString",{func:"BC",ret:J.im,args:[J.im,J.im]},"byte","buffer",{func:"YI",void:true,args:[P.a]},"title","xhr","header","shouldAdd","prevValue","selector","stream","pos",L.DP,{func:"JA",ret:L.DP},{func:"Qs",args:[L.DP]},E.tuj,F.Vct,A.D13,N.WZq,{func:"Xb",args:[P.Z0,J.im]},{func:"hN",ret:J.O,args:[J.kn]},"newSpace",K.pva,"response",H.Tp,"st",{func:"iR",args:[J.im,null]},{func:"ZT",void:true,args:[null,null,null]},B.T5,"trace",Z.cda,Z.uL,J.im,[J.Q,L.Y2],[J.Q,J.O],"codeCaller",{func:"UO",args:[L.Vi]},J.Q,L.XN,{func:"cH",ret:J.im},{func:"r5",ret:J.Q},{func:"mR",args:[J.Q]},{func:"ub",void:true,args:[L.bv,J.im,P.Z0]},"totalSamples",{func:"F9",void:true,args:[L.bv]},{func:"bN",ret:J.O,args:[L.Y2]},"row",{func:"Sz",void:true,args:[W.ea,null,W.cv]},X.waa,"profile",{func:"Wy",ret:L.bv},{func:"Gt",args:[L.bv]},D.V0,Z.V4,M.V10,"logLevel","rec",{func:"IM",args:[N.HV]},{func:"cr",ret:[J.Q,P.Z0]},{func:"he",ret:[J.Q,J.O]},{func:"ZD",args:[[J.Q,J.O]]},{func:"zs",ret:J.O,args:[J.O]},"link",F.V11,L.dZ,L.Nu,L.yU,"label",[P.Z0,J.O,L.rj],[J.Q,L.kx],[P.Z0,J.O,J.GW],{func:"Ik",ret:L.CM},{func:"Ve",args:[L.CM]},"address","coverages","timer",[P.Z0,J.O,L.bv],"E",{func:"EU",ret:P.iD},{func:"Y4",args:[P.iD]},"scriptURL",{func:"jN",ret:J.O,args:[J.O,J.O]},"isolateId",{func:"fP",ret:J.GW},{func:"mV",args:[J.GW]},[J.Q,L.DP],"calls","codes","instructionList","profileCode",{func:"VL",args:[L.kx,L.kx]},[J.Q,L.c2],{func:"dt",ret:P.cX},"lineNumber","hits",{func:"D8",args:[[J.Q,P.Z0]]},"responseString","requestString",{func:"Tz",void:true,args:[null,null]},"children","rowIndex",V.V12,{func:"AG",void:true,args:[J.O,J.O,J.O]},{func:"ru",ret:L.mL},{func:"pu",args:[L.mL]},{func:"nx",ret:J.O,args:[J.GW]},"time","bytes",{func:"kX",ret:J.O,args:[P.Z0]},"frame",{func:"h6",ret:J.kn,args:[J.O]},Z.LP,{func:"Aa",args:[P.e4,P.JB]},{func:"TB",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"S5",ret:J.kn,args:[P.a]},{func:"na",args:[[J.Q,G.DA]]},{func:"mRV",args:[[J.Q,T.z2]]},"superDecl","delegates","matcher","scopeDescriptor","cssText","properties","onName","eventType","declaration","elementElement","root",{func:"qk",void:true,args:[J.O,J.O]},"preventCascade",{func:"KT",void:true,args:[[P.cX,T.z2]]},"changes","events",{func:"WW",void:true,args:[W.ea]},"callbackOrMethod","pair","p",{func:"YT",void:true,args:[[J.Q,T.z2]]},"d","def",{func:"Zu",args:[J.O,null,null]},"arg0",{func:"pp",ret:U.zX,args:[U.hw,U.hw]},"h","item","kind","precedence","prefix",3,{func:"Nt",args:[U.hw]},A.qe,L.rj,{func:"LW",ret:L.rj},{func:"PF",args:[L.rj]},{func:"Yg",ret:J.O,args:[L.c2]},U.V13,"coverage",Q.Ds,K.V14,X.V15,"y","instanceRef",{func:"en",ret:J.O,args:[P.a]},{func:"IK",ret:J.O,args:[[J.Q,P.a]]},"values","instanceNodes",{func:"K7",void:true,args:[[J.Q,G.DA]]},];$=null
 I = I.$finishIsolateConstructor(I)
 $=new I()
 function convertToFastObject(properties) {
@@ -23952,10 +24308,17 @@
 X = convertToFastObject(X)
 Y = convertToFastObject(Y)
 Z = convertToFastObject(Z)
-!function(){var z=Object.prototype
-for(var y=0;;y++){var x="___dart_dispatch_record_ZxYxX_0_"
-if(y>0)x=rootProperty+"_"+y
-if(!(x in z))return init.dispatchPropertyName=x}}()
+!function(){function intern(a){var v={}
+v[a]=1
+return Object.keys(convertToFastObject(v))[0]}init.getIsolateTag=function(a){return intern("___dart_"+a+init.isolateTag)}
+var z="___dart_isolate_tags_"
+var y=Object[z]||(Object[z]=Object.create(null))
+var x="_ZxYxX"
+for(var w=0;;w++){property=intern(x+"_"+w+"_")
+if(!(property in y)){y[property]=1
+init.isolateTag=property
+break}}}()
+init.dispatchPropertyName=init.getIsolateTag("dispatch_record")
 ;(function (callback) {
   if (typeof document === "undefined") {
     callback(null);
@@ -23980,9 +24343,9 @@
   init.currentScript = currentScript;
 
   if (typeof dartMainRunner === "function") {
-    dartMainRunner(function() { H.oT(E.Im()); });
+    dartMainRunner(function() { H.oT(E.Pc()); });
   } else {
-    H.oT(E.Im());
+    H.oT(E.Pc());
   }
 })
 function init(){I.p={}
@@ -24040,7 +24403,7 @@
 if(typeof dart_precompiled=="function"){var v=dart_precompiled(a)}else{var u="function $reflectable(fn){fn.$reflectable=1;return fn};\n"+"var $desc;\n"
 var t=[]}for(var s in a){if(w.call(a,s)){var r=a[s]
 if(r instanceof Array)r=r[1]
-var q=r[""],p,o=s,n=q
+var q=r["^"],p,o=s,n=q
 if(typeof q=="object"&&q instanceof Array){q=n=q[0]}if(typeof q=="string"){var m=q.split("/")
 if(m.length==2){o=m[0]
 n=m[1]}}var l=n.split(";")
@@ -24126,20 +24489,20 @@
 Gh.prototype.gcC=function(receiver){return receiver.hash}
 Gh.prototype.scC=function(receiver,v){return receiver.hash=v}
 Gh.prototype.gmH=function(receiver){return receiver.href}
-function rK(){}rK.builtin$cls="rK"
-if(!"name" in rK)rK.name="rK"
-$desc=$collectedClasses.rK
+function A0(){}A0.builtin$cls="A0"
+if(!"name" in A0)A0.name="A0"
+$desc=$collectedClasses.A0
 if($desc instanceof Array)$desc=$desc[1]
-rK.prototype=$desc
-function fY(){}fY.builtin$cls="fY"
-if(!"name" in fY)fY.name="fY"
-$desc=$collectedClasses.fY
+A0.prototype=$desc
+function na(){}na.builtin$cls="na"
+if(!"name" in na)na.name="na"
+$desc=$collectedClasses.na
 if($desc instanceof Array)$desc=$desc[1]
-fY.prototype=$desc
-fY.prototype.gN=function(receiver){return receiver.target}
-fY.prototype.gcC=function(receiver){return receiver.hash}
-fY.prototype.scC=function(receiver,v){return receiver.hash=v}
-fY.prototype.gmH=function(receiver){return receiver.href}
+na.prototype=$desc
+na.prototype.gN=function(receiver){return receiver.target}
+na.prototype.gcC=function(receiver){return receiver.hash}
+na.prototype.scC=function(receiver,v){return receiver.hash=v}
+na.prototype.gmH=function(receiver){return receiver.href}
 function Mr(){}Mr.builtin$cls="Mr"
 if(!"name" in Mr)Mr.name="Mr"
 $desc=$collectedClasses.Mr
@@ -24168,11 +24531,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 W2.prototype=$desc
 W2.prototype.gO3=function(receiver){return receiver.url}
-function zJ(){}zJ.builtin$cls="zJ"
-if(!"name" in zJ)zJ.name="zJ"
-$desc=$collectedClasses.zJ
+function it(){}it.builtin$cls="it"
+if(!"name" in it)it.name="it"
+$desc=$collectedClasses.it
 if($desc instanceof Array)$desc=$desc[1]
-zJ.prototype=$desc
+it.prototype=$desc
 function Az(){}Az.builtin$cls="Az"
 if(!"name" in Az)Az.name="Az"
 $desc=$collectedClasses.Az
@@ -24196,23 +24559,23 @@
 QW.prototype.st5=function(receiver,v){return receiver.type=v}
 QW.prototype.gP=function(receiver){return receiver.value}
 QW.prototype.sP=function(receiver,v){return receiver.value=v}
-function n6(){}n6.builtin$cls="n6"
-if(!"name" in n6)n6.name="n6"
-$desc=$collectedClasses.n6
+function jr(){}jr.builtin$cls="jr"
+if(!"name" in jr)jr.name="jr"
+$desc=$collectedClasses.jr
 if($desc instanceof Array)$desc=$desc[1]
-n6.prototype=$desc
-function Nu(){}Nu.builtin$cls="Nu"
-if(!"name" in Nu)Nu.name="Nu"
-$desc=$collectedClasses.Nu
+jr.prototype=$desc
+function Ny(){}Ny.builtin$cls="Ny"
+if(!"name" in Ny)Ny.name="Ny"
+$desc=$collectedClasses.Ny
 if($desc instanceof Array)$desc=$desc[1]
-Nu.prototype=$desc
-function OM(){}OM.builtin$cls="OM"
-if(!"name" in OM)OM.name="OM"
-$desc=$collectedClasses.OM
+Ny.prototype=$desc
+function nx(){}nx.builtin$cls="nx"
+if(!"name" in nx)nx.name="nx"
+$desc=$collectedClasses.nx
 if($desc instanceof Array)$desc=$desc[1]
-OM.prototype=$desc
-OM.prototype.gRn=function(receiver){return receiver.data}
-OM.prototype.gB=function(receiver){return receiver.length}
+nx.prototype=$desc
+nx.prototype.gRn=function(receiver){return receiver.data}
+nx.prototype.gB=function(receiver){return receiver.length}
 function QQ(){}QQ.builtin$cls="QQ"
 if(!"name" in QQ)QQ.name="QQ"
 $desc=$collectedClasses.QQ
@@ -24224,44 +24587,38 @@
 $desc=$collectedClasses.BR
 if($desc instanceof Array)$desc=$desc[1]
 BR.prototype=$desc
-function wT(){}wT.builtin$cls="wT"
-if(!"name" in wT)wT.name="wT"
-$desc=$collectedClasses.wT
+function di(){}di.builtin$cls="di"
+if(!"name" in di)di.name="di"
+$desc=$collectedClasses.di
 if($desc instanceof Array)$desc=$desc[1]
-wT.prototype=$desc
-wT.prototype.gRn=function(receiver){return receiver.data}
+di.prototype=$desc
+di.prototype.gRn=function(receiver){return receiver.data}
 function d7(){}d7.builtin$cls="d7"
 if(!"name" in d7)d7.name="d7"
 $desc=$collectedClasses.d7
 if($desc instanceof Array)$desc=$desc[1]
 d7.prototype=$desc
-function na(){}na.builtin$cls="na"
-if(!"name" in na)na.name="na"
-$desc=$collectedClasses.na
+function yJ(){}yJ.builtin$cls="yJ"
+if(!"name" in yJ)yJ.name="yJ"
+$desc=$collectedClasses.yJ
 if($desc instanceof Array)$desc=$desc[1]
-na.prototype=$desc
-function oJ(){}oJ.builtin$cls="oJ"
-if(!"name" in oJ)oJ.name="oJ"
-$desc=$collectedClasses.oJ
+yJ.prototype=$desc
+function He(){}He.builtin$cls="He"
+if(!"name" in He)He.name="He"
+$desc=$collectedClasses.He
 if($desc instanceof Array)$desc=$desc[1]
-oJ.prototype=$desc
-oJ.prototype.gB=function(receiver){return receiver.length}
-function DG(){}DG.builtin$cls="DG"
-if(!"name" in DG)DG.name="DG"
-$desc=$collectedClasses.DG
-if($desc instanceof Array)$desc=$desc[1]
-DG.prototype=$desc
+He.prototype=$desc
 function vz(){}vz.builtin$cls="vz"
 if(!"name" in vz)vz.name="vz"
 $desc=$collectedClasses.vz
 if($desc instanceof Array)$desc=$desc[1]
 vz.prototype=$desc
-function bY(){}bY.builtin$cls="bY"
-if(!"name" in bY)bY.name="bY"
-$desc=$collectedClasses.bY
+function vHT(){}vHT.builtin$cls="vHT"
+if(!"name" in vHT)vHT.name="vHT"
+$desc=$collectedClasses.vHT
 if($desc instanceof Array)$desc=$desc[1]
-bY.prototype=$desc
-bY.prototype.gbG=function(receiver){return receiver.options}
+vHT.prototype=$desc
+vHT.prototype.gbG=function(receiver){return receiver.options}
 function n0(){}n0.builtin$cls="n0"
 if(!"name" in n0)n0.name="n0"
 $desc=$collectedClasses.n0
@@ -24272,11 +24629,11 @@
 $desc=$collectedClasses.Em
 if($desc instanceof Array)$desc=$desc[1]
 Em.prototype=$desc
-function rD(){}rD.builtin$cls="rD"
-if(!"name" in rD)rD.name="rD"
-$desc=$collectedClasses.rD
+function pt(){}pt.builtin$cls="pt"
+if(!"name" in pt)pt.name="pt"
+$desc=$collectedClasses.pt
 if($desc instanceof Array)$desc=$desc[1]
-rD.prototype=$desc
+pt.prototype=$desc
 function rV(){}rV.builtin$cls="rV"
 if(!"name" in rV)rV.name="rV"
 $desc=$collectedClasses.rV
@@ -24292,34 +24649,29 @@
 $desc=$collectedClasses.QF
 if($desc instanceof Array)$desc=$desc[1]
 QF.prototype=$desc
-function hN(){}hN.builtin$cls="hN"
-if(!"name" in hN)hN.name="hN"
-$desc=$collectedClasses.hN
+function Aj(){}Aj.builtin$cls="Aj"
+if(!"name" in Aj)Aj.name="Aj"
+$desc=$collectedClasses.Aj
 if($desc instanceof Array)$desc=$desc[1]
-hN.prototype=$desc
-function SL(){}SL.builtin$cls="SL"
-if(!"name" in SL)SL.name="SL"
-$desc=$collectedClasses.SL
+Aj.prototype=$desc
+function cm(){}cm.builtin$cls="cm"
+if(!"name" in cm)cm.name="cm"
+$desc=$collectedClasses.cm
 if($desc instanceof Array)$desc=$desc[1]
-SL.prototype=$desc
-function rv(){}rv.builtin$cls="rv"
-if(!"name" in rv)rv.name="rv"
-$desc=$collectedClasses.rv
-if($desc instanceof Array)$desc=$desc[1]
-rv.prototype=$desc
-rv.prototype.gG1=function(receiver){return receiver.message}
-rv.prototype.goc=function(receiver){return receiver.name}
+cm.prototype=$desc
+cm.prototype.gG1=function(receiver){return receiver.message}
+cm.prototype.goc=function(receiver){return receiver.name}
 function Nh(){}Nh.builtin$cls="Nh"
 if(!"name" in Nh)Nh.name="Nh"
 $desc=$collectedClasses.Nh
 if($desc instanceof Array)$desc=$desc[1]
 Nh.prototype=$desc
 Nh.prototype.gG1=function(receiver){return receiver.message}
-function ac(){}ac.builtin$cls="ac"
-if(!"name" in ac)ac.name="ac"
-$desc=$collectedClasses.ac
+function wj(){}wj.builtin$cls="wj"
+if(!"name" in wj)wj.name="wj"
+$desc=$collectedClasses.wj
 if($desc instanceof Array)$desc=$desc[1]
-ac.prototype=$desc
+wj.prototype=$desc
 function cv(){}cv.builtin$cls="cv"
 if(!"name" in cv)cv.name="cv"
 $desc=$collectedClasses.cv
@@ -24374,27 +24726,27 @@
 if($desc instanceof Array)$desc=$desc[1]
 hH.prototype=$desc
 hH.prototype.goc=function(receiver){return receiver.name}
-function QU(){}QU.builtin$cls="QU"
-if(!"name" in QU)QU.name="QU"
-$desc=$collectedClasses.QU
+function Aa(){}Aa.builtin$cls="Aa"
+if(!"name" in Aa)Aa.name="Aa"
+$desc=$collectedClasses.Aa
 if($desc instanceof Array)$desc=$desc[1]
-QU.prototype=$desc
-QU.prototype.gtT=function(receiver){return receiver.code}
+Aa.prototype=$desc
+Aa.prototype.gtT=function(receiver){return receiver.code}
 function u5(){}u5.builtin$cls="u5"
 if(!"name" in u5)u5.name="u5"
 $desc=$collectedClasses.u5
 if($desc instanceof Array)$desc=$desc[1]
 u5.prototype=$desc
-function Yu(){}Yu.builtin$cls="Yu"
-if(!"name" in Yu)Yu.name="Yu"
-$desc=$collectedClasses.Yu
+function h4(){}h4.builtin$cls="h4"
+if(!"name" in h4)h4.name="h4"
+$desc=$collectedClasses.h4
 if($desc instanceof Array)$desc=$desc[1]
-Yu.prototype=$desc
-Yu.prototype.gB=function(receiver){return receiver.length}
-Yu.prototype.gbP=function(receiver){return receiver.method}
-Yu.prototype.goc=function(receiver){return receiver.name}
-Yu.prototype.soc=function(receiver,v){return receiver.name=v}
-Yu.prototype.gN=function(receiver){return receiver.target}
+h4.prototype=$desc
+h4.prototype.gB=function(receiver){return receiver.length}
+h4.prototype.gbP=function(receiver){return receiver.method}
+h4.prototype.goc=function(receiver){return receiver.name}
+h4.prototype.soc=function(receiver,v){return receiver.name=v}
+h4.prototype.gN=function(receiver){return receiver.target}
 function W4(){}W4.builtin$cls="W4"
 if(!"name" in W4)W4.name="W4"
 $desc=$collectedClasses.W4
@@ -24405,21 +24757,21 @@
 $desc=$collectedClasses.jP
 if($desc instanceof Array)$desc=$desc[1]
 jP.prototype=$desc
-function Cz(){}Cz.builtin$cls="Cz"
-if(!"name" in Cz)Cz.name="Cz"
-$desc=$collectedClasses.Cz
+function Hd(){}Hd.builtin$cls="Hd"
+if(!"name" in Hd)Hd.name="Hd"
+$desc=$collectedClasses.Hd
 if($desc instanceof Array)$desc=$desc[1]
-Cz.prototype=$desc
+Hd.prototype=$desc
 function tA(){}tA.builtin$cls="tA"
 if(!"name" in tA)tA.name="tA"
 $desc=$collectedClasses.tA
 if($desc instanceof Array)$desc=$desc[1]
 tA.prototype=$desc
-function Cv(){}Cv.builtin$cls="Cv"
-if(!"name" in Cv)Cv.name="Cv"
-$desc=$collectedClasses.Cv
+function wa(){}wa.builtin$cls="wa"
+if(!"name" in wa)wa.name="wa"
+$desc=$collectedClasses.wa
 if($desc instanceof Array)$desc=$desc[1]
-Cv.prototype=$desc
+wa.prototype=$desc
 function Uq(){}Uq.builtin$cls="Uq"
 if(!"name" in Uq)Uq.name="Uq"
 $desc=$collectedClasses.Uq
@@ -24430,11 +24782,11 @@
 $desc=$collectedClasses.QH
 if($desc instanceof Array)$desc=$desc[1]
 QH.prototype=$desc
-function So(){}So.builtin$cls="So"
-if(!"name" in So)So.name="So"
-$desc=$collectedClasses.So
+function Rt(){}Rt.builtin$cls="Rt"
+if(!"name" in Rt)Rt.name="Rt"
+$desc=$collectedClasses.Rt
 if($desc instanceof Array)$desc=$desc[1]
-So.prototype=$desc
+Rt.prototype=$desc
 function X2(){}X2.builtin$cls="X2"
 if(!"name" in X2)X2.name="X2"
 $desc=$collectedClasses.X2
@@ -24448,11 +24800,11 @@
 zU.prototype.giC=function(receiver){return receiver.responseText}
 zU.prototype.gys=function(receiver){return receiver.status}
 zU.prototype.gpo=function(receiver){return receiver.statusText}
-function wa(){}wa.builtin$cls="wa"
-if(!"name" in wa)wa.name="wa"
-$desc=$collectedClasses.wa
+function pk(){}pk.builtin$cls="pk"
+if(!"name" in pk)pk.name="pk"
+$desc=$collectedClasses.pk
 if($desc instanceof Array)$desc=$desc[1]
-wa.prototype=$desc
+pk.prototype=$desc
 function tX(){}tX.builtin$cls="tX"
 if(!"name" in tX)tX.name="tX"
 $desc=$collectedClasses.tX
@@ -24494,15 +24846,15 @@
 $desc=$collectedClasses.Gt
 if($desc instanceof Array)$desc=$desc[1]
 Gt.prototype=$desc
-function ttH(){}ttH.builtin$cls="ttH"
-if(!"name" in ttH)ttH.name="ttH"
-$desc=$collectedClasses.ttH
+function In(){}In.builtin$cls="In"
+if(!"name" in In)In.name="In"
+$desc=$collectedClasses.In
 if($desc instanceof Array)$desc=$desc[1]
-ttH.prototype=$desc
-ttH.prototype.gMB=function(receiver){return receiver.form}
-ttH.prototype.goc=function(receiver){return receiver.name}
-ttH.prototype.soc=function(receiver,v){return receiver.name=v}
-ttH.prototype.gt5=function(receiver){return receiver.type}
+In.prototype=$desc
+In.prototype.gMB=function(receiver){return receiver.form}
+In.prototype.goc=function(receiver){return receiver.name}
+In.prototype.soc=function(receiver,v){return receiver.name=v}
+In.prototype.gt5=function(receiver){return receiver.type}
 function wP(){}wP.builtin$cls="wP"
 if(!"name" in wP)wP.name="wP"
 $desc=$collectedClasses.wP
@@ -24538,13 +24890,13 @@
 cS.prototype.gcC=function(receiver){return receiver.hash}
 cS.prototype.scC=function(receiver,v){return receiver.hash=v}
 cS.prototype.gmH=function(receiver){return receiver.href}
-function M6(){}M6.builtin$cls="M6"
-if(!"name" in M6)M6.name="M6"
-$desc=$collectedClasses.M6
+function YI(){}YI.builtin$cls="YI"
+if(!"name" in YI)YI.name="YI"
+$desc=$collectedClasses.YI
 if($desc instanceof Array)$desc=$desc[1]
-M6.prototype=$desc
-M6.prototype.goc=function(receiver){return receiver.name}
-M6.prototype.soc=function(receiver,v){return receiver.name=v}
+YI.prototype=$desc
+YI.prototype.goc=function(receiver){return receiver.name}
+YI.prototype.soc=function(receiver,v){return receiver.name=v}
 function El(){}El.builtin$cls="El"
 if(!"name" in El)El.name="El"
 $desc=$collectedClasses.El
@@ -24592,11 +24944,11 @@
 $desc=$collectedClasses.HO
 if($desc instanceof Array)$desc=$desc[1]
 HO.prototype=$desc
-function rC(){}rC.builtin$cls="rC"
-if(!"name" in rC)rC.name="rC"
-$desc=$collectedClasses.rC
+function Kk(){}Kk.builtin$cls="Kk"
+if(!"name" in Kk)Kk.name="Kk"
+$desc=$collectedClasses.Kk
 if($desc instanceof Array)$desc=$desc[1]
-rC.prototype=$desc
+Kk.prototype=$desc
 function ZY(){}ZY.builtin$cls="ZY"
 if(!"name" in ZY)ZY.name="ZY"
 $desc=$collectedClasses.ZY
@@ -24607,14 +24959,14 @@
 $desc=$collectedClasses.DD
 if($desc instanceof Array)$desc=$desc[1]
 DD.prototype=$desc
-function la(){}la.builtin$cls="la"
-if(!"name" in la)la.name="la"
-$desc=$collectedClasses.la
+function EeC(){}EeC.builtin$cls="EeC"
+if(!"name" in EeC)EeC.name="EeC"
+$desc=$collectedClasses.EeC
 if($desc instanceof Array)$desc=$desc[1]
-la.prototype=$desc
-la.prototype.gjb=function(receiver){return receiver.content}
-la.prototype.goc=function(receiver){return receiver.name}
-la.prototype.soc=function(receiver,v){return receiver.name=v}
+EeC.prototype=$desc
+EeC.prototype.gjb=function(receiver){return receiver.content}
+EeC.prototype.goc=function(receiver){return receiver.name}
+EeC.prototype.soc=function(receiver,v){return receiver.name=v}
 function Qb(){}Qb.builtin$cls="Qb"
 if(!"name" in Qb)Qb.name="Qb"
 $desc=$collectedClasses.Qb
@@ -24643,24 +24995,24 @@
 $desc=$collectedClasses.bn
 if($desc instanceof Array)$desc=$desc[1]
 bn.prototype=$desc
-function tH(){}tH.builtin$cls="tH"
-if(!"name" in tH)tH.name="tH"
-$desc=$collectedClasses.tH
+function Imr(){}Imr.builtin$cls="Imr"
+if(!"name" in Imr)Imr.name="Imr"
+$desc=$collectedClasses.Imr
 if($desc instanceof Array)$desc=$desc[1]
-tH.prototype=$desc
-tH.prototype.gjO=function(receiver){return receiver.id}
-tH.prototype.goc=function(receiver){return receiver.name}
-tH.prototype.gt5=function(receiver){return receiver.type}
-function oB(){}oB.builtin$cls="oB"
-if(!"name" in oB)oB.name="oB"
-$desc=$collectedClasses.oB
+Imr.prototype=$desc
+Imr.prototype.gjO=function(receiver){return receiver.id}
+Imr.prototype.goc=function(receiver){return receiver.name}
+Imr.prototype.gt5=function(receiver){return receiver.type}
+function Ve(){}Ve.builtin$cls="Ve"
+if(!"name" in Ve)Ve.name="Ve"
+$desc=$collectedClasses.Ve
 if($desc instanceof Array)$desc=$desc[1]
-oB.prototype=$desc
-function Aj(){}Aj.builtin$cls="Aj"
-if(!"name" in Aj)Aj.name="Aj"
-$desc=$collectedClasses.Aj
+Ve.prototype=$desc
+function Oq(){}Oq.builtin$cls="Oq"
+if(!"name" in Oq)Oq.name="Oq"
+$desc=$collectedClasses.Oq
 if($desc instanceof Array)$desc=$desc[1]
-Aj.prototype=$desc
+Oq.prototype=$desc
 function H9(){}H9.builtin$cls="H9"
 if(!"name" in H9)H9.name="H9"
 $desc=$collectedClasses.H9
@@ -24686,18 +25038,18 @@
 ih.prototype=$desc
 ih.prototype.gG1=function(receiver){return receiver.message}
 ih.prototype.goc=function(receiver){return receiver.name}
-function uH(){}uH.builtin$cls="uH"
-if(!"name" in uH)uH.name="uH"
-$desc=$collectedClasses.uH
+function KV(){}KV.builtin$cls="KV"
+if(!"name" in KV)KV.name="KV"
+$desc=$collectedClasses.KV
 if($desc instanceof Array)$desc=$desc[1]
-uH.prototype=$desc
-uH.prototype.gq6=function(receiver){return receiver.firstChild}
-uH.prototype.guD=function(receiver){return receiver.nextSibling}
-uH.prototype.gM0=function(receiver){return receiver.ownerDocument}
-uH.prototype.geT=function(receiver){return receiver.parentElement}
-uH.prototype.gKV=function(receiver){return receiver.parentNode}
-uH.prototype.ga4=function(receiver){return receiver.textContent}
-uH.prototype.sa4=function(receiver,v){return receiver.textContent=v}
+KV.prototype=$desc
+KV.prototype.gq6=function(receiver){return receiver.firstChild}
+KV.prototype.guD=function(receiver){return receiver.nextSibling}
+KV.prototype.gM0=function(receiver){return receiver.ownerDocument}
+KV.prototype.geT=function(receiver){return receiver.parentElement}
+KV.prototype.gKV=function(receiver){return receiver.parentNode}
+KV.prototype.ga4=function(receiver){return receiver.textContent}
+KV.prototype.sa4=function(receiver,v){return receiver.textContent=v}
 function yk(){}yk.builtin$cls="yk"
 if(!"name" in yk)yk.name="yk"
 $desc=$collectedClasses.yk
@@ -24756,11 +25108,11 @@
 $desc=$collectedClasses.FH
 if($desc instanceof Array)$desc=$desc[1]
 FH.prototype=$desc
-function SN(){}SN.builtin$cls="SN"
-if(!"name" in SN)SN.name="SN"
-$desc=$collectedClasses.SN
+function iL(){}iL.builtin$cls="iL"
+if(!"name" in iL)iL.name="iL"
+$desc=$collectedClasses.iL
 if($desc instanceof Array)$desc=$desc[1]
-SN.prototype=$desc
+iL.prototype=$desc
 function HD(){}HD.builtin$cls="HD"
 if(!"name" in HD)HD.name="HD"
 $desc=$collectedClasses.HD
@@ -24859,11 +25211,11 @@
 lp.prototype.gt5=function(receiver){return receiver.type}
 lp.prototype.gP=function(receiver){return receiver.value}
 lp.prototype.sP=function(receiver,v){return receiver.value=v}
-function kd(){}kd.builtin$cls="kd"
-if(!"name" in kd)kd.name="kd"
-$desc=$collectedClasses.kd
+function pD(){}pD.builtin$cls="pD"
+if(!"name" in pD)pD.name="pD"
+$desc=$collectedClasses.pD
 if($desc instanceof Array)$desc=$desc[1]
-kd.prototype=$desc
+pD.prototype=$desc
 function I0(){}I0.builtin$cls="I0"
 if(!"name" in I0)I0.name="I0"
 $desc=$collectedClasses.I0
@@ -24888,13 +25240,13 @@
 $desc=$collectedClasses.Ta
 if($desc instanceof Array)$desc=$desc[1]
 Ta.prototype=$desc
-function Hd(){}Hd.builtin$cls="Hd"
-if(!"name" in Hd)Hd.name="Hd"
-$desc=$collectedClasses.Hd
+function zD9(){}zD9.builtin$cls="zD9"
+if(!"name" in zD9)zD9.name="zD9"
+$desc=$collectedClasses.zD9
 if($desc instanceof Array)$desc=$desc[1]
-Hd.prototype=$desc
-Hd.prototype.gkc=function(receiver){return receiver.error}
-Hd.prototype.gG1=function(receiver){return receiver.message}
+zD9.prototype=$desc
+zD9.prototype.gkc=function(receiver){return receiver.error}
+zD9.prototype.gG1=function(receiver){return receiver.message}
 function Ul(){}Ul.builtin$cls="Ul"
 if(!"name" in Ul)Ul.name="Ul"
 $desc=$collectedClasses.Ul
@@ -24906,15 +25258,15 @@
 if($desc instanceof Array)$desc=$desc[1]
 G5.prototype=$desc
 G5.prototype.goc=function(receiver){return receiver.name}
-function wb(){}wb.builtin$cls="wb"
-if(!"name" in wb)wb.name="wb"
-$desc=$collectedClasses.wb
+function bk(){}bk.builtin$cls="bk"
+if(!"name" in bk)bk.name="bk"
+$desc=$collectedClasses.bk
 if($desc instanceof Array)$desc=$desc[1]
-wb.prototype=$desc
-wb.prototype.gG3=function(receiver){return receiver.key}
-wb.prototype.gzZ=function(receiver){return receiver.newValue}
-wb.prototype.gjL=function(receiver){return receiver.oldValue}
-wb.prototype.gO3=function(receiver){return receiver.url}
+bk.prototype=$desc
+bk.prototype.gG3=function(receiver){return receiver.key}
+bk.prototype.gzZ=function(receiver){return receiver.newValue}
+bk.prototype.gjL=function(receiver){return receiver.oldValue}
+bk.prototype.gO3=function(receiver){return receiver.url}
 function fq(){}fq.builtin$cls="fq"
 if(!"name" in fq)fq.name="fq"
 $desc=$collectedClasses.fq
@@ -24922,11 +25274,11 @@
 fq.prototype=$desc
 fq.prototype.gt5=function(receiver){return receiver.type}
 fq.prototype.st5=function(receiver,v){return receiver.type=v}
-function h4(){}h4.builtin$cls="h4"
-if(!"name" in h4)h4.name="h4"
-$desc=$collectedClasses.h4
+function Er(){}Er.builtin$cls="Er"
+if(!"name" in Er)Er.name="Er"
+$desc=$collectedClasses.Er
 if($desc instanceof Array)$desc=$desc[1]
-h4.prototype=$desc
+Er.prototype=$desc
 function qk(){}qk.builtin$cls="qk"
 if(!"name" in qk)qk.name="qk"
 $desc=$collectedClasses.qk
@@ -24971,6 +25323,8 @@
 AE.prototype.gMB=function(receiver){return receiver.form}
 AE.prototype.goc=function(receiver){return receiver.name}
 AE.prototype.soc=function(receiver,v){return receiver.name=v}
+AE.prototype.gWT=function(receiver){return receiver.rows}
+AE.prototype.sWT=function(receiver,v){return receiver.rows=v}
 AE.prototype.gt5=function(receiver){return receiver.type}
 AE.prototype.gP=function(receiver){return receiver.value}
 AE.prototype.sP=function(receiver,v){return receiver.value=v}
@@ -24998,11 +25352,11 @@
 RH.prototype.gfY=function(receiver){return receiver.kind}
 RH.prototype.sfY=function(receiver,v){return receiver.kind=v}
 RH.prototype.gLA=function(receiver){return receiver.src}
-function pU(){}pU.builtin$cls="pU"
-if(!"name" in pU)pU.name="pU"
-$desc=$collectedClasses.pU
+function ho(){}ho.builtin$cls="ho"
+if(!"name" in ho)ho.name="ho"
+$desc=$collectedClasses.ho
 if($desc instanceof Array)$desc=$desc[1]
-pU.prototype=$desc
+ho.prototype=$desc
 function OJ(){}OJ.builtin$cls="OJ"
 if(!"name" in OJ)OJ.name="OJ"
 $desc=$collectedClasses.OJ
@@ -25018,11 +25372,11 @@
 $desc=$collectedClasses.dp
 if($desc instanceof Array)$desc=$desc[1]
 dp.prototype=$desc
-function r4(){}r4.builtin$cls="r4"
-if(!"name" in r4)r4.name="r4"
-$desc=$collectedClasses.r4
+function vw(){}vw.builtin$cls="vw"
+if(!"name" in vw)vw.name="vw"
+$desc=$collectedClasses.vw
 if($desc instanceof Array)$desc=$desc[1]
-r4.prototype=$desc
+vw.prototype=$desc
 function aG(){}aG.builtin$cls="aG"
 if(!"name" in aG)aG.name="aG"
 $desc=$collectedClasses.aG
@@ -25049,21 +25403,21 @@
 Bn.prototype.goc=function(receiver){return receiver.name}
 Bn.prototype.gP=function(receiver){return receiver.value}
 Bn.prototype.sP=function(receiver,v){return receiver.value=v}
+function hq(){}hq.builtin$cls="hq"
+if(!"name" in hq)hq.name="hq"
+$desc=$collectedClasses.hq
+if($desc instanceof Array)$desc=$desc[1]
+hq.prototype=$desc
 function UL(){}UL.builtin$cls="UL"
 if(!"name" in UL)UL.name="UL"
 $desc=$collectedClasses.UL
 if($desc instanceof Array)$desc=$desc[1]
 UL.prototype=$desc
-function rq(){}rq.builtin$cls="rq"
-if(!"name" in rq)rq.name="rq"
-$desc=$collectedClasses.rq
+function tZ(){}tZ.builtin$cls="tZ"
+if(!"name" in tZ)tZ.name="tZ"
+$desc=$collectedClasses.tZ
 if($desc instanceof Array)$desc=$desc[1]
-rq.prototype=$desc
-function I1(){}I1.builtin$cls="I1"
-if(!"name" in I1)I1.name="I1"
-$desc=$collectedClasses.I1
-if($desc instanceof Array)$desc=$desc[1]
-I1.prototype=$desc
+tZ.prototype=$desc
 function kc(){}kc.builtin$cls="kc"
 if(!"name" in kc)kc.name="kc"
 $desc=$collectedClasses.kc
@@ -25074,11 +25428,11 @@
 $desc=$collectedClasses.AK
 if($desc instanceof Array)$desc=$desc[1]
 AK.prototype=$desc
-function dM(){}dM.builtin$cls="dM"
-if(!"name" in dM)dM.name="dM"
-$desc=$collectedClasses.dM
+function ty(){}ty.builtin$cls="ty"
+if(!"name" in ty)ty.name="ty"
+$desc=$collectedClasses.ty
 if($desc instanceof Array)$desc=$desc[1]
-dM.prototype=$desc
+ty.prototype=$desc
 function Nf(){}Nf.builtin$cls="Nf"
 if(!"name" in Nf)Nf.name="Nf"
 $desc=$collectedClasses.Nf
@@ -25114,11 +25468,11 @@
 $desc=$collectedClasses.hF
 if($desc instanceof Array)$desc=$desc[1]
 hF.prototype=$desc
-function hr(){}hr.builtin$cls="hr"
-if(!"name" in hr)hr.name="hr"
-$desc=$collectedClasses.hr
+function OF(){}OF.builtin$cls="OF"
+if(!"name" in OF)OF.name="OF"
+$desc=$collectedClasses.OF
 if($desc instanceof Array)$desc=$desc[1]
-hr.prototype=$desc
+OF.prototype=$desc
 function Dh(){}Dh.builtin$cls="Dh"
 if(!"name" in Dh)Dh.name="Dh"
 $desc=$collectedClasses.Dh
@@ -25142,11 +25496,11 @@
 $desc=$collectedClasses.NE
 if($desc instanceof Array)$desc=$desc[1]
 NE.prototype=$desc
-function Fl(){}Fl.builtin$cls="Fl"
-if(!"name" in Fl)Fl.name="Fl"
-$desc=$collectedClasses.Fl
+function lC(){}lC.builtin$cls="lC"
+if(!"name" in lC)lC.name="lC"
+$desc=$collectedClasses.lC
 if($desc instanceof Array)$desc=$desc[1]
-Fl.prototype=$desc
+lC.prototype=$desc
 function y5(){}y5.builtin$cls="y5"
 if(!"name" in y5)y5.name="y5"
 $desc=$collectedClasses.y5
@@ -25167,11 +25521,11 @@
 $desc=$collectedClasses.ui
 if($desc instanceof Array)$desc=$desc[1]
 ui.prototype=$desc
-function vO(){}vO.builtin$cls="vO"
-if(!"name" in vO)vO.name="vO"
-$desc=$collectedClasses.vO
+function mk(){}mk.builtin$cls="mk"
+if(!"name" in mk)mk.name="mk"
+$desc=$collectedClasses.mk
 if($desc instanceof Array)$desc=$desc[1]
-vO.prototype=$desc
+mk.prototype=$desc
 function DQ(){}DQ.builtin$cls="DQ"
 if(!"name" in DQ)DQ.name="DQ"
 $desc=$collectedClasses.DQ
@@ -25220,21 +25574,21 @@
 $desc=$collectedClasses.W1
 if($desc instanceof Array)$desc=$desc[1]
 W1.prototype=$desc
-function HC(){}HC.builtin$cls="HC"
-if(!"name" in HC)HC.name="HC"
-$desc=$collectedClasses.HC
+function mCz(){}mCz.builtin$cls="mCz"
+if(!"name" in mCz)mCz.name="mCz"
+$desc=$collectedClasses.mCz
 if($desc instanceof Array)$desc=$desc[1]
-HC.prototype=$desc
+mCz.prototype=$desc
 function kK(){}kK.builtin$cls="kK"
 if(!"name" in kK)kK.name="kK"
 $desc=$collectedClasses.kK
 if($desc instanceof Array)$desc=$desc[1]
 kK.prototype=$desc
-function hq(){}hq.builtin$cls="hq"
-if(!"name" in hq)hq.name="hq"
-$desc=$collectedClasses.hq
+function n5(){}n5.builtin$cls="n5"
+if(!"name" in n5)n5.name="n5"
+$desc=$collectedClasses.n5
 if($desc instanceof Array)$desc=$desc[1]
-hq.prototype=$desc
+n5.prototype=$desc
 function bb(){}bb.builtin$cls="bb"
 if(!"name" in bb)bb.name="bb"
 $desc=$collectedClasses.bb
@@ -25271,11 +25625,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 me.prototype=$desc
 me.prototype.gmH=function(receiver){return receiver.href}
-function bO(){}bO.builtin$cls="bO"
-if(!"name" in bO)bO.name="bO"
-$desc=$collectedClasses.bO
+function oB(){}oB.builtin$cls="oB"
+if(!"name" in oB)oB.name="oB"
+$desc=$collectedClasses.oB
 if($desc instanceof Array)$desc=$desc[1]
-bO.prototype=$desc
+oB.prototype=$desc
 function nh(){}nh.builtin$cls="nh"
 if(!"name" in nh)nh.name="nh"
 $desc=$collectedClasses.nh
@@ -25297,11 +25651,11 @@
 $desc=$collectedClasses.ca
 if($desc instanceof Array)$desc=$desc[1]
 ca.prototype=$desc
-function zt(){}zt.builtin$cls="zt"
-if(!"name" in zt)zt.name="zt"
-$desc=$collectedClasses.zt
+function um(){}um.builtin$cls="um"
+if(!"name" in um)um.name="um"
+$desc=$collectedClasses.um
 if($desc instanceof Array)$desc=$desc[1]
-zt.prototype=$desc
+um.prototype=$desc
 function eW(){}eW.builtin$cls="eW"
 if(!"name" in eW)eW.name="eW"
 $desc=$collectedClasses.eW
@@ -25318,12 +25672,12 @@
 if($desc instanceof Array)$desc=$desc[1]
 Fu.prototype=$desc
 Fu.prototype.gt5=function(receiver){return receiver.type}
-function OE(){}OE.builtin$cls="OE"
-if(!"name" in OE)OE.name="OE"
-$desc=$collectedClasses.OE
+function QN(){}QN.builtin$cls="QN"
+if(!"name" in QN)QN.name="QN"
+$desc=$collectedClasses.QN
 if($desc instanceof Array)$desc=$desc[1]
-OE.prototype=$desc
-OE.prototype.gmH=function(receiver){return receiver.href}
+QN.prototype=$desc
+QN.prototype.gmH=function(receiver){return receiver.href}
 function N9(){}N9.builtin$cls="N9"
 if(!"name" in N9)N9.name="N9"
 $desc=$collectedClasses.N9
@@ -25334,6 +25688,11 @@
 $desc=$collectedClasses.BA
 if($desc instanceof Array)$desc=$desc[1]
 BA.prototype=$desc
+function d0(){}d0.builtin$cls="d0"
+if(!"name" in d0)d0.name="d0"
+$desc=$collectedClasses.d0
+if($desc instanceof Array)$desc=$desc[1]
+d0.prototype=$desc
 function zp(){}zp.builtin$cls="zp"
 if(!"name" in zp)zp.name="zp"
 $desc=$collectedClasses.zp
@@ -25350,11 +25709,11 @@
 $desc=$collectedClasses.PIw
 if($desc instanceof Array)$desc=$desc[1]
 PIw.prototype=$desc
-function PQ(){}PQ.builtin$cls="PQ"
-if(!"name" in PQ)PQ.name="PQ"
-$desc=$collectedClasses.PQ
+function vd(){}vd.builtin$cls="vd"
+if(!"name" in vd)vd.name="vd"
+$desc=$collectedClasses.vd
 if($desc instanceof Array)$desc=$desc[1]
-PQ.prototype=$desc
+vd.prototype=$desc
 function Jq(){}Jq.builtin$cls="Jq"
 if(!"name" in Jq)Jq.name="Jq"
 $desc=$collectedClasses.Jq
@@ -25391,11 +25750,11 @@
 $desc=$collectedClasses.GH
 if($desc instanceof Array)$desc=$desc[1]
 GH.prototype=$desc
-function Lx(){}Lx.builtin$cls="Lx"
-if(!"name" in Lx)Lx.name="Lx"
-$desc=$collectedClasses.Lx
+function lo(){}lo.builtin$cls="lo"
+if(!"name" in lo)lo.name="lo"
+$desc=$collectedClasses.lo
 if($desc instanceof Array)$desc=$desc[1]
-Lx.prototype=$desc
+lo.prototype=$desc
 function NJ(){}NJ.builtin$cls="NJ"
 if(!"name" in NJ)NJ.name="NJ"
 $desc=$collectedClasses.NJ
@@ -25419,23 +25778,23 @@
 $desc=$collectedClasses.rQ
 if($desc instanceof Array)$desc=$desc[1]
 rQ.prototype=$desc
-function Lu(){}Lu.builtin$cls="Lu"
-if(!"name" in Lu)Lu.name="Lu"
-$desc=$collectedClasses.Lu
+function Lx(){}Lx.builtin$cls="Lx"
+if(!"name" in Lx)Lx.name="Lx"
+$desc=$collectedClasses.Lx
 if($desc instanceof Array)$desc=$desc[1]
-Lu.prototype=$desc
-Lu.prototype.gt5=function(receiver){return receiver.type}
-Lu.prototype.st5=function(receiver,v){return receiver.type=v}
+Lx.prototype=$desc
+Lx.prototype.gt5=function(receiver){return receiver.type}
+Lx.prototype.st5=function(receiver,v){return receiver.type=v}
 function LR(){}LR.builtin$cls="LR"
 if(!"name" in LR)LR.name="LR"
 $desc=$collectedClasses.LR
 if($desc instanceof Array)$desc=$desc[1]
 LR.prototype=$desc
-function GN(){}GN.builtin$cls="GN"
-if(!"name" in GN)GN.name="GN"
-$desc=$collectedClasses.GN
+function d5(){}d5.builtin$cls="d5"
+if(!"name" in d5)d5.name="d5"
+$desc=$collectedClasses.d5
 if($desc instanceof Array)$desc=$desc[1]
-GN.prototype=$desc
+d5.prototype=$desc
 function hy(){}hy.builtin$cls="hy"
 if(!"name" in hy)hy.name="hy"
 $desc=$collectedClasses.hy
@@ -25494,11 +25853,11 @@
 $desc=$collectedClasses.ZD
 if($desc instanceof Array)$desc=$desc[1]
 ZD.prototype=$desc
-function Rlr(){}Rlr.builtin$cls="Rlr"
-if(!"name" in Rlr)Rlr.name="Rlr"
-$desc=$collectedClasses.Rlr
+function rD(){}rD.builtin$cls="rD"
+if(!"name" in rD)rD.name="rD"
+$desc=$collectedClasses.rD
 if($desc instanceof Array)$desc=$desc[1]
-Rlr.prototype=$desc
+rD.prototype=$desc
 function wD(){}wD.builtin$cls="wD"
 if(!"name" in wD)wD.name="wD"
 $desc=$collectedClasses.wD
@@ -25520,26 +25879,26 @@
 $desc=$collectedClasses.Fi
 if($desc instanceof Array)$desc=$desc[1]
 Fi.prototype=$desc
-function Qr(){}Qr.builtin$cls="Qr"
-if(!"name" in Qr)Qr.name="Qr"
-$desc=$collectedClasses.Qr
+function Ja(){}Ja.builtin$cls="Ja"
+if(!"name" in Ja)Ja.name="Ja"
+$desc=$collectedClasses.Ja
 if($desc instanceof Array)$desc=$desc[1]
-Qr.prototype=$desc
-function zI(){}zI.builtin$cls="zI"
-if(!"name" in zI)zI.name="zI"
-$desc=$collectedClasses.zI
+Ja.prototype=$desc
+function mj(){}mj.builtin$cls="mj"
+if(!"name" in mj)mj.name="mj"
+$desc=$collectedClasses.mj
 if($desc instanceof Array)$desc=$desc[1]
-zI.prototype=$desc
+mj.prototype=$desc
 function cB(){}cB.builtin$cls="cB"
 if(!"name" in cB)cB.name="cB"
 $desc=$collectedClasses.cB
 if($desc instanceof Array)$desc=$desc[1]
 cB.prototype=$desc
-function uY(){}uY.builtin$cls="uY"
-if(!"name" in uY)uY.name="uY"
-$desc=$collectedClasses.uY
+function Mh(){}Mh.builtin$cls="Mh"
+if(!"name" in Mh)Mh.name="Mh"
+$desc=$collectedClasses.Mh
 if($desc instanceof Array)$desc=$desc[1]
-uY.prototype=$desc
+Mh.prototype=$desc
 function yR(){}yR.builtin$cls="yR"
 if(!"name" in yR)yR.name="yR"
 $desc=$collectedClasses.yR
@@ -25555,11 +25914,11 @@
 $desc=$collectedClasses.xJ
 if($desc instanceof Array)$desc=$desc[1]
 xJ.prototype=$desc
-function oI(){}oI.builtin$cls="oI"
-if(!"name" in oI)oI.name="oI"
-$desc=$collectedClasses.oI
+function Nn(){}Nn.builtin$cls="Nn"
+if(!"name" in Nn)Nn.name="Nn"
+$desc=$collectedClasses.Nn
 if($desc instanceof Array)$desc=$desc[1]
-oI.prototype=$desc
+Nn.prototype=$desc
 function Et(){}Et.builtin$cls="Et"
 if(!"name" in Et)Et.name="Et"
 $desc=$collectedClasses.Et
@@ -25585,11 +25944,11 @@
 $desc=$collectedClasses.xt
 if($desc instanceof Array)$desc=$desc[1]
 xt.prototype=$desc
-function tG(){}tG.builtin$cls="tG"
-if(!"name" in tG)tG.name="tG"
-$desc=$collectedClasses.tG
+function wx(){}wx.builtin$cls="wx"
+if(!"name" in wx)wx.name="wx"
+$desc=$collectedClasses.wx
 if($desc instanceof Array)$desc=$desc[1]
-tG.prototype=$desc
+wx.prototype=$desc
 function P0(){}P0.builtin$cls="P0"
 if(!"name" in P0)P0.name="P0"
 $desc=$collectedClasses.P0
@@ -25617,66 +25976,66 @@
 TM.prototype=$desc
 TM.prototype.gtT=function(receiver){return receiver.code}
 TM.prototype.gG1=function(receiver){return receiver.message}
-function I2(){}I2.builtin$cls="I2"
-if(!"name" in I2)I2.name="I2"
-$desc=$collectedClasses.I2
+function WZ(){}WZ.builtin$cls="WZ"
+if(!"name" in WZ)WZ.name="WZ"
+$desc=$collectedClasses.WZ
 if($desc instanceof Array)$desc=$desc[1]
-I2.prototype=$desc
-function HY(){}HY.builtin$cls="HY"
-if(!"name" in HY)HY.name="HY"
-$desc=$collectedClasses.HY
+WZ.prototype=$desc
+function rn(){}rn.builtin$cls="rn"
+if(!"name" in rn)rn.name="rn"
+$desc=$collectedClasses.rn
 if($desc instanceof Array)$desc=$desc[1]
-HY.prototype=$desc
-function Kq(){}Kq.builtin$cls="Kq"
-if(!"name" in Kq)Kq.name="Kq"
-$desc=$collectedClasses.Kq
+rn.prototype=$desc
+function df(){}df.builtin$cls="df"
+if(!"name" in df)df.name="df"
+$desc=$collectedClasses.df
 if($desc instanceof Array)$desc=$desc[1]
-Kq.prototype=$desc
-function Nn(){}Nn.builtin$cls="Nn"
-if(!"name" in Nn)Nn.name="Nn"
-$desc=$collectedClasses.Nn
+df.prototype=$desc
+function Hg(){}Hg.builtin$cls="Hg"
+if(!"name" in Hg)Hg.name="Hg"
+$desc=$collectedClasses.Hg
 if($desc instanceof Array)$desc=$desc[1]
-Nn.prototype=$desc
-function Un(){}Un.builtin$cls="Un"
-if(!"name" in Un)Un.name="Un"
-$desc=$collectedClasses.Un
+Hg.prototype=$desc
+function L3(){}L3.builtin$cls="L3"
+if(!"name" in L3)L3.name="L3"
+$desc=$collectedClasses.L3
 if($desc instanceof Array)$desc=$desc[1]
-Un.prototype=$desc
-function rF(){}rF.builtin$cls="rF"
-if(!"name" in rF)rF.name="rF"
-$desc=$collectedClasses.rF
+L3.prototype=$desc
+function xj(){}xj.builtin$cls="xj"
+if(!"name" in xj)xj.name="xj"
+$desc=$collectedClasses.xj
 if($desc instanceof Array)$desc=$desc[1]
-rF.prototype=$desc
-function Sb(){}Sb.builtin$cls="Sb"
-if(!"name" in Sb)Sb.name="Sb"
-$desc=$collectedClasses.Sb
+xj.prototype=$desc
+function dE(){}dE.builtin$cls="dE"
+if(!"name" in dE)dE.name="dE"
+$desc=$collectedClasses.dE
 if($desc instanceof Array)$desc=$desc[1]
-Sb.prototype=$desc
-function UZ(){}UZ.builtin$cls="UZ"
-if(!"name" in UZ)UZ.name="UZ"
-$desc=$collectedClasses.UZ
+dE.prototype=$desc
+function Eb(){}Eb.builtin$cls="Eb"
+if(!"name" in Eb)Eb.name="Eb"
+$desc=$collectedClasses.Eb
 if($desc instanceof Array)$desc=$desc[1]
-UZ.prototype=$desc
-function yc(){}yc.builtin$cls="yc"
-if(!"name" in yc)yc.name="yc"
-$desc=$collectedClasses.yc
+Eb.prototype=$desc
+function dT(){}dT.builtin$cls="dT"
+if(!"name" in dT)dT.name="dT"
+$desc=$collectedClasses.dT
 if($desc instanceof Array)$desc=$desc[1]
-yc.prototype=$desc
-function Aw(){}Aw.builtin$cls="Aw"
-if(!"name" in Aw)Aw.name="Aw"
-$desc=$collectedClasses.Aw
+dT.prototype=$desc
+function N2(){}N2.builtin$cls="N2"
+if(!"name" in N2)N2.name="N2"
+$desc=$collectedClasses.N2
 if($desc instanceof Array)$desc=$desc[1]
-Aw.prototype=$desc
-function jx(){}jx.builtin$cls="jx"
-if(!"name" in jx)jx.name="jx"
-$desc=$collectedClasses.jx
+N2.prototype=$desc
+function eE(){}eE.builtin$cls="eE"
+if(!"name" in eE)eE.name="eE"
+$desc=$collectedClasses.eE
 if($desc instanceof Array)$desc=$desc[1]
-jx.prototype=$desc
-function F0(){}F0.builtin$cls="F0"
-if(!"name" in F0)F0.name="F0"
-$desc=$collectedClasses.F0
+eE.prototype=$desc
+function V6(){}V6.builtin$cls="V6"
+if(!"name" in V6)V6.name="V6"
+$desc=$collectedClasses.V6
 if($desc instanceof Array)$desc=$desc[1]
-F0.prototype=$desc
+V6.prototype=$desc
 function Lt(tT){this.tT=tT}Lt.builtin$cls="Lt"
 if(!"name" in Lt)Lt.name="Lt"
 $desc=$collectedClasses.Lt
@@ -25693,11 +26052,11 @@
 $desc=$collectedClasses.kn
 if($desc instanceof Array)$desc=$desc[1]
 kn.prototype=$desc
-function PE(){}PE.builtin$cls="PE"
-if(!"name" in PE)PE.name="PE"
-$desc=$collectedClasses.PE
+function ht(){}ht.builtin$cls="Null"
+if(!"name" in ht)ht.name="ht"
+$desc=$collectedClasses.ht
 if($desc instanceof Array)$desc=$desc[1]
-PE.prototype=$desc
+ht.prototype=$desc
 function QI(){}QI.builtin$cls="QI"
 if(!"name" in QI)QI.name="QI"
 $desc=$collectedClasses.QI
@@ -25718,11 +26077,11 @@
 $desc=$collectedClasses.Q
 if($desc instanceof Array)$desc=$desc[1]
 Q.prototype=$desc
-function NK(){}NK.builtin$cls="NK"
-if(!"name" in NK)NK.name="NK"
-$desc=$collectedClasses.NK
+function nM(){}nM.builtin$cls="nM"
+if(!"name" in nM)nM.name="nM"
+$desc=$collectedClasses.nM
 if($desc instanceof Array)$desc=$desc[1]
-NK.prototype=$desc
+nM.prototype=$desc
 function ZC(){}ZC.builtin$cls="ZC"
 if(!"name" in ZC)ZC.name="ZC"
 $desc=$collectedClasses.ZC
@@ -25768,11 +26127,6 @@
 $desc=$collectedClasses.O
 if($desc instanceof Array)$desc=$desc[1]
 O.prototype=$desc
-function Qe(iN){this.iN=iN}Qe.builtin$cls="Qe"
-if(!"name" in Qe)Qe.name="Qe"
-$desc=$collectedClasses.Qe
-if($desc instanceof Array)$desc=$desc[1]
-Qe.prototype=$desc
 function PK(a){this.a=a}PK.builtin$cls="PK"
 if(!"name" in PK)PK.name="PK"
 $desc=$collectedClasses.PK
@@ -25783,7 +26137,7 @@
 $desc=$collectedClasses.JO
 if($desc instanceof Array)$desc=$desc[1]
 JO.prototype=$desc
-function f0(Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2,my,XC,w2){this.Hg=Hg
+function f0(Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2,vd,XC,w2){this.Hg=Hg
 this.oL=oL
 this.hJ=hJ
 this.N0=N0
@@ -25793,7 +26147,7 @@
 this.EF=EF
 this.ji=ji
 this.i2=i2
-this.my=my
+this.vd=vd
 this.XC=XC
 this.w2=w2}f0.builtin$cls="f0"
 if(!"name" in f0)f0.name="f0"
@@ -25803,16 +26157,24 @@
 f0.prototype.gi2=function(){return this.i2}
 f0.prototype.si2=function(v){return this.i2=v}
 f0.prototype.gw2=function(){return this.w2}
-function aX(jO,Gx,fW,En){this.jO=jO
+function aX(jO,Gx,fW,En,EE,Qy,RW,C9,lJ){this.jO=jO
 this.Gx=Gx
 this.fW=fW
-this.En=En}aX.builtin$cls="aX"
+this.En=En
+this.EE=EE
+this.Qy=Qy
+this.RW=RW
+this.C9=C9
+this.lJ=lJ}aX.builtin$cls="aX"
 if(!"name" in aX)aX.name="aX"
 $desc=$collectedClasses.aX
 if($desc instanceof Array)$desc=$desc[1]
 aX.prototype=$desc
 aX.prototype.gjO=function(receiver){return this.jO}
 aX.prototype.gEn=function(){return this.En}
+aX.prototype.gEE=function(){return this.EE}
+aX.prototype.gRW=function(){return this.RW}
+aX.prototype.gC9=function(){return this.C9}
 function cC(Rk,bZ){this.Rk=Rk
 this.bZ=bZ}cC.builtin$cls="cC"
 if(!"name" in cC)cC.name="cC"
@@ -25849,11 +26211,11 @@
 $desc=$collectedClasses.jl
 if($desc instanceof Array)$desc=$desc[1]
 jl.prototype=$desc
-function Iy4(){}Iy4.builtin$cls="Iy4"
-if(!"name" in Iy4)Iy4.name="Iy4"
-$desc=$collectedClasses.Iy4
+function Iy(){}Iy.builtin$cls="Iy"
+if(!"name" in Iy)Iy.name="Iy"
+$desc=$collectedClasses.Iy
 if($desc instanceof Array)$desc=$desc[1]
-Iy4.prototype=$desc
+Iy.prototype=$desc
 function Z6(JE,Jz){this.JE=JE
 this.Jz=Jz}Z6.builtin$cls="Z6"
 if(!"name" in Z6)Z6.name="Z6"
@@ -25881,20 +26243,14 @@
 $desc=$collectedClasses.yo
 if($desc instanceof Array)$desc=$desc[1]
 yo.prototype=$desc
-yo.prototype.gng=function(){return this.ng}
+yo.prototype.gng=function(receiver){return this.ng}
 yo.prototype.gP0=function(){return this.P0}
-function Rd(vl,da){this.vl=vl
-this.da=da}Rd.builtin$cls="Rd"
-if(!"name" in Rd)Rd.name="Rd"
-$desc=$collectedClasses.Rd
+function NA(CN,il){this.CN=CN
+this.il=il}NA.builtin$cls="NA"
+if(!"name" in NA)NA.name="NA"
+$desc=$collectedClasses.NA
 if($desc instanceof Array)$desc=$desc[1]
-Rd.prototype=$desc
-function Bj(CN,il){this.CN=CN
-this.il=il}Bj.builtin$cls="Bj"
-if(!"name" in Bj)Bj.name="Bj"
-$desc=$collectedClasses.Bj
-if($desc instanceof Array)$desc=$desc[1]
-Bj.prototype=$desc
+NA.prototype=$desc
 function NO(il){this.il=il}NO.builtin$cls="NO"
 if(!"name" in NO)NO.name="NO"
 $desc=$collectedClasses.NO
@@ -25936,11 +26292,11 @@
 $desc=$collectedClasses.hz
 if($desc instanceof Array)$desc=$desc[1]
 hz.prototype=$desc
-function AP(){}AP.builtin$cls="AP"
-if(!"name" in AP)AP.name="AP"
-$desc=$collectedClasses.AP
+function iY(){}iY.builtin$cls="iY"
+if(!"name" in iY)iY.name="iY"
+$desc=$collectedClasses.iY
 if($desc instanceof Array)$desc=$desc[1]
-AP.prototype=$desc
+iY.prototype=$desc
 function yH(Kf,zu,p9){this.Kf=Kf
 this.zu=zu
 this.p9=p9}yH.builtin$cls="yH"
@@ -25960,6 +26316,12 @@
 $desc=$collectedClasses.Av
 if($desc instanceof Array)$desc=$desc[1]
 Av.prototype=$desc
+function ku(ng){this.ng=ng}ku.builtin$cls="ku"
+if(!"name" in ku)ku.name="ku"
+$desc=$collectedClasses.ku
+if($desc instanceof Array)$desc=$desc[1]
+ku.prototype=$desc
+ku.prototype.gng=function(receiver){return this.ng}
 function Zd(){}Zd.builtin$cls="Zd"
 if(!"name" in Zd)Zd.name="Zd"
 $desc=$collectedClasses.Zd
@@ -25970,18 +26332,18 @@
 $desc=$collectedClasses.xQ
 if($desc instanceof Array)$desc=$desc[1]
 xQ.prototype=$desc
-function Q9(){}Q9.builtin$cls="Q9"
-if(!"name" in Q9)Q9.name="Q9"
-$desc=$collectedClasses.Q9
+function F0(){}F0.builtin$cls="F0"
+if(!"name" in F0)F0.name="F0"
+$desc=$collectedClasses.F0
 if($desc instanceof Array)$desc=$desc[1]
-Q9.prototype=$desc
+F0.prototype=$desc
 function oH(){}oH.builtin$cls="oH"
 if(!"name" in oH)oH.name="oH"
 $desc=$collectedClasses.oH
 if($desc instanceof Array)$desc=$desc[1]
 oH.prototype=$desc
-function LPe(B,eZ,tc){this.B=B
-this.eZ=eZ
+function LPe(B,HV,tc){this.B=B
+this.HV=HV
 this.tc=tc}LPe.builtin$cls="LPe"
 if(!"name" in LPe)LPe.name="LPe"
 $desc=$collectedClasses.LPe
@@ -26020,14 +26382,18 @@
 $desc=$collectedClasses.LI
 if($desc instanceof Array)$desc=$desc[1]
 LI.prototype=$desc
-function Ny(mr,eK,Ot){this.mr=mr
+function A2(Pi,mr,eK,Ot){this.Pi=Pi
+this.mr=mr
 this.eK=eK
-this.Ot=Ot}Ny.builtin$cls="Ny"
-if(!"name" in Ny)Ny.name="Ny"
-$desc=$collectedClasses.Ny
+this.Ot=Ot}A2.builtin$cls="A2"
+if(!"name" in A2)A2.name="A2"
+$desc=$collectedClasses.A2
 if($desc instanceof Array)$desc=$desc[1]
-Ny.prototype=$desc
-function IW(qa,mr,eK,Ot){this.qa=qa
+A2.prototype=$desc
+A2.prototype.gPi=function(){return this.Pi}
+A2.prototype.geK=function(){return this.eK}
+function IW(qa,Pi,mr,eK,Ot){this.qa=qa
+this.Pi=Pi
 this.mr=mr
 this.eK=eK
 this.Ot=Ot}IW.builtin$cls="IW"
@@ -26293,7 +26659,7 @@
 $desc=$collectedClasses.tQ
 if($desc instanceof Array)$desc=$desc[1]
 tQ.prototype=$desc
-function G6(eE,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eE=eE
+function G6(BW,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.BW=BW
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26301,29 +26667,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}G6.builtin$cls="G6"
+this.X0=X0}G6.builtin$cls="G6"
 if(!"name" in G6)G6.name="G6"
 $desc=$collectedClasses.G6
 if($desc instanceof Array)$desc=$desc[1]
 G6.prototype=$desc
-G6.prototype.geE=function(receiver){return receiver.eE}
-G6.prototype.geE.$reflectable=1
-G6.prototype.seE=function(receiver,v){return receiver.eE=v}
-G6.prototype.seE.$reflectable=1
+G6.prototype.gBW=function(receiver){return receiver.BW}
+G6.prototype.gBW.$reflectable=1
+G6.prototype.sBW=function(receiver,v){return receiver.BW=v}
+G6.prototype.sBW.$reflectable=1
 function Vf(){}Vf.builtin$cls="Vf"
 if(!"name" in Vf)Vf.name="Vf"
 $desc=$collectedClasses.Vf
 if($desc instanceof Array)$desc=$desc[1]
 Vf.prototype=$desc
-function kf(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function Tg(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26331,19 +26698,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}kf.builtin$cls="kf"
-if(!"name" in kf)kf.name="kf"
-$desc=$collectedClasses.kf
+this.X0=X0}Tg.builtin$cls="Tg"
+if(!"name" in Tg)Tg.name="Tg"
+$desc=$collectedClasses.Tg
 if($desc instanceof Array)$desc=$desc[1]
-kf.prototype=$desc
-function Ps(F0,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.F0=F0
+Tg.prototype=$desc
+function Ps(F0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.F0=F0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26351,14 +26718,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Ps.builtin$cls="Ps"
+this.X0=X0}Ps.builtin$cls="Ps"
 if(!"name" in Ps)Ps.name="Ps"
 $desc=$collectedClasses.Ps
 if($desc instanceof Array)$desc=$desc[1]
@@ -26372,8 +26739,9 @@
 $desc=$collectedClasses.pv
 if($desc instanceof Array)$desc=$desc[1]
 pv.prototype=$desc
-function CN(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function CN(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26381,19 +26749,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}CN.builtin$cls="CN"
+this.X0=X0}CN.builtin$cls="CN"
 if(!"name" in CN)CN.name="CN"
 $desc=$collectedClasses.CN
 if($desc instanceof Array)$desc=$desc[1]
 CN.prototype=$desc
-function vc(eJ,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eJ=eJ
+function vc(eJ,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.eJ=eJ
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26401,14 +26769,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}vc.builtin$cls="vc"
+this.X0=X0}vc.builtin$cls="vc"
 if(!"name" in vc)vc.name="vc"
 $desc=$collectedClasses.vc
 if($desc instanceof Array)$desc=$desc[1]
@@ -26422,7 +26790,7 @@
 $desc=$collectedClasses.Vfx
 if($desc instanceof Array)$desc=$desc[1]
 Vfx.prototype=$desc
-function i6(zh,HX,Uy,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.zh=zh
+function i6(zh,HX,Uy,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.zh=zh
 this.HX=HX
 this.Uy=Uy
 this.AP=AP
@@ -26432,14 +26800,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}i6.builtin$cls="i6"
+this.X0=X0}i6.builtin$cls="i6"
 if(!"name" in i6)i6.name="i6"
 $desc=$collectedClasses.i6
 if($desc instanceof Array)$desc=$desc[1]
@@ -26543,12 +26911,12 @@
 $desc=$collectedClasses.H6
 if($desc instanceof Array)$desc=$desc[1]
 H6.prototype=$desc
-function d5(l6,FT){this.l6=l6
-this.FT=FT}d5.builtin$cls="d5"
-if(!"name" in d5)d5.name="d5"
-$desc=$collectedClasses.d5
+function wB(l6,FT){this.l6=l6
+this.FT=FT}wB.builtin$cls="wB"
+if(!"name" in wB)wB.name="wB"
+$desc=$collectedClasses.wB
 if($desc instanceof Array)$desc=$desc[1]
-d5.prototype=$desc
+wB.prototype=$desc
 function U1(OI,FT){this.OI=OI
 this.FT=FT}U1.builtin$cls="U1"
 if(!"name" in U1)U1.name="U1"
@@ -26565,16 +26933,16 @@
 $desc=$collectedClasses.SU7
 if($desc instanceof Array)$desc=$desc[1]
 SU7.prototype=$desc
-function JJ(){}JJ.builtin$cls="JJ"
-if(!"name" in JJ)JJ.name="JJ"
-$desc=$collectedClasses.JJ
+function Qr(){}Qr.builtin$cls="Qr"
+if(!"name" in Qr)Qr.name="Qr"
+$desc=$collectedClasses.Qr
 if($desc instanceof Array)$desc=$desc[1]
-JJ.prototype=$desc
-function Iy(){}Iy.builtin$cls="Iy"
-if(!"name" in Iy)Iy.name="Iy"
-$desc=$collectedClasses.Iy
+Qr.prototype=$desc
+function w2Y(){}w2Y.builtin$cls="w2Y"
+if(!"name" in w2Y)w2Y.name="w2Y"
+$desc=$collectedClasses.w2Y
 if($desc instanceof Array)$desc=$desc[1]
-Iy.prototype=$desc
+w2Y.prototype=$desc
 function iK(CR){this.CR=CR}iK.builtin$cls="iK"
 if(!"name" in iK)iK.name="iK"
 $desc=$collectedClasses.iK
@@ -26613,12 +26981,12 @@
 $desc=$collectedClasses.mb
 if($desc instanceof Array)$desc=$desc[1]
 mb.prototype=$desc
-function mZ(If){this.If=If}mZ.builtin$cls="mZ"
-if(!"name" in mZ)mZ.name="mZ"
-$desc=$collectedClasses.mZ
+function am(If){this.If=If}am.builtin$cls="am"
+if(!"name" in am)am.name="am"
+$desc=$collectedClasses.am
 if($desc instanceof Array)$desc=$desc[1]
-mZ.prototype=$desc
-mZ.prototype.gIf=function(){return this.If}
+am.prototype=$desc
+am.prototype.gIf=function(){return this.If}
 function cw(XP,xW,Nz,LQ,If){this.XP=XP
 this.xW=xW
 this.Nz=Nz
@@ -26659,11 +27027,11 @@
 Uz.prototype.gFP=function(){return this.FP}
 Uz.prototype.gGD=function(){return this.GD}
 Uz.prototype.gae=function(){return this.ae}
-function NZ(){}NZ.builtin$cls="NZ"
-if(!"name" in NZ)NZ.name="NZ"
-$desc=$collectedClasses.NZ
+function uh(){}uh.builtin$cls="uh"
+if(!"name" in uh)uh.name="uh"
+$desc=$collectedClasses.uh
 if($desc instanceof Array)$desc=$desc[1]
-NZ.prototype=$desc
+uh.prototype=$desc
 function IB(a){this.a=a}IB.builtin$cls="IB"
 if(!"name" in IB)IB.name="IB"
 $desc=$collectedClasses.IB
@@ -26689,17 +27057,18 @@
 if($desc instanceof Array)$desc=$desc[1]
 BI.prototype=$desc
 BI.prototype.gAY=function(){return this.AY}
-function vk(){}vk.builtin$cls="vk"
-if(!"name" in vk)vk.name="vk"
-$desc=$collectedClasses.vk
+function Un(){}Un.builtin$cls="Un"
+if(!"name" in Un)Un.name="Un"
+$desc=$collectedClasses.Un
 if($desc instanceof Array)$desc=$desc[1]
-vk.prototype=$desc
+Un.prototype=$desc
 function M2(){}M2.builtin$cls="M2"
 if(!"name" in M2)M2.name="M2"
 $desc=$collectedClasses.M2
 if($desc instanceof Array)$desc=$desc[1]
 M2.prototype=$desc
-function iu(Ax){this.Ax=Ax}iu.builtin$cls="iu"
+function iu(Ax,xq){this.Ax=Ax
+this.xq=xq}iu.builtin$cls="iu"
 if(!"name" in iu)iu.name="iu"
 $desc=$collectedClasses.iu
 if($desc instanceof Array)$desc=$desc[1]
@@ -26710,7 +27079,7 @@
 $desc=$collectedClasses.mg
 if($desc instanceof Array)$desc=$desc[1]
 mg.prototype=$desc
-function bl(NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,QY,If){this.NK=NK
+function bl(NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,RH,If){this.NK=NK
 this.EZ=EZ
 this.ut=ut
 this.Db=Db
@@ -26724,7 +27093,7 @@
 this.qN=qN
 this.qm=qm
 this.eL=eL
-this.QY=QY
+this.RH=RH
 this.If=If}bl.builtin$cls="bl"
 if(!"name" in bl)bl.name="bl"
 $desc=$collectedClasses.bl
@@ -26750,7 +27119,7 @@
 $desc=$collectedClasses.Ax
 if($desc instanceof Array)$desc=$desc[1]
 Ax.prototype=$desc
-function Wf(Cr,Tx,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,QY,nz,If){this.Cr=Cr
+function Wf(Cr,Tx,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,RH,nz,If){this.Cr=Cr
 this.Tx=Tx
 this.H8=H8
 this.Ht=Ht
@@ -26770,7 +27139,7 @@
 this.qm=qm
 this.UF=UF
 this.eL=eL
-this.QY=QY
+this.RH=RH
 this.nz=nz
 this.If=If}Wf.builtin$cls="Wf"
 if(!"name" in Wf)Wf.name="Wf"
@@ -26779,11 +27148,11 @@
 Wf.prototype=$desc
 Wf.prototype.gCr=function(){return this.Cr}
 Wf.prototype.gTx=function(){return this.Tx}
-function HZT(){}HZT.builtin$cls="HZT"
-if(!"name" in HZT)HZT.name="HZT"
-$desc=$collectedClasses.HZT
+function vk(){}vk.builtin$cls="vk"
+if(!"name" in vk)vk.name="vk"
+$desc=$collectedClasses.vk
 if($desc instanceof Array)$desc=$desc[1]
-HZT.prototype=$desc
+vk.prototype=$desc
 function Ei(a){this.a=a}Ei.builtin$cls="Ei"
 if(!"name" in Ei)Ei.name="Ei"
 $desc=$collectedClasses.Ei
@@ -26815,12 +27184,13 @@
 Ld.prototype.gV5=function(){return this.V5}
 Ld.prototype.gFo=function(){return this.Fo}
 Ld.prototype.gAy=function(receiver){return this.Ay}
-function Sz(Ax){this.Ax=Ax}Sz.builtin$cls="Sz"
+function Sz(Ax,xq){this.Ax=Ax
+this.xq=xq}Sz.builtin$cls="Sz"
 if(!"name" in Sz)Sz.name="Sz"
 $desc=$collectedClasses.Sz
 if($desc instanceof Array)$desc=$desc[1]
 Sz.prototype=$desc
-function Zk(dl,Yq,lT,hB,Fo,xV,qx,nz,le,G6,H3,If){this.dl=dl
+function Zk(dl,Yq,lT,hB,Fo,xV,qx,nz,le,wM,H3,If){this.dl=dl
 this.Yq=Yq
 this.lT=lT
 this.hB=hB
@@ -26829,7 +27199,7 @@
 this.qx=qx
 this.nz=nz
 this.le=le
-this.G6=G6
+this.wM=wM
 this.H3=H3
 this.If=If}Zk.builtin$cls="Zk"
 if(!"name" in Zk)Zk.name="Zk"
@@ -26840,11 +27210,12 @@
 Zk.prototype.ghB=function(){return this.hB}
 Zk.prototype.gFo=function(){return this.Fo}
 Zk.prototype.gxV=function(){return this.xV}
-function fu(XP,Ay,Q2,Sh,BE,If){this.XP=XP
+function fu(XP,Ay,Q2,Sh,BE,QY,If){this.XP=XP
 this.Ay=Ay
 this.Q2=Q2
 this.Sh=Sh
 this.BE=BE
+this.QY=QY
 this.If=If}fu.builtin$cls="fu"
 if(!"name" in fu)fu.name="fu"
 $desc=$collectedClasses.fu
@@ -26853,6 +27224,11 @@
 fu.prototype.gXP=function(){return this.XP}
 fu.prototype.gAy=function(receiver){return this.Ay}
 fu.prototype.gQ2=function(){return this.Q2}
+function wt(){}wt.builtin$cls="wt"
+if(!"name" in wt)wt.name="wt"
+$desc=$collectedClasses.wt
+if($desc instanceof Array)$desc=$desc[1]
+wt.prototype=$desc
 function ng(Cr,CM,If){this.Cr=Cr
 this.CM=CM
 this.If=If}ng.builtin$cls="ng"
@@ -26940,16 +27316,12 @@
 JI.prototype.siE=function(v){return this.iE=v}
 JI.prototype.gSJ=function(){return this.SJ}
 JI.prototype.sSJ=function(v){return this.SJ=v}
-function Ks(nL,QC,iE,SJ){this.nL=nL
-this.QC=QC
-this.iE=iE
+function Ks(iE,SJ){this.iE=iE
 this.SJ=SJ}Ks.builtin$cls="Ks"
 if(!"name" in Ks)Ks.name="Ks"
 $desc=$collectedClasses.Ks
 if($desc instanceof Array)$desc=$desc[1]
 Ks.prototype=$desc
-Ks.prototype.gnL=function(){return this.nL}
-Ks.prototype.gQC=function(){return this.QC}
 Ks.prototype.giE=function(){return this.iE}
 Ks.prototype.siE=function(v){return this.iE=v}
 Ks.prototype.gSJ=function(){return this.SJ}
@@ -27053,45 +27425,64 @@
 $desc=$collectedClasses.ZL
 if($desc instanceof Array)$desc=$desc[1]
 ZL.prototype=$desc
-function mi(c,d){this.c=c
-this.d=d}mi.builtin$cls="mi"
-if(!"name" in mi)mi.name="mi"
-$desc=$collectedClasses.mi
+function rq(b,c,d,e){this.b=b
+this.c=c
+this.d=d
+this.e=e}rq.builtin$cls="rq"
+if(!"name" in rq)rq.name="rq"
+$desc=$collectedClasses.rq
 if($desc instanceof Array)$desc=$desc[1]
-mi.prototype=$desc
-function jb(c,b,e,f){this.c=c
+rq.prototype=$desc
+function RW(c,b,f,UI){this.c=c
 this.b=b
-this.e=e
-this.f=f}jb.builtin$cls="jb"
-if(!"name" in jb)jb.name="jb"
-$desc=$collectedClasses.jb
+this.f=f
+this.UI=UI}RW.builtin$cls="RW"
+if(!"name" in RW)RW.name="RW"
+$desc=$collectedClasses.RW
 if($desc instanceof Array)$desc=$desc[1]
-jb.prototype=$desc
-function wB(c,UI){this.c=c
-this.UI=UI}wB.builtin$cls="wB"
-if(!"name" in wB)wB.name="wB"
-$desc=$collectedClasses.wB
+RW.prototype=$desc
+function RT(c,b,bK,Gq,Rm){this.c=c
+this.b=b
+this.bK=bK
+this.Gq=Gq
+this.Rm=Rm}RT.builtin$cls="RT"
+if(!"name" in RT)RT.name="RT"
+$desc=$collectedClasses.RT
 if($desc instanceof Array)$desc=$desc[1]
-wB.prototype=$desc
-function Pu(a,bK){this.a=a
-this.bK=bK}Pu.builtin$cls="Pu"
-if(!"name" in Pu)Pu.name="Pu"
-$desc=$collectedClasses.Pu
+RT.prototype=$desc
+function jZ(c,w3){this.c=c
+this.w3=w3}jZ.builtin$cls="jZ"
+if(!"name" in jZ)jZ.name="jZ"
+$desc=$collectedClasses.jZ
 if($desc instanceof Array)$desc=$desc[1]
-Pu.prototype=$desc
+jZ.prototype=$desc
+function FZ(a,HZ){this.a=a
+this.HZ=HZ}FZ.builtin$cls="FZ"
+if(!"name" in FZ)FZ.name="FZ"
+$desc=$collectedClasses.FZ
+if($desc instanceof Array)$desc=$desc[1]
+FZ.prototype=$desc
+function OM(FR,aw){this.FR=FR
+this.aw=aw}OM.builtin$cls="OM"
+if(!"name" in OM)OM.name="OM"
+$desc=$collectedClasses.OM
+if($desc instanceof Array)$desc=$desc[1]
+OM.prototype=$desc
+OM.prototype.gaw=function(){return this.aw}
+OM.prototype.saw=function(v){return this.aw=v}
 function qh(){}qh.builtin$cls="qh"
 if(!"name" in qh)qh.name="qh"
 $desc=$collectedClasses.qh
 if($desc instanceof Array)$desc=$desc[1]
 qh.prototype=$desc
-function YJ(a,b,c,d){this.a=a
+function tG(a,b,c,d){this.a=a
 this.b=b
 this.c=c
-this.d=d}YJ.builtin$cls="YJ"
-if(!"name" in YJ)YJ.name="YJ"
-$desc=$collectedClasses.YJ
+this.d=d}tG.builtin$cls="tG"
+if(!"name" in tG)tG.name="tG"
+$desc=$collectedClasses.tG
 if($desc instanceof Array)$desc=$desc[1]
-YJ.prototype=$desc
+tG.prototype=$desc
 function jv(e,f){this.e=e
 this.f=f}jv.builtin$cls="jv"
 if(!"name" in jv)jv.name="jv"
@@ -27104,11 +27495,11 @@
 $desc=$collectedClasses.LB
 if($desc instanceof Array)$desc=$desc[1]
 LB.prototype=$desc
-function DO(bK){this.bK=bK}DO.builtin$cls="DO"
-if(!"name" in DO)DO.name="DO"
-$desc=$collectedClasses.DO
+function zn(bK){this.bK=bK}zn.builtin$cls="zn"
+if(!"name" in zn)zn.name="zn"
+$desc=$collectedClasses.zn
 if($desc instanceof Array)$desc=$desc[1]
-DO.prototype=$desc
+zn.prototype=$desc
 function lz(a,b,c,d){this.a=a
 this.b=b
 this.c=c
@@ -27234,89 +27625,17 @@
 $desc=$collectedClasses.MO
 if($desc instanceof Array)$desc=$desc[1]
 MO.prototype=$desc
-function ms(){}ms.builtin$cls="ms"
-if(!"name" in ms)ms.name="ms"
-$desc=$collectedClasses.ms
-if($desc instanceof Array)$desc=$desc[1]
-ms.prototype=$desc
-function UO(a){this.a=a}UO.builtin$cls="UO"
-if(!"name" in UO)UO.name="UO"
-$desc=$collectedClasses.UO
-if($desc instanceof Array)$desc=$desc[1]
-UO.prototype=$desc
-function Bc(a){this.a=a}Bc.builtin$cls="Bc"
-if(!"name" in Bc)Bc.name="Bc"
-$desc=$collectedClasses.Bc
-if($desc instanceof Array)$desc=$desc[1]
-Bc.prototype=$desc
-function vp(){}vp.builtin$cls="vp"
-if(!"name" in vp)vp.name="vp"
-$desc=$collectedClasses.vp
-if($desc instanceof Array)$desc=$desc[1]
-vp.prototype=$desc
-function lk(){}lk.builtin$cls="lk"
-if(!"name" in lk)lk.name="lk"
-$desc=$collectedClasses.lk
-if($desc instanceof Array)$desc=$desc[1]
-lk.prototype=$desc
-function q1(nL,p4,Z9,QC,iP,Gv,Ip){this.nL=nL
-this.p4=p4
-this.Z9=Z9
-this.QC=QC
-this.iP=iP
-this.Gv=Gv
-this.Ip=Ip}q1.builtin$cls="q1"
-if(!"name" in q1)q1.name="q1"
-$desc=$collectedClasses.q1
-if($desc instanceof Array)$desc=$desc[1]
-q1.prototype=$desc
-q1.prototype.gnL=function(){return this.nL}
-q1.prototype.gp4=function(){return this.p4}
-q1.prototype.gZ9=function(){return this.Z9}
-q1.prototype.gQC=function(){return this.QC}
-function ZzD(){}ZzD.builtin$cls="ZzD"
-if(!"name" in ZzD)ZzD.name="ZzD"
-$desc=$collectedClasses.ZzD
-if($desc instanceof Array)$desc=$desc[1]
-ZzD.prototype=$desc
-function ly(nL,p4,Z9,QC,iP,Gv,Ip){this.nL=nL
-this.p4=p4
-this.Z9=Z9
-this.QC=QC
-this.iP=iP
-this.Gv=Gv
-this.Ip=Ip}ly.builtin$cls="ly"
-if(!"name" in ly)ly.name="ly"
-$desc=$collectedClasses.ly
-if($desc instanceof Array)$desc=$desc[1]
-ly.prototype=$desc
-ly.prototype.gnL=function(){return this.nL}
-ly.prototype.gp4=function(){return this.p4}
-ly.prototype.gZ9=function(){return this.Z9}
-ly.prototype.gQC=function(){return this.QC}
-function fE(){}fE.builtin$cls="fE"
-if(!"name" in fE)fE.name="fE"
-$desc=$collectedClasses.fE
-if($desc instanceof Array)$desc=$desc[1]
-fE.prototype=$desc
-function O9(Y8){this.Y8=Y8}O9.builtin$cls="O9"
+function O9(){}O9.builtin$cls="O9"
 if(!"name" in O9)O9.name="O9"
 $desc=$collectedClasses.O9
 if($desc instanceof Array)$desc=$desc[1]
 O9.prototype=$desc
-function yU(Y8,dB,o7,Bd,Lj,Gv,lz,Ri){this.Y8=Y8
-this.dB=dB
-this.o7=o7
-this.Bd=Bd
-this.Lj=Lj
-this.Gv=Gv
-this.lz=lz
-this.Ri=Ri}yU.builtin$cls="yU"
-if(!"name" in yU)yU.name="yU"
-$desc=$collectedClasses.yU
+function oh(Y8){this.Y8=Y8}oh.builtin$cls="oh"
+if(!"name" in oh)oh.name="oh"
+$desc=$collectedClasses.oh
 if($desc instanceof Array)$desc=$desc[1]
-yU.prototype=$desc
-yU.prototype.gY8=function(){return this.Y8}
+oh.prototype=$desc
+oh.prototype.gY8=function(){return this.Y8}
 function nP(){}nP.builtin$cls="nP"
 if(!"name" in nP)nP.name="nP"
 $desc=$collectedClasses.nP
@@ -27352,23 +27671,23 @@
 $desc=$collectedClasses.ez
 if($desc instanceof Array)$desc=$desc[1]
 ez.prototype=$desc
-function lx(LD){this.LD=LD}lx.builtin$cls="lx"
+function lx(aw){this.aw=aw}lx.builtin$cls="lx"
 if(!"name" in lx)lx.name="lx"
 $desc=$collectedClasses.lx
 if($desc instanceof Array)$desc=$desc[1]
 lx.prototype=$desc
-lx.prototype.gLD=function(){return this.LD}
-lx.prototype.sLD=function(v){return this.LD=v}
-function LV(P,LD){this.P=P
-this.LD=LD}LV.builtin$cls="LV"
+lx.prototype.gaw=function(){return this.aw}
+lx.prototype.saw=function(v){return this.aw=v}
+function LV(P,aw){this.P=P
+this.aw=aw}LV.builtin$cls="LV"
 if(!"name" in LV)LV.name="LV"
 $desc=$collectedClasses.LV
 if($desc instanceof Array)$desc=$desc[1]
 LV.prototype=$desc
 LV.prototype.gP=function(receiver){return this.P}
-function DS(kc,I4,LD){this.kc=kc
+function DS(kc,I4,aw){this.kc=kc
 this.I4=I4
-this.LD=LD}DS.builtin$cls="DS"
+this.aw=aw}DS.builtin$cls="DS"
 if(!"name" in DS)DS.name="DS"
 $desc=$collectedClasses.DS
 if($desc instanceof Array)$desc=$desc[1]
@@ -27380,11 +27699,11 @@
 $desc=$collectedClasses.JF
 if($desc instanceof Array)$desc=$desc[1]
 JF.prototype=$desc
-function ht(){}ht.builtin$cls="ht"
-if(!"name" in ht)ht.name="ht"
-$desc=$collectedClasses.ht
+function Je(){}Je.builtin$cls="Je"
+if(!"name" in Je)Je.name="Je"
+$desc=$collectedClasses.Je
 if($desc instanceof Array)$desc=$desc[1]
-ht.prototype=$desc
+Je.prototype=$desc
 function CR(a,b){this.a=a
 this.b=b}CR.builtin$cls="CR"
 if(!"name" in CR)CR.name="CR"
@@ -27398,25 +27717,25 @@
 $desc=$collectedClasses.Qk
 if($desc instanceof Array)$desc=$desc[1]
 Qk.prototype=$desc
-function dR(a,b,c){this.a=a
+function v1y(a,b,c){this.a=a
 this.b=b
-this.c=c}dR.builtin$cls="dR"
-if(!"name" in dR)dR.name="dR"
-$desc=$collectedClasses.dR
+this.c=c}v1y.builtin$cls="v1y"
+if(!"name" in v1y)v1y.name="v1y"
+$desc=$collectedClasses.v1y
 if($desc instanceof Array)$desc=$desc[1]
-dR.prototype=$desc
+v1y.prototype=$desc
 function uR(a,b){this.a=a
 this.b=b}uR.builtin$cls="uR"
 if(!"name" in uR)uR.name="uR"
 $desc=$collectedClasses.uR
 if($desc instanceof Array)$desc=$desc[1]
 uR.prototype=$desc
-function QX(a,b){this.a=a
-this.b=b}QX.builtin$cls="QX"
-if(!"name" in QX)QX.name="QX"
-$desc=$collectedClasses.QX
+function Q0(a,b){this.a=a
+this.b=b}Q0.builtin$cls="Q0"
+if(!"name" in Q0)Q0.name="Q0"
+$desc=$collectedClasses.Q0
 if($desc instanceof Array)$desc=$desc[1]
-QX.prototype=$desc
+Q0.prototype=$desc
 function YR(){}YR.builtin$cls="YR"
 if(!"name" in YR)YR.name="YR"
 $desc=$collectedClasses.YR
@@ -27453,11 +27772,11 @@
 $desc=$collectedClasses.dq
 if($desc instanceof Array)$desc=$desc[1]
 dq.prototype=$desc
-function tU(){}tU.builtin$cls="tU"
-if(!"name" in tU)tU.name="tU"
-$desc=$collectedClasses.tU
+function lO(){}lO.builtin$cls="lO"
+if(!"name" in lO)lO.name="lO"
+$desc=$collectedClasses.lO
 if($desc instanceof Array)$desc=$desc[1]
-tU.prototype=$desc
+lO.prototype=$desc
 function aY(){}aY.builtin$cls="aY"
 if(!"name" in aY)aY.name="aY"
 $desc=$collectedClasses.aY
@@ -27500,7 +27819,7 @@
 $desc=$collectedClasses.JB
 if($desc instanceof Array)$desc=$desc[1]
 JB.prototype=$desc
-function Id(nU){this.nU=nU}Id.builtin$cls="Id"
+function Id(oh){this.oh=oh}Id.builtin$cls="Id"
 if(!"name" in Id)Id.name="Id"
 $desc=$collectedClasses.Id
 if($desc instanceof Array)$desc=$desc[1]
@@ -27546,15 +27865,15 @@
 $desc=$collectedClasses.pV
 if($desc instanceof Array)$desc=$desc[1]
 pV.prototype=$desc
-function cc(eT,zU,R1){this.eT=eT
+function uo(eT,zU,R1){this.eT=eT
 this.zU=zU
-this.R1=R1}cc.builtin$cls="cc"
-if(!"name" in cc)cc.name="cc"
-$desc=$collectedClasses.cc
+this.R1=R1}uo.builtin$cls="uo"
+if(!"name" in uo)uo.name="uo"
+$desc=$collectedClasses.uo
 if($desc instanceof Array)$desc=$desc[1]
-cc.prototype=$desc
-cc.prototype.geT=function(receiver){return this.eT}
-cc.prototype.gzU=function(){return this.zU}
+uo.prototype=$desc
+uo.prototype.geT=function(receiver){return this.eT}
+uo.prototype.gzU=function(){return this.zU}
 function pK(a,b){this.a=a
 this.b=b}pK.builtin$cls="pK"
 if(!"name" in pK)pK.name="pK"
@@ -27572,21 +27891,21 @@
 $desc=$collectedClasses.Uez
 if($desc instanceof Array)$desc=$desc[1]
 Uez.prototype=$desc
-function W5(){}W5.builtin$cls="W5"
-if(!"name" in W5)W5.name="W5"
-$desc=$collectedClasses.W5
+function nU(){}nU.builtin$cls="nU"
+if(!"name" in nU)nU.name="nU"
+$desc=$collectedClasses.nU
 if($desc instanceof Array)$desc=$desc[1]
-W5.prototype=$desc
+nU.prototype=$desc
 function R8(){}R8.builtin$cls="R8"
 if(!"name" in R8)R8.name="R8"
 $desc=$collectedClasses.R8
 if($desc instanceof Array)$desc=$desc[1]
 R8.prototype=$desc
-function k6(X5,vv,OX,OB,aw){this.X5=X5
+function k6(X5,vv,OX,OB,wV){this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}k6.builtin$cls="k6"
+this.wV=wV}k6.builtin$cls="k6"
 if(!"name" in k6)k6.name="k6"
 $desc=$collectedClasses.k6
 if($desc instanceof Array)$desc=$desc[1]
@@ -27607,23 +27926,23 @@
 $desc=$collectedClasses.DJ
 if($desc instanceof Array)$desc=$desc[1]
 DJ.prototype=$desc
-function PL(X5,vv,OX,OB,aw){this.X5=X5
+function PL(X5,vv,OX,OB,wV){this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}PL.builtin$cls="PL"
+this.wV=wV}PL.builtin$cls="PL"
 if(!"name" in PL)PL.name="PL"
 $desc=$collectedClasses.PL
 if($desc instanceof Array)$desc=$desc[1]
 PL.prototype=$desc
-function Fq(m6,Q6,ac,X5,vv,OX,OB,aw){this.m6=m6
+function Fq(m6,Q6,ac,X5,vv,OX,OB,wV){this.m6=m6
 this.Q6=Q6
 this.ac=ac
 this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}Fq.builtin$cls="Fq"
+this.wV=wV}Fq.builtin$cls="Fq"
 if(!"name" in Fq)Fq.name="Fq"
 $desc=$collectedClasses.Fq
 if($desc instanceof Array)$desc=$desc[1]
@@ -27638,8 +27957,8 @@
 $desc=$collectedClasses.fG
 if($desc instanceof Array)$desc=$desc[1]
 fG.prototype=$desc
-function EQ(Fb,aw,zi,fD){this.Fb=Fb
-this.aw=aw
+function EQ(Fb,wV,zi,fD){this.Fb=Fb
+this.wV=wV
 this.zi=zi
 this.fD=fD}EQ.builtin$cls="EQ"
 if(!"name" in EQ)EQ.name="EQ"
@@ -27815,16 +28134,16 @@
 $desc=$collectedClasses.ZQ
 if($desc instanceof Array)$desc=$desc[1]
 ZQ.prototype=$desc
-function Sw(v5,av,HV,qT){this.v5=v5
+function Sw(v5,av,eZ,qT){this.v5=v5
 this.av=av
-this.HV=HV
+this.eZ=eZ
 this.qT=qT}Sw.builtin$cls="Sw"
 if(!"name" in Sw)Sw.name="Sw"
 $desc=$collectedClasses.Sw
 if($desc instanceof Array)$desc=$desc[1]
 Sw.prototype=$desc
-function o0(Lz,dP,qT,Dc,fD){this.Lz=Lz
-this.dP=dP
+function o0(Lz,pP,qT,Dc,fD){this.Lz=Lz
+this.pP=pP
 this.qT=qT
 this.Dc=Dc
 this.fD=fD}o0.builtin$cls="o0"
@@ -27840,8 +28159,8 @@
 if($desc instanceof Array)$desc=$desc[1]
 qv.prototype=$desc
 qv.prototype.gG3=function(receiver){return this.G3}
-qv.prototype.gBb=function(receiver){return this.Bb}
-qv.prototype.gT8=function(receiver){return this.T8}
+qv.prototype.gBb=function(){return this.Bb}
+qv.prototype.gT8=function(){return this.T8}
 function jp(P,G3,Bb,T8){this.P=P
 this.G3=G3
 this.Bb=Bb
@@ -27964,16 +28283,17 @@
 $desc=$collectedClasses.K8
 if($desc instanceof Array)$desc=$desc[1]
 K8.prototype=$desc
-function by(){}by.builtin$cls="by"
+function by(N5,iY){this.N5=N5
+this.iY=iY}by.builtin$cls="by"
 if(!"name" in by)by.name="by"
 $desc=$collectedClasses.by
 if($desc instanceof Array)$desc=$desc[1]
 by.prototype=$desc
-function pD(Xi){this.Xi=Xi}pD.builtin$cls="pD"
-if(!"name" in pD)pD.name="pD"
-$desc=$collectedClasses.pD
+function dI(Xi){this.Xi=Xi}dI.builtin$cls="dI"
+if(!"name" in dI)dI.name="dI"
+$desc=$collectedClasses.dI
 if($desc instanceof Array)$desc=$desc[1]
-pD.prototype=$desc
+dI.prototype=$desc
 function Cf(N5){this.N5=N5}Cf.builtin$cls="Cf"
 if(!"name" in Cf)Cf.name="Cf"
 $desc=$collectedClasses.Cf
@@ -28009,21 +28329,6 @@
 $desc=$collectedClasses.Rw
 if($desc instanceof Array)$desc=$desc[1]
 Rw.prototype=$desc
-function GY(lH){this.lH=lH}GY.builtin$cls="GY"
-if(!"name" in GY)GY.name="GY"
-$desc=$collectedClasses.GY
-if($desc instanceof Array)$desc=$desc[1]
-GY.prototype=$desc
-function jZ(lH,aS,rU,Ok,TY,VN){this.lH=lH
-this.aS=aS
-this.rU=rU
-this.Ok=Ok
-this.TY=TY
-this.VN=VN}jZ.builtin$cls="jZ"
-if(!"name" in jZ)jZ.name="jZ"
-$desc=$collectedClasses.jZ
-if($desc instanceof Array)$desc=$desc[1]
-jZ.prototype=$desc
 function HB(a){this.a=a}HB.builtin$cls="HB"
 if(!"name" in HB)HB.name="HB"
 $desc=$collectedClasses.HB
@@ -28252,24 +28557,19 @@
 $desc=$collectedClasses.uq
 if($desc instanceof Array)$desc=$desc[1]
 uq.prototype=$desc
-function iD(NN,HC,r0,Fi,iV,tP,Ka,ld,yW){this.NN=NN
+function iD(NN,HC,r0,Fi,ku,tP,Ka,YG,yW){this.NN=NN
 this.HC=HC
 this.r0=r0
 this.Fi=Fi
-this.iV=iV
+this.ku=ku
 this.tP=tP
 this.Ka=Ka
-this.ld=ld
+this.YG=YG
 this.yW=yW}iD.builtin$cls="iD"
 if(!"name" in iD)iD.name="iD"
 $desc=$collectedClasses.iD
 if($desc instanceof Array)$desc=$desc[1]
 iD.prototype=$desc
-function In(a){this.a=a}In.builtin$cls="In"
-if(!"name" in In)In.name="In"
-$desc=$collectedClasses.In
-if($desc instanceof Array)$desc=$desc[1]
-In.prototype=$desc
 function hb(){}hb.builtin$cls="hb"
 if(!"name" in hb)hb.name="hb"
 $desc=$collectedClasses.hb
@@ -28365,16 +28665,6 @@
 $desc=$collectedClasses.QZ
 if($desc instanceof Array)$desc=$desc[1]
 QZ.prototype=$desc
-function BV(){}BV.builtin$cls="BV"
-if(!"name" in BV)BV.name="BV"
-$desc=$collectedClasses.BV
-if($desc instanceof Array)$desc=$desc[1]
-BV.prototype=$desc
-function E1(){}E1.builtin$cls="E1"
-if(!"name" in E1)E1.name="E1"
-$desc=$collectedClasses.E1
-if($desc instanceof Array)$desc=$desc[1]
-E1.prototype=$desc
 function VG(MW,vG){this.MW=MW
 this.vG=vG}VG.builtin$cls="VG"
 if(!"name" in VG)VG.name="VG"
@@ -28415,11 +28705,11 @@
 $desc=$collectedClasses.RAp
 if($desc instanceof Array)$desc=$desc[1]
 RAp.prototype=$desc
-function ma(){}ma.builtin$cls="ma"
-if(!"name" in ma)ma.name="ma"
-$desc=$collectedClasses.ma
+function Gb(){}Gb.builtin$cls="Gb"
+if(!"name" in Gb)Gb.name="Gb"
+$desc=$collectedClasses.Gb
 if($desc instanceof Array)$desc=$desc[1]
-ma.prototype=$desc
+Gb.prototype=$desc
 function Kx(){}Kx.builtin$cls="Kx"
 if(!"name" in Kx)Kx.name="Kx"
 $desc=$collectedClasses.Kx
@@ -28507,6 +28797,12 @@
 $desc=$collectedClasses.vf
 if($desc instanceof Array)$desc=$desc[1]
 vf.prototype=$desc
+function Iw(a,b){this.a=a
+this.b=b}Iw.builtin$cls="Iw"
+if(!"name" in Iw)Iw.name="Iw"
+$desc=$collectedClasses.Iw
+if($desc instanceof Array)$desc=$desc[1]
+Iw.prototype=$desc
 function Fc(a){this.a=a}Fc.builtin$cls="Fc"
 if(!"name" in Fc)Fc.name="Fc"
 $desc=$collectedClasses.Fc
@@ -28589,16 +28885,26 @@
 $desc=$collectedClasses.RX
 if($desc instanceof Array)$desc=$desc[1]
 RX.prototype=$desc
-function hP(Vy){this.Vy=Vy}hP.builtin$cls="hP"
-if(!"name" in hP)hP.name="hP"
-$desc=$collectedClasses.hP
+function bO(xY){this.xY=xY}bO.builtin$cls="bO"
+if(!"name" in bO)bO.name="bO"
+$desc=$collectedClasses.bO
 if($desc instanceof Array)$desc=$desc[1]
-hP.prototype=$desc
+bO.prototype=$desc
 function Gm(){}Gm.builtin$cls="Gm"
 if(!"name" in Gm)Gm.name="Gm"
 $desc=$collectedClasses.Gm
 if($desc instanceof Array)$desc=$desc[1]
 Gm.prototype=$desc
+function Of(xa){this.xa=xa}Of.builtin$cls="Of"
+if(!"name" in Of)Of.name="Of"
+$desc=$collectedClasses.Of
+if($desc instanceof Array)$desc=$desc[1]
+Of.prototype=$desc
+function Qg(je){this.je=je}Qg.builtin$cls="Qg"
+if(!"name" in Qg)Qg.name="Qg"
+$desc=$collectedClasses.Qg
+if($desc instanceof Array)$desc=$desc[1]
+Qg.prototype=$desc
 function W9(nj,vN,Nq,QZ){this.nj=nj
 this.vN=vN
 this.Nq=Nq
@@ -28628,16 +28934,21 @@
 $desc=$collectedClasses.O7
 if($desc instanceof Array)$desc=$desc[1]
 O7.prototype=$desc
+function IU(){}IU.builtin$cls="IU"
+if(!"name" in IU)IU.name="IU"
+$desc=$collectedClasses.IU
+if($desc instanceof Array)$desc=$desc[1]
+IU.prototype=$desc
 function E4(eh){this.eh=eh}E4.builtin$cls="E4"
 if(!"name" in E4)E4.name="E4"
 $desc=$collectedClasses.E4
 if($desc instanceof Array)$desc=$desc[1]
 E4.prototype=$desc
-function Xb(a){this.a=a}Xb.builtin$cls="Xb"
-if(!"name" in Xb)Xb.name="Xb"
-$desc=$collectedClasses.Xb
+function Gn(a){this.a=a}Gn.builtin$cls="Gn"
+if(!"name" in Gn)Gn.name="Gn"
+$desc=$collectedClasses.Gn
 if($desc instanceof Array)$desc=$desc[1]
-Xb.prototype=$desc
+Gn.prototype=$desc
 function r7(eh){this.eh=eh}r7.builtin$cls="r7"
 if(!"name" in r7)r7.name="r7"
 $desc=$collectedClasses.r7
@@ -28708,11 +29019,11 @@
 $desc=$collectedClasses.Ms
 if($desc instanceof Array)$desc=$desc[1]
 Ms.prototype=$desc
-function tg(){}tg.builtin$cls="tg"
-if(!"name" in tg)tg.name="tg"
-$desc=$collectedClasses.tg
+function ac(){}ac.builtin$cls="ac"
+if(!"name" in ac)ac.name="ac"
+$desc=$collectedClasses.ac
 if($desc instanceof Array)$desc=$desc[1]
-tg.prototype=$desc
+ac.prototype=$desc
 function RS(){}RS.builtin$cls="RS"
 if(!"name" in RS)RS.name="RS"
 $desc=$collectedClasses.RS
@@ -28728,19 +29039,19 @@
 $desc=$collectedClasses.Ys
 if($desc instanceof Array)$desc=$desc[1]
 Ys.prototype=$desc
-function WS4(EE,m2,nV,V3){this.EE=EE
-this.m2=m2
+function WS4(ew,yz,nV,V3){this.ew=ew
+this.yz=yz
 this.nV=nV
 this.V3=V3}WS4.builtin$cls="WS4"
 if(!"name" in WS4)WS4.name="WS4"
 $desc=$collectedClasses.WS4
 if($desc instanceof Array)$desc=$desc[1]
 WS4.prototype=$desc
-function A2(EV){this.EV=EV}A2.builtin$cls="A2"
-if(!"name" in A2)A2.name="A2"
-$desc=$collectedClasses.A2
+function Gj(EV){this.EV=EV}Gj.builtin$cls="Gj"
+if(!"name" in Gj)Gj.name="Gj"
+$desc=$collectedClasses.Gj
 if($desc instanceof Array)$desc=$desc[1]
-A2.prototype=$desc
+Gj.prototype=$desc
 function U4(){}U4.builtin$cls="U4"
 if(!"name" in U4)U4.name="U4"
 $desc=$collectedClasses.U4
@@ -28756,42 +29067,42 @@
 $desc=$collectedClasses.Nx
 if($desc instanceof Array)$desc=$desc[1]
 Nx.prototype=$desc
-function ue(){}ue.builtin$cls="ue"
-if(!"name" in ue)ue.name="ue"
-$desc=$collectedClasses.ue
+function LZ(){}LZ.builtin$cls="LZ"
+if(!"name" in LZ)LZ.name="LZ"
+$desc=$collectedClasses.LZ
 if($desc instanceof Array)$desc=$desc[1]
-ue.prototype=$desc
-function GG(){}GG.builtin$cls="GG"
-if(!"name" in GG)GG.name="GG"
-$desc=$collectedClasses.GG
+LZ.prototype=$desc
+function Dg(){}Dg.builtin$cls="Dg"
+if(!"name" in Dg)Dg.name="Dg"
+$desc=$collectedClasses.Dg
 if($desc instanceof Array)$desc=$desc[1]
-GG.prototype=$desc
-function Y8(){}Y8.builtin$cls="Y8"
-if(!"name" in Y8)Y8.name="Y8"
-$desc=$collectedClasses.Y8
+Dg.prototype=$desc
+function Ob(){}Ob.builtin$cls="Ob"
+if(!"name" in Ob)Ob.name="Ob"
+$desc=$collectedClasses.Ob
 if($desc instanceof Array)$desc=$desc[1]
-Y8.prototype=$desc
-function Bk(){}Bk.builtin$cls="Bk"
-if(!"name" in Bk)Bk.name="Bk"
-$desc=$collectedClasses.Bk
+Ob.prototype=$desc
+function Ip(){}Ip.builtin$cls="Ip"
+if(!"name" in Ip)Ip.name="Ip"
+$desc=$collectedClasses.Ip
 if($desc instanceof Array)$desc=$desc[1]
-Bk.prototype=$desc
-function iY(){}iY.builtin$cls="iY"
-if(!"name" in iY)iY.name="iY"
-$desc=$collectedClasses.iY
+Ip.prototype=$desc
+function Pg(){}Pg.builtin$cls="Pg"
+if(!"name" in Pg)Pg.name="Pg"
+$desc=$collectedClasses.Pg
 if($desc instanceof Array)$desc=$desc[1]
-iY.prototype=$desc
-function C0A(){}C0A.builtin$cls="C0A"
-if(!"name" in C0A)C0A.name="C0A"
-$desc=$collectedClasses.C0A
+Pg.prototype=$desc
+function Nb(){}Nb.builtin$cls="Nb"
+if(!"name" in Nb)Nb.name="Nb"
+$desc=$collectedClasses.Nb
 if($desc instanceof Array)$desc=$desc[1]
-C0A.prototype=$desc
-function RAK(){}RAK.builtin$cls="RAK"
-if(!"name" in RAK)RAK.name="RAK"
-$desc=$collectedClasses.RAK
+Nb.prototype=$desc
+function nA(){}nA.builtin$cls="nA"
+if(!"name" in nA)nA.name="nA"
+$desc=$collectedClasses.nA
 if($desc instanceof Array)$desc=$desc[1]
-RAK.prototype=$desc
-function FvP(m0,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.m0=m0
+nA.prototype=$desc
+function Fv(F8,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.F8=F8
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28799,28 +29110,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}FvP.builtin$cls="FvP"
-if(!"name" in FvP)FvP.name="FvP"
-$desc=$collectedClasses.FvP
+this.X0=X0}Fv.builtin$cls="Fv"
+if(!"name" in Fv)Fv.name="Fv"
+$desc=$collectedClasses.Fv
 if($desc instanceof Array)$desc=$desc[1]
-FvP.prototype=$desc
-FvP.prototype.gm0=function(receiver){return receiver.m0}
-FvP.prototype.gm0.$reflectable=1
-FvP.prototype.sm0=function(receiver,v){return receiver.m0=v}
-FvP.prototype.sm0.$reflectable=1
+Fv.prototype=$desc
+Fv.prototype.gF8=function(receiver){return receiver.F8}
+Fv.prototype.gF8.$reflectable=1
+Fv.prototype.sF8=function(receiver,v){return receiver.F8=v}
+Fv.prototype.sF8.$reflectable=1
 function tuj(){}tuj.builtin$cls="tuj"
 if(!"name" in tuj)tuj.name="tuj"
 $desc=$collectedClasses.tuj
 if($desc instanceof Array)$desc=$desc[1]
 tuj.prototype=$desc
-function Ir(Py,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Py=Py
+function E9(Py,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Py=Py
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28828,29 +29139,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Ir.builtin$cls="Ir"
-if(!"name" in Ir)Ir.name="Ir"
-$desc=$collectedClasses.Ir
+this.X0=X0}E9.builtin$cls="E9"
+if(!"name" in E9)E9.name="E9"
+$desc=$collectedClasses.E9
 if($desc instanceof Array)$desc=$desc[1]
-Ir.prototype=$desc
-Ir.prototype.gPy=function(receiver){return receiver.Py}
-Ir.prototype.gPy.$reflectable=1
-Ir.prototype.sPy=function(receiver,v){return receiver.Py=v}
-Ir.prototype.sPy.$reflectable=1
+E9.prototype=$desc
+E9.prototype.gPy=function(receiver){return receiver.Py}
+E9.prototype.gPy.$reflectable=1
+E9.prototype.sPy=function(receiver,v){return receiver.Py=v}
+E9.prototype.sPy.$reflectable=1
 function Vct(){}Vct.builtin$cls="Vct"
 if(!"name" in Vct)Vct.name="Vct"
 $desc=$collectedClasses.Vct
 if($desc instanceof Array)$desc=$desc[1]
 Vct.prototype=$desc
-function m8(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function m8(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28858,19 +29170,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}m8.builtin$cls="m8"
+this.X0=X0}m8.builtin$cls="m8"
 if(!"name" in m8)m8.name="m8"
 $desc=$collectedClasses.m8
 if($desc instanceof Array)$desc=$desc[1]
 m8.prototype=$desc
-function jM(vt,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.vt=vt
+function Gk(vt,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.vt=vt
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28878,29 +29190,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}jM.builtin$cls="jM"
-if(!"name" in jM)jM.name="jM"
-$desc=$collectedClasses.jM
+this.X0=X0}Gk.builtin$cls="Gk"
+if(!"name" in Gk)Gk.name="Gk"
+$desc=$collectedClasses.Gk
 if($desc instanceof Array)$desc=$desc[1]
-jM.prototype=$desc
-jM.prototype.gvt=function(receiver){return receiver.vt}
-jM.prototype.gvt.$reflectable=1
-jM.prototype.svt=function(receiver,v){return receiver.vt=v}
-jM.prototype.svt.$reflectable=1
+Gk.prototype=$desc
+Gk.prototype.gvt=function(receiver){return receiver.vt}
+Gk.prototype.gvt.$reflectable=1
+Gk.prototype.svt=function(receiver,v){return receiver.vt=v}
+Gk.prototype.svt.$reflectable=1
 function D13(){}D13.builtin$cls="D13"
 if(!"name" in D13)D13.name="D13"
 $desc=$collectedClasses.D13
 if($desc instanceof Array)$desc=$desc[1]
 D13.prototype=$desc
-function DKl(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function GG(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28908,19 +29221,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}DKl.builtin$cls="DKl"
-if(!"name" in DKl)DKl.name="DKl"
-$desc=$collectedClasses.DKl
+this.X0=X0}GG.builtin$cls="GG"
+if(!"name" in GG)GG.name="GG"
+$desc=$collectedClasses.GG
 if($desc instanceof Array)$desc=$desc[1]
-DKl.prototype=$desc
-function mk(Z8,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Z8=Z8
+GG.prototype=$desc
+function yb(Z8,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Z8=Z8
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28928,28 +29241,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}mk.builtin$cls="mk"
-if(!"name" in mk)mk.name="mk"
-$desc=$collectedClasses.mk
+this.X0=X0}yb.builtin$cls="yb"
+if(!"name" in yb)yb.name="yb"
+$desc=$collectedClasses.yb
 if($desc instanceof Array)$desc=$desc[1]
-mk.prototype=$desc
-mk.prototype.gZ8=function(receiver){return receiver.Z8}
-mk.prototype.gZ8.$reflectable=1
-mk.prototype.sZ8=function(receiver,v){return receiver.Z8=v}
-mk.prototype.sZ8.$reflectable=1
+yb.prototype=$desc
+yb.prototype.gZ8=function(receiver){return receiver.Z8}
+yb.prototype.gZ8.$reflectable=1
+yb.prototype.sZ8=function(receiver,v){return receiver.Z8=v}
+yb.prototype.sZ8.$reflectable=1
 function WZq(){}WZq.builtin$cls="WZq"
 if(!"name" in WZq)WZq.name="WZq"
 $desc=$collectedClasses.WZq
 if($desc instanceof Array)$desc=$desc[1]
 WZq.prototype=$desc
-function NM(GQ,J0,Oc,CO,e6,an,Ol,X3,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.GQ=GQ
+function NM(GQ,J0,Oc,CO,e6,an,Ol,X3,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.GQ=GQ
 this.J0=J0
 this.Oc=Oc
 this.CO=CO
@@ -28964,14 +29277,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}NM.builtin$cls="NM"
+this.X0=X0}NM.builtin$cls="NM"
 if(!"name" in NM)NM.name="NM"
 $desc=$collectedClasses.NM
 if($desc instanceof Array)$desc=$desc[1]
@@ -29051,12 +29364,12 @@
 $desc=$collectedClasses.Tm
 if($desc instanceof Array)$desc=$desc[1]
 Tm.prototype=$desc
-function rz(a,Gq){this.a=a
-this.Gq=Gq}rz.builtin$cls="rz"
-if(!"name" in rz)rz.name="rz"
-$desc=$collectedClasses.rz
+function q1(a,Gq){this.a=a
+this.Gq=Gq}q1.builtin$cls="q1"
+if(!"name" in q1)q1.name="q1"
+$desc=$collectedClasses.q1
 if($desc instanceof Array)$desc=$desc[1]
-rz.prototype=$desc
+q1.prototype=$desc
 function CA(a,b){this.a=a
 this.b=b}CA.builtin$cls="CA"
 if(!"name" in CA)CA.name="CA"
@@ -29081,11 +29394,11 @@
 $desc=$collectedClasses.xL
 if($desc instanceof Array)$desc=$desc[1]
 xL.prototype=$desc
-function Ay(){}Ay.builtin$cls="Ay"
-if(!"name" in Ay)Ay.name="Ay"
-$desc=$collectedClasses.Ay
+function As(){}As.builtin$cls="As"
+if(!"name" in As)As.name="As"
+$desc=$collectedClasses.As
 if($desc instanceof Array)$desc=$desc[1]
-Ay.prototype=$desc
+As.prototype=$desc
 function GE(a){this.a=a}GE.builtin$cls="GE"
 if(!"name" in GE)GE.name="GE"
 $desc=$collectedClasses.GE
@@ -29117,8 +29430,12 @@
 $desc=$collectedClasses.GS
 if($desc instanceof Array)$desc=$desc[1]
 GS.prototype=$desc
-function pR(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function pR(qX,AP,fn,tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.qX=qX
+this.AP=AP
+this.fn=fn
+this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29126,19 +29443,38 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}pR.builtin$cls="pR"
+this.X0=X0}pR.builtin$cls="pR"
 if(!"name" in pR)pR.name="pR"
 $desc=$collectedClasses.pR
 if($desc instanceof Array)$desc=$desc[1]
 pR.prototype=$desc
-function hx(Xh,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Xh=Xh
+pR.prototype.gqX=function(receiver){return receiver.qX}
+pR.prototype.gqX.$reflectable=1
+pR.prototype.sqX=function(receiver,v){return receiver.qX=v}
+pR.prototype.sqX.$reflectable=1
+function T5(){}T5.builtin$cls="T5"
+if(!"name" in T5)T5.name="T5"
+$desc=$collectedClasses.T5
+if($desc instanceof Array)$desc=$desc[1]
+T5.prototype=$desc
+function YE(a){this.a=a}YE.builtin$cls="YE"
+if(!"name" in YE)YE.name="YE"
+$desc=$collectedClasses.YE
+if($desc instanceof Array)$desc=$desc[1]
+YE.prototype=$desc
+function we(){}we.builtin$cls="we"
+if(!"name" in we)we.name="we"
+$desc=$collectedClasses.we
+if($desc instanceof Array)$desc=$desc[1]
+we.prototype=$desc
+function hx(Xh,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Xh=Xh
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29146,14 +29482,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}hx.builtin$cls="hx"
+this.X0=X0}hx.builtin$cls="hx"
 if(!"name" in hx)hx.name="hx"
 $desc=$collectedClasses.hx
 if($desc instanceof Array)$desc=$desc[1]
@@ -29167,19 +29503,19 @@
 $desc=$collectedClasses.cda
 if($desc instanceof Array)$desc=$desc[1]
 cda.prototype=$desc
-function u7(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+function u7(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}u7.builtin$cls="u7"
+this.X0=X0}u7.builtin$cls="u7"
 if(!"name" in u7)u7.name="u7"
 $desc=$collectedClasses.u7
 if($desc instanceof Array)$desc=$desc[1]
@@ -29189,10 +29525,32 @@
 $desc=$collectedClasses.fW
 if($desc instanceof Array)$desc=$desc[1]
 fW.prototype=$desc
-function E7(BA,fb,iZ,qY,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.BA=BA
+function qm(Aq,tT,eT,yt,wd,oH,np,AP,fn){this.Aq=Aq
+this.tT=tT
+this.eT=eT
+this.yt=yt
+this.wd=wd
+this.oH=oH
+this.np=np
+this.AP=AP
+this.fn=fn}qm.builtin$cls="qm"
+if(!"name" in qm)qm.name="qm"
+$desc=$collectedClasses.qm
+if($desc instanceof Array)$desc=$desc[1]
+qm.prototype=$desc
+qm.prototype.gAq=function(receiver){return this.Aq}
+qm.prototype.gtT=function(receiver){return this.tT}
+qm.prototype.gtT.$reflectable=1
+function vO(a){this.a=a}vO.builtin$cls="vO"
+if(!"name" in vO)vO.name="vO"
+$desc=$collectedClasses.vO
+if($desc instanceof Array)$desc=$desc[1]
+vO.prototype=$desc
+function E7(BA,fb,qY,qO,Hm,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.BA=BA
 this.fb=fb
-this.iZ=iZ
 this.qY=qY
+this.qO=qO
+this.Hm=Hm
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29200,14 +29558,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}E7.builtin$cls="E7"
+this.X0=X0}E7.builtin$cls="E7"
 if(!"name" in E7)E7.name="E7"
 $desc=$collectedClasses.E7
 if($desc instanceof Array)$desc=$desc[1]
@@ -29218,14 +29576,16 @@
 E7.prototype.sBA.$reflectable=1
 E7.prototype.gfb=function(receiver){return receiver.fb}
 E7.prototype.gfb.$reflectable=1
-E7.prototype.giZ=function(receiver){return receiver.iZ}
-E7.prototype.giZ.$reflectable=1
-E7.prototype.siZ=function(receiver,v){return receiver.iZ=v}
-E7.prototype.siZ.$reflectable=1
 E7.prototype.gqY=function(receiver){return receiver.qY}
 E7.prototype.gqY.$reflectable=1
 E7.prototype.sqY=function(receiver,v){return receiver.qY=v}
 E7.prototype.sqY.$reflectable=1
+E7.prototype.gqO=function(receiver){return receiver.qO}
+E7.prototype.gqO.$reflectable=1
+E7.prototype.gHm=function(receiver){return receiver.Hm}
+E7.prototype.gHm.$reflectable=1
+E7.prototype.sHm=function(receiver,v){return receiver.Hm=v}
+E7.prototype.sHm.$reflectable=1
 function waa(){}waa.builtin$cls="waa"
 if(!"name" in waa)waa.name="waa"
 $desc=$collectedClasses.waa
@@ -29242,7 +29602,7 @@
 $desc=$collectedClasses.EL
 if($desc instanceof Array)$desc=$desc[1]
 EL.prototype=$desc
-function St(Pw,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Pw=Pw
+function St(Pw,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Pw=Pw
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29250,14 +29610,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}St.builtin$cls="St"
+this.X0=X0}St.builtin$cls="St"
 if(!"name" in St)St.name="St"
 $desc=$collectedClasses.St
 if($desc instanceof Array)$desc=$desc[1]
@@ -29271,7 +29631,7 @@
 $desc=$collectedClasses.V0
 if($desc instanceof Array)$desc=$desc[1]
 V0.prototype=$desc
-function vj(eb,kf,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eb=eb
+function vj(eb,kf,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.eb=eb
 this.kf=kf
 this.AP=AP
 this.fn=fn
@@ -29280,14 +29640,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}vj.builtin$cls="vj"
+this.X0=X0}vj.builtin$cls="vj"
 if(!"name" in vj)vj.name="vj"
 $desc=$collectedClasses.vj
 if($desc instanceof Array)$desc=$desc[1]
@@ -29305,8 +29665,9 @@
 $desc=$collectedClasses.V4
 if($desc instanceof Array)$desc=$desc[1]
 V4.prototype=$desc
-function LU(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function LU(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29314,19 +29675,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}LU.builtin$cls="LU"
+this.X0=X0}LU.builtin$cls="LU"
 if(!"name" in LU)LU.name="LU"
 $desc=$collectedClasses.LU
 if($desc instanceof Array)$desc=$desc[1]
 LU.prototype=$desc
-function CX(N7,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.N7=N7
+function T2(N7,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.N7=N7
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29334,27 +29695,27 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}CX.builtin$cls="CX"
-if(!"name" in CX)CX.name="CX"
-$desc=$collectedClasses.CX
+this.X0=X0}T2.builtin$cls="T2"
+if(!"name" in T2)T2.name="T2"
+$desc=$collectedClasses.T2
 if($desc instanceof Array)$desc=$desc[1]
-CX.prototype=$desc
-CX.prototype.gN7=function(receiver){return receiver.N7}
-CX.prototype.gN7.$reflectable=1
-CX.prototype.sN7=function(receiver,v){return receiver.N7=v}
-CX.prototype.sN7.$reflectable=1
-function V6(){}V6.builtin$cls="V6"
-if(!"name" in V6)V6.name="V6"
-$desc=$collectedClasses.V6
+T2.prototype=$desc
+T2.prototype.gN7=function(receiver){return receiver.N7}
+T2.prototype.gN7.$reflectable=1
+T2.prototype.sN7=function(receiver,v){return receiver.N7=v}
+T2.prototype.sN7.$reflectable=1
+function V10(){}V10.builtin$cls="V10"
+if(!"name" in V10)V10.name="V10"
+$desc=$collectedClasses.V10
 if($desc instanceof Array)$desc=$desc[1]
-V6.prototype=$desc
+V10.prototype=$desc
 function TJ(oc,eT,n2,Cj,wd,Gs){this.oc=oc
 this.eT=eT
 this.n2=n2
@@ -29408,20 +29769,20 @@
 $desc=$collectedClasses.Lb
 if($desc instanceof Array)$desc=$desc[1]
 Lb.prototype=$desc
-function PF(Gj,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Gj=Gj
+function PF(Gj,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Gj=Gj
 this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}PF.builtin$cls="PF"
+this.X0=X0}PF.builtin$cls="PF"
 if(!"name" in PF)PF.name="PF"
 $desc=$collectedClasses.PF
 if($desc instanceof Array)$desc=$desc[1]
@@ -29447,34 +29808,34 @@
 if($desc instanceof Array)$desc=$desc[1]
 jA.prototype=$desc
 jA.prototype.goc=function(receiver){return this.oc}
-function Jo(){}Jo.builtin$cls="Jo"
-if(!"name" in Jo)Jo.name="Jo"
-$desc=$collectedClasses.Jo
+function PO(){}PO.builtin$cls="PO"
+if(!"name" in PO)PO.name="PO"
+$desc=$collectedClasses.PO
 if($desc instanceof Array)$desc=$desc[1]
-Jo.prototype=$desc
+PO.prototype=$desc
 function c5(){}c5.builtin$cls="c5"
 if(!"name" in c5)c5.name="c5"
 $desc=$collectedClasses.c5
 if($desc instanceof Array)$desc=$desc[1]
 c5.prototype=$desc
-function qT(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+function qT(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}qT.builtin$cls="qT"
+this.X0=X0}qT.builtin$cls="qT"
 if(!"name" in qT)qT.name="qT"
 $desc=$collectedClasses.qT
 if($desc instanceof Array)$desc=$desc[1]
 qT.prototype=$desc
-function Xd(rK,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.rK=rK
+function Xd(rK,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.rK=rK
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29482,14 +29843,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Xd.builtin$cls="Xd"
+this.X0=X0}Xd.builtin$cls="Xd"
 if(!"name" in Xd)Xd.name="Xd"
 $desc=$collectedClasses.Xd
 if($desc instanceof Array)$desc=$desc[1]
@@ -29498,13 +29859,13 @@
 Xd.prototype.grK.$reflectable=1
 Xd.prototype.srK=function(receiver,v){return receiver.rK=v}
 Xd.prototype.srK.$reflectable=1
-function V10(){}V10.builtin$cls="V10"
-if(!"name" in V10)V10.name="V10"
-$desc=$collectedClasses.V10
+function V11(){}V11.builtin$cls="V11"
+if(!"name" in V11)V11.name="V11"
+$desc=$collectedClasses.V11
 if($desc instanceof Array)$desc=$desc[1]
-V10.prototype=$desc
-function mL(Z6,lw,nI,AP,fn){this.Z6=Z6
-this.lw=lw
+V11.prototype=$desc
+function mL(Z6,DF,nI,AP,fn){this.Z6=Z6
+this.DF=DF
 this.nI=nI
 this.AP=AP
 this.fn=fn}mL.builtin$cls="mL"
@@ -29514,8 +29875,8 @@
 mL.prototype=$desc
 mL.prototype.gZ6=function(){return this.Z6}
 mL.prototype.gZ6.$reflectable=1
-mL.prototype.glw=function(){return this.lw}
-mL.prototype.glw.$reflectable=1
+mL.prototype.gDF=function(){return this.DF}
+mL.prototype.gDF.$reflectable=1
 mL.prototype.gnI=function(){return this.nI}
 mL.prototype.gnI.$reflectable=1
 function Kf(oV){this.oV=oV}Kf.builtin$cls="Kf"
@@ -29531,15 +29892,15 @@
 if($desc instanceof Array)$desc=$desc[1]
 qu.prototype=$desc
 qu.prototype.gbG=function(receiver){return this.bG}
-function bv(WP,XR,Z0,md,mY,F3,Gg,LE,a3,mU,mM,Td,AP,fn){this.WP=WP
+function bv(WP,XR,Z0,md,mY,F3,rU,LE,iP,mU,mM,Td,AP,fn){this.WP=WP
 this.XR=XR
 this.Z0=Z0
 this.md=md
 this.mY=mY
 this.F3=F3
-this.Gg=Gg
+this.rU=rU
 this.LE=LE
-this.a3=a3
+this.iP=iP
 this.mU=mU
 this.mM=mM
 this.Td=Td
@@ -29570,17 +29931,17 @@
 $desc=$collectedClasses.TI
 if($desc instanceof Array)$desc=$desc[1]
 TI.prototype=$desc
-function pt(XT,i2,AP,fn){this.XT=XT
+function yU(XT,i2,AP,fn){this.XT=XT
 this.i2=i2
 this.AP=AP
-this.fn=fn}pt.builtin$cls="pt"
-if(!"name" in pt)pt.name="pt"
-$desc=$collectedClasses.pt
+this.fn=fn}yU.builtin$cls="yU"
+if(!"name" in yU)yU.name="yU"
+$desc=$collectedClasses.yU
 if($desc instanceof Array)$desc=$desc[1]
-pt.prototype=$desc
-pt.prototype.sXT=function(v){return this.XT=v}
-pt.prototype.gi2=function(){return this.i2}
-pt.prototype.gi2.$reflectable=1
+yU.prototype=$desc
+yU.prototype.sXT=function(v){return this.XT=v}
+yU.prototype.gi2=function(){return this.i2}
+yU.prototype.gi2.$reflectable=1
 function Ub(a){this.a=a}Ub.builtin$cls="Ub"
 if(!"name" in Ub)Ub.name="Ub"
 $desc=$collectedClasses.Ub
@@ -29618,11 +29979,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 dZ.prototype=$desc
 dZ.prototype.sXT=function(v){return this.XT=v}
-function us(a){this.a=a}us.builtin$cls="us"
-if(!"name" in us)us.name="us"
-$desc=$collectedClasses.us
+function Qe(a){this.a=a}Qe.builtin$cls="Qe"
+if(!"name" in Qe)Qe.name="Qe"
+$desc=$collectedClasses.Qe
 if($desc instanceof Array)$desc=$desc[1]
-us.prototype=$desc
+Qe.prototype=$desc
 function DP(Yu,m7,L4,Fv,ZZ,AP,fn){this.Yu=Yu
 this.m7=m7
 this.L4=L4
@@ -29645,25 +30006,35 @@
 $desc=$collectedClasses.WAE
 if($desc instanceof Array)$desc=$desc[1]
 WAE.prototype=$desc
-function N8(Yu,a0){this.Yu=Yu
-this.a0=a0}N8.builtin$cls="N8"
+function N8(Yu,z4,Iw){this.Yu=Yu
+this.z4=z4
+this.Iw=Iw}N8.builtin$cls="N8"
 if(!"name" in N8)N8.name="N8"
 $desc=$collectedClasses.N8
 if($desc instanceof Array)$desc=$desc[1]
 N8.prototype=$desc
 N8.prototype.gYu=function(){return this.Yu}
-N8.prototype.ga0=function(){return this.a0}
-function kx(fY,vg,Mb,a0,fF,Du,va,Qo,kY,mY,Tl,AP,fn){this.fY=fY
+function Vi(tT,Ou){this.tT=tT
+this.Ou=Ou}Vi.builtin$cls="Vi"
+if(!"name" in Vi)Vi.name="Vi"
+$desc=$collectedClasses.Vi
+if($desc instanceof Array)$desc=$desc[1]
+Vi.prototype=$desc
+Vi.prototype.gtT=function(receiver){return this.tT}
+Vi.prototype.gOu=function(){return this.Ou}
+function kx(fY,vg,Mb,a0,VS,hw,fF,Du,va,Qo,uP,mY,B0,AP,fn){this.fY=fY
 this.vg=vg
 this.Mb=Mb
 this.a0=a0
+this.VS=VS
+this.hw=hw
 this.fF=fF
 this.Du=Du
 this.va=va
 this.Qo=Qo
-this.kY=kY
+this.uP=uP
 this.mY=mY
-this.Tl=Tl
+this.B0=B0
 this.AP=AP
 this.fn=fn}kx.builtin$cls="kx"
 if(!"name" in kx)kx.name="kx"
@@ -29672,13 +30043,18 @@
 kx.prototype=$desc
 kx.prototype.gfY=function(receiver){return this.fY}
 kx.prototype.ga0=function(){return this.a0}
+kx.prototype.gVS=function(){return this.VS}
 kx.prototype.gfF=function(){return this.fF}
-kx.prototype.sfF=function(v){return this.fF=v}
 kx.prototype.gDu=function(){return this.Du}
-kx.prototype.sDu=function(v){return this.Du=v}
 kx.prototype.gva=function(){return this.va}
 kx.prototype.gva.$reflectable=1
-function CM(Aq,hV){this.Aq=Aq
+function fx(){}fx.builtin$cls="fx"
+if(!"name" in fx)fx.name="fx"
+$desc=$collectedClasses.fx
+if($desc instanceof Array)$desc=$desc[1]
+fx.prototype=$desc
+function CM(Aq,jV,hV){this.Aq=Aq
+this.jV=jV
 this.hV=hV}CM.builtin$cls="CM"
 if(!"name" in CM)CM.name="CM"
 $desc=$collectedClasses.CM
@@ -29691,26 +30067,11 @@
 $desc=$collectedClasses.xn
 if($desc instanceof Array)$desc=$desc[1]
 xn.prototype=$desc
-function ct(a){this.a=a}ct.builtin$cls="ct"
-if(!"name" in ct)ct.name="ct"
-$desc=$collectedClasses.ct
-if($desc instanceof Array)$desc=$desc[1]
-ct.prototype=$desc
-function hM(a){this.a=a}hM.builtin$cls="hM"
-if(!"name" in hM)hM.name="hM"
-$desc=$collectedClasses.hM
-if($desc instanceof Array)$desc=$desc[1]
-hM.prototype=$desc
 function vu(){}vu.builtin$cls="vu"
 if(!"name" in vu)vu.name="vu"
 $desc=$collectedClasses.vu
 if($desc instanceof Array)$desc=$desc[1]
 vu.prototype=$desc
-function Ja(){}Ja.builtin$cls="Ja"
-if(!"name" in Ja)Ja.name="Ja"
-$desc=$collectedClasses.Ja
-if($desc instanceof Array)$desc=$desc[1]
-Ja.prototype=$desc
 function c2(Rd,eB,P2,AP,fn){this.Rd=Rd
 this.eB=eB
 this.P2=P2
@@ -29720,7 +30081,7 @@
 $desc=$collectedClasses.c2
 if($desc instanceof Array)$desc=$desc[1]
 c2.prototype=$desc
-c2.prototype.gRd=function(){return this.Rd}
+c2.prototype.gRd=function(receiver){return this.Rd}
 c2.prototype.gRd.$reflectable=1
 function rj(W6,xN,Hz,Sw,UK,AP,fn){this.W6=W6
 this.xN=xN
@@ -29735,14 +30096,14 @@
 rj.prototype=$desc
 rj.prototype.gSw=function(){return this.Sw}
 rj.prototype.gSw.$reflectable=1
-function R2(XT,e0){this.XT=XT
-this.e0=e0}R2.builtin$cls="R2"
-if(!"name" in R2)R2.name="R2"
-$desc=$collectedClasses.R2
+function Nu(XT,e0){this.XT=XT
+this.e0=e0}Nu.builtin$cls="Nu"
+if(!"name" in Nu)Nu.name="Nu"
+$desc=$collectedClasses.Nu
 if($desc instanceof Array)$desc=$desc[1]
-R2.prototype=$desc
-R2.prototype.sXT=function(v){return this.XT=v}
-R2.prototype.se0=function(v){return this.e0=v}
+Nu.prototype=$desc
+Nu.prototype.sXT=function(v){return this.XT=v}
+Nu.prototype.se0=function(v){return this.e0=v}
 function Q4(a,b,c){this.a=a
 this.b=b
 this.c=c}Q4.builtin$cls="Q4"
@@ -29773,16 +30134,16 @@
 $desc=$collectedClasses.Q2
 if($desc instanceof Array)$desc=$desc[1]
 Q2.prototype=$desc
-function tb(XT,e0,SI,Tj,AP,fn){this.XT=XT
+function r1(XT,e0,SI,Tj,AP,fn){this.XT=XT
 this.e0=e0
 this.SI=SI
 this.Tj=Tj
 this.AP=AP
-this.fn=fn}tb.builtin$cls="tb"
-if(!"name" in tb)tb.name="tb"
-$desc=$collectedClasses.tb
+this.fn=fn}r1.builtin$cls="r1"
+if(!"name" in r1)r1.name="r1"
+$desc=$collectedClasses.r1
 if($desc instanceof Array)$desc=$desc[1]
-tb.prototype=$desc
+r1.prototype=$desc
 function Rb(eA,Wj,XT,e0,SI,Tj,AP,fn){this.eA=eA
 this.Wj=Wj
 this.XT=XT
@@ -29795,7 +30156,32 @@
 $desc=$collectedClasses.Rb
 if($desc instanceof Array)$desc=$desc[1]
 Rb.prototype=$desc
-function F1(k5,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.k5=k5
+function Y2(eT,yt,wd,oH){this.eT=eT
+this.yt=yt
+this.wd=wd
+this.oH=oH}Y2.builtin$cls="Y2"
+if(!"name" in Y2)Y2.name="Y2"
+$desc=$collectedClasses.Y2
+if($desc instanceof Array)$desc=$desc[1]
+Y2.prototype=$desc
+Y2.prototype.geT=function(receiver){return this.eT}
+Y2.prototype.gyt=function(){return this.yt}
+Y2.prototype.gyt.$reflectable=1
+Y2.prototype.gwd=function(receiver){return this.wd}
+Y2.prototype.gwd.$reflectable=1
+Y2.prototype.goH=function(){return this.oH}
+Y2.prototype.goH.$reflectable=1
+function XN(JL,WT,AP,fn){this.JL=JL
+this.WT=WT
+this.AP=AP
+this.fn=fn}XN.builtin$cls="XN"
+if(!"name" in XN)XN.name="XN"
+$desc=$collectedClasses.XN
+if($desc instanceof Array)$desc=$desc[1]
+XN.prototype=$desc
+XN.prototype.gWT=function(receiver){return this.WT}
+XN.prototype.gWT.$reflectable=1
+function F1(k5,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.k5=k5
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29803,14 +30189,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}F1.builtin$cls="F1"
+this.X0=X0}F1.builtin$cls="F1"
 if(!"name" in F1)F1.name="F1"
 $desc=$collectedClasses.F1
 if($desc instanceof Array)$desc=$desc[1]
@@ -29819,24 +30205,24 @@
 F1.prototype.gk5.$reflectable=1
 F1.prototype.sk5=function(receiver,v){return receiver.k5=v}
 F1.prototype.sk5.$reflectable=1
-function V11(){}V11.builtin$cls="V11"
-if(!"name" in V11)V11.name="V11"
-$desc=$collectedClasses.V11
+function V12(){}V12.builtin$cls="V12"
+if(!"name" in V12)V12.name="V12"
+$desc=$collectedClasses.V12
 if($desc instanceof Array)$desc=$desc[1]
-V11.prototype=$desc
-function uL(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+V12.prototype=$desc
+function uL(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}uL.builtin$cls="uL"
+this.X0=X0}uL.builtin$cls="uL"
 if(!"name" in uL)uL.name="uL"
 $desc=$collectedClasses.uL
 if($desc instanceof Array)$desc=$desc[1]
@@ -29899,11 +30285,11 @@
 $desc=$collectedClasses.b5
 if($desc instanceof Array)$desc=$desc[1]
 b5.prototype=$desc
-function u3(b){this.b=b}u3.builtin$cls="u3"
-if(!"name" in u3)u3.name="u3"
-$desc=$collectedClasses.u3
+function zI(b){this.b=b}zI.builtin$cls="zI"
+if(!"name" in zI)zI.name="zI"
+$desc=$collectedClasses.zI
 if($desc instanceof Array)$desc=$desc[1]
-u3.prototype=$desc
+zI.prototype=$desc
 function Zb(c,d,e,f){this.c=c
 this.d=d
 this.e=e
@@ -29951,12 +30337,12 @@
 $desc=$collectedClasses.d3
 if($desc instanceof Array)$desc=$desc[1]
 d3.prototype=$desc
-function X6(a,b){this.a=a
-this.b=b}X6.builtin$cls="X6"
-if(!"name" in X6)X6.name="X6"
-$desc=$collectedClasses.X6
+function lS(a,b){this.a=a
+this.b=b}lS.builtin$cls="lS"
+if(!"name" in lS)lS.name="lS"
+$desc=$collectedClasses.lS
 if($desc instanceof Array)$desc=$desc[1]
-X6.prototype=$desc
+lS.prototype=$desc
 function xh(L1,AP,fn){this.L1=L1
 this.AP=AP
 this.fn=fn}xh.builtin$cls="xh"
@@ -29973,16 +30359,16 @@
 $desc=$collectedClasses.wn
 if($desc instanceof Array)$desc=$desc[1]
 wn.prototype=$desc
-function uF(){}uF.builtin$cls="uF"
-if(!"name" in uF)uF.name="uF"
-$desc=$collectedClasses.uF
+function Ay(){}Ay.builtin$cls="Ay"
+if(!"name" in Ay)Ay.name="Ay"
+$desc=$collectedClasses.Ay
 if($desc instanceof Array)$desc=$desc[1]
-uF.prototype=$desc
-function cj(a){this.a=a}cj.builtin$cls="cj"
-if(!"name" in cj)cj.name="cj"
-$desc=$collectedClasses.cj
+Ay.prototype=$desc
+function Bj(a){this.a=a}Bj.builtin$cls="Bj"
+if(!"name" in Bj)Bj.name="Bj"
+$desc=$collectedClasses.Bj
 if($desc instanceof Array)$desc=$desc[1]
-cj.prototype=$desc
+Bj.prototype=$desc
 function HA(G3,jL,zZ,JD,dr){this.G3=G3
 this.jL=jL
 this.zZ=zZ
@@ -30053,96 +30439,6 @@
 $desc=$collectedClasses.km
 if($desc instanceof Array)$desc=$desc[1]
 km.prototype=$desc
-function lI(S,l){this.S=S
-this.l=l}lI.builtin$cls="lI"
-if(!"name" in lI)lI.name="lI"
-$desc=$collectedClasses.lI
-if($desc instanceof Array)$desc=$desc[1]
-lI.prototype=$desc
-function u2(){}u2.builtin$cls="u2"
-if(!"name" in u2)u2.name="u2"
-$desc=$collectedClasses.u2
-if($desc instanceof Array)$desc=$desc[1]
-u2.prototype=$desc
-function q7(){}q7.builtin$cls="q7"
-if(!"name" in q7)q7.name="q7"
-$desc=$collectedClasses.q7
-if($desc instanceof Array)$desc=$desc[1]
-q7.prototype=$desc
-function Qt(){}Qt.builtin$cls="Qt"
-if(!"name" in Qt)Qt.name="Qt"
-$desc=$collectedClasses.Qt
-if($desc instanceof Array)$desc=$desc[1]
-Qt.prototype=$desc
-function No(){}No.builtin$cls="No"
-if(!"name" in No)No.name="No"
-$desc=$collectedClasses.No
-if($desc instanceof Array)$desc=$desc[1]
-No.prototype=$desc
-function v5(S,SF,aA,wZ,ZB){this.S=S
-this.SF=SF
-this.aA=aA
-this.wZ=wZ
-this.ZB=ZB}v5.builtin$cls="v5"
-if(!"name" in v5)v5.name="v5"
-$desc=$collectedClasses.v5
-if($desc instanceof Array)$desc=$desc[1]
-v5.prototype=$desc
-function OO(TL){this.TL=TL}OO.builtin$cls="OO"
-if(!"name" in OO)OO.name="OO"
-$desc=$collectedClasses.OO
-if($desc instanceof Array)$desc=$desc[1]
-OO.prototype=$desc
-OO.prototype.gTL=function(){return this.TL}
-function OF(oc,mI,DF,nK,Ew,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.TL=TL}OF.builtin$cls="OF"
-if(!"name" in OF)OF.name="OF"
-$desc=$collectedClasses.OF
-if($desc instanceof Array)$desc=$desc[1]
-OF.prototype=$desc
-OF.prototype.goc=function(receiver){return this.oc}
-OF.prototype.gmI=function(){return this.mI}
-OF.prototype.gDF=function(){return this.DF}
-OF.prototype.gnK=function(){return this.nK}
-OF.prototype.gEw=function(){return this.Ew}
-function rM(oc,mI,DF,nK,Ew,ir,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.ir=ir
-this.TL=TL}rM.builtin$cls="rM"
-if(!"name" in rM)rM.name="rM"
-$desc=$collectedClasses.rM
-if($desc instanceof Array)$desc=$desc[1]
-rM.prototype=$desc
-rM.prototype.goc=function(receiver){return this.oc}
-rM.prototype.gmI=function(){return this.mI}
-rM.prototype.gDF=function(){return this.DF}
-rM.prototype.gnK=function(){return this.nK}
-rM.prototype.gEw=function(){return this.Ew}
-rM.prototype.gTL=function(){return this.ir}
-function IV(oc,mI,DF,nK,Ew,r9,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.r9=r9
-this.TL=TL}IV.builtin$cls="IV"
-if(!"name" in IV)IV.name="IV"
-$desc=$collectedClasses.IV
-if($desc instanceof Array)$desc=$desc[1]
-IV.prototype=$desc
-IV.prototype.goc=function(receiver){return this.oc}
-IV.prototype.gmI=function(){return this.mI}
-IV.prototype.gDF=function(){return this.DF}
-IV.prototype.gnK=function(){return this.nK}
-IV.prototype.gEw=function(){return this.Ew}
-IV.prototype.gTL=function(){return this.r9}
 function Zj(){}Zj.builtin$cls="Zj"
 if(!"name" in Zj)Zj.name="Zj"
 $desc=$collectedClasses.Zj
@@ -30199,27 +30495,27 @@
 $desc=$collectedClasses.MX
 if($desc instanceof Array)$desc=$desc[1]
 MX.prototype=$desc
-function w11(){}w11.builtin$cls="w11"
-if(!"name" in w11)w11.name="w11"
-$desc=$collectedClasses.w11
+function w9(){}w9.builtin$cls="w9"
+if(!"name" in w9)w9.name="w9"
+$desc=$collectedClasses.w9
 if($desc instanceof Array)$desc=$desc[1]
-w11.prototype=$desc
-function ppY(a){this.a=a}ppY.builtin$cls="ppY"
-if(!"name" in ppY)ppY.name="ppY"
-$desc=$collectedClasses.ppY
+w9.prototype=$desc
+function r3y(a){this.a=a}r3y.builtin$cls="r3y"
+if(!"name" in r3y)r3y.name="r3y"
+$desc=$collectedClasses.r3y
 if($desc instanceof Array)$desc=$desc[1]
-ppY.prototype=$desc
+r3y.prototype=$desc
 function yL(){}yL.builtin$cls="yL"
 if(!"name" in yL)yL.name="yL"
 $desc=$collectedClasses.yL
 if($desc instanceof Array)$desc=$desc[1]
 yL.prototype=$desc
-function zs(ZQ){this.ZQ=ZQ}zs.builtin$cls="zs"
+function zs(X0){this.X0=X0}zs.builtin$cls="zs"
 if(!"name" in zs)zs.name="zs"
 $desc=$collectedClasses.zs
 if($desc instanceof Array)$desc=$desc[1]
 zs.prototype=$desc
-zs.prototype.gKM=function(receiver){return receiver.ZQ}
+zs.prototype.gKM=function(receiver){return receiver.X0}
 zs.prototype.gKM.$reflectable=1
 function WC(a){this.a=a}WC.builtin$cls="WC"
 if(!"name" in WC)WC.name="WC"
@@ -30303,41 +30599,41 @@
 $desc=$collectedClasses.Bf
 if($desc instanceof Array)$desc=$desc[1]
 Bf.prototype=$desc
-function ir(AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.AP=AP
+function ir(AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}ir.builtin$cls="ir"
+this.X0=X0}ir.builtin$cls="ir"
 if(!"name" in ir)ir.name="ir"
 $desc=$collectedClasses.ir
 if($desc instanceof Array)$desc=$desc[1]
 ir.prototype=$desc
-function Sa(ZQ){this.ZQ=ZQ}Sa.builtin$cls="Sa"
-if(!"name" in Sa)Sa.name="Sa"
-$desc=$collectedClasses.Sa
+function jpR(X0){this.X0=X0}jpR.builtin$cls="jpR"
+if(!"name" in jpR)jpR.name="jpR"
+$desc=$collectedClasses.jpR
 if($desc instanceof Array)$desc=$desc[1]
-Sa.prototype=$desc
-zs.prototype.gKM=function(receiver){return receiver.ZQ}
+jpR.prototype=$desc
+zs.prototype.gKM=function(receiver){return receiver.X0}
 zs.prototype.gKM.$reflectable=1
-function Ao(){}Ao.builtin$cls="Ao"
-if(!"name" in Ao)Ao.name="Ao"
-$desc=$collectedClasses.Ao
+function GN(){}GN.builtin$cls="GN"
+if(!"name" in GN)GN.name="GN"
+$desc=$collectedClasses.GN
 if($desc instanceof Array)$desc=$desc[1]
-Ao.prototype=$desc
-function k8(jL,zZ){this.jL=jL
-this.zZ=zZ}k8.builtin$cls="k8"
-if(!"name" in k8)k8.name="k8"
-$desc=$collectedClasses.k8
+GN.prototype=$desc
+function bS(jL,zZ){this.jL=jL
+this.zZ=zZ}bS.builtin$cls="bS"
+if(!"name" in bS)bS.name="bS"
+$desc=$collectedClasses.bS
 if($desc instanceof Array)$desc=$desc[1]
-k8.prototype=$desc
-k8.prototype.gjL=function(receiver){return this.jL}
-k8.prototype.gzZ=function(receiver){return this.zZ}
-k8.prototype.szZ=function(receiver,v){return this.zZ=v}
+bS.prototype=$desc
+bS.prototype.gjL=function(receiver){return this.jL}
+bS.prototype.gzZ=function(receiver){return this.zZ}
+bS.prototype.szZ=function(receiver,v){return this.zZ=v}
 function HJ(nF){this.nF=nF}HJ.builtin$cls="HJ"
 if(!"name" in HJ)HJ.name="HJ"
 $desc=$collectedClasses.HJ
@@ -30399,26 +30695,26 @@
 $desc=$collectedClasses.pp
 if($desc instanceof Array)$desc=$desc[1]
 pp.prototype=$desc
-function Nq(){}Nq.builtin$cls="Nq"
-if(!"name" in Nq)Nq.name="Nq"
-$desc=$collectedClasses.Nq
-if($desc instanceof Array)$desc=$desc[1]
-Nq.prototype=$desc
 function nl(){}nl.builtin$cls="nl"
 if(!"name" in nl)nl.name="nl"
 $desc=$collectedClasses.nl
 if($desc instanceof Array)$desc=$desc[1]
 nl.prototype=$desc
-function mf(a){this.a=a}mf.builtin$cls="mf"
-if(!"name" in mf)mf.name="mf"
-$desc=$collectedClasses.mf
-if($desc instanceof Array)$desc=$desc[1]
-mf.prototype=$desc
 function ik(){}ik.builtin$cls="ik"
 if(!"name" in ik)ik.name="ik"
 $desc=$collectedClasses.ik
 if($desc instanceof Array)$desc=$desc[1]
 ik.prototype=$desc
+function mf(a){this.a=a}mf.builtin$cls="mf"
+if(!"name" in mf)mf.name="mf"
+$desc=$collectedClasses.mf
+if($desc instanceof Array)$desc=$desc[1]
+mf.prototype=$desc
+function LfS(){}LfS.builtin$cls="LfS"
+if(!"name" in LfS)LfS.name="LfS"
+$desc=$collectedClasses.LfS
+if($desc instanceof Array)$desc=$desc[1]
+LfS.prototype=$desc
 function HK(b){this.b=b}HK.builtin$cls="HK"
 if(!"name" in HK)HK.name="HK"
 $desc=$collectedClasses.HK
@@ -30446,11 +30742,11 @@
 $desc=$collectedClasses.Xy
 if($desc instanceof Array)$desc=$desc[1]
 Xy.prototype=$desc
-function uK(a){this.a=a}uK.builtin$cls="uK"
-if(!"name" in uK)uK.name="uK"
-$desc=$collectedClasses.uK
+function G0(a){this.a=a}G0.builtin$cls="G0"
+if(!"name" in G0)G0.name="G0"
+$desc=$collectedClasses.G0
 if($desc instanceof Array)$desc=$desc[1]
-uK.prototype=$desc
+G0.prototype=$desc
 function mY(a9,Cu,uI,Y7,AP,fn){this.a9=a9
 this.Cu=Cu
 this.uI=uI
@@ -30480,12 +30776,22 @@
 $desc=$collectedClasses.XF
 if($desc instanceof Array)$desc=$desc[1]
 XF.prototype=$desc
-function iH(a,b){this.a=a
-this.b=b}iH.builtin$cls="iH"
-if(!"name" in iH)iH.name="iH"
-$desc=$collectedClasses.iH
+function bX(a,b){this.a=a
+this.b=b}bX.builtin$cls="bX"
+if(!"name" in bX)bX.name="bX"
+$desc=$collectedClasses.bX
 if($desc instanceof Array)$desc=$desc[1]
-iH.prototype=$desc
+bX.prototype=$desc
+function lP(){}lP.builtin$cls="lP"
+if(!"name" in lP)lP.name="lP"
+$desc=$collectedClasses.lP
+if($desc instanceof Array)$desc=$desc[1]
+lP.prototype=$desc
+function Uf(){}Uf.builtin$cls="Uf"
+if(!"name" in Uf)Uf.name="Uf"
+$desc=$collectedClasses.Uf
+if($desc instanceof Array)$desc=$desc[1]
+Uf.prototype=$desc
 function Ra(){}Ra.builtin$cls="Ra"
 if(!"name" in Ra)Ra.name="Ra"
 $desc=$collectedClasses.Ra
@@ -30556,16 +30862,6 @@
 $desc=$collectedClasses.w7
 if($desc instanceof Array)$desc=$desc[1]
 w7.prototype=$desc
-function w9(){}w9.builtin$cls="w9"
-if(!"name" in w9)w9.name="w9"
-$desc=$collectedClasses.w9
-if($desc instanceof Array)$desc=$desc[1]
-w9.prototype=$desc
-function w10(){}w10.builtin$cls="w10"
-if(!"name" in w10)w10.name="w10"
-$desc=$collectedClasses.w10
-if($desc instanceof Array)$desc=$desc[1]
-w10.prototype=$desc
 function c4(a){this.a=a}c4.builtin$cls="c4"
 if(!"name" in c4)c4.name="c4"
 $desc=$collectedClasses.c4
@@ -30580,14 +30876,14 @@
 if($desc instanceof Array)$desc=$desc[1]
 z6.prototype=$desc
 z6.prototype.geT=function(receiver){return this.eT}
-function dE(bO,Lv){this.bO=bO
-this.Lv=Lv}dE.builtin$cls="dE"
-if(!"name" in dE)dE.name="dE"
-$desc=$collectedClasses.dE
+function Mb(bO,Lv){this.bO=bO
+this.Lv=Lv}Mb.builtin$cls="Mb"
+if(!"name" in Mb)Mb.name="Mb"
+$desc=$collectedClasses.Mb
 if($desc instanceof Array)$desc=$desc[1]
-dE.prototype=$desc
-dE.prototype.sbO=function(v){return this.bO=v}
-dE.prototype.gLv=function(){return this.Lv}
+Mb.prototype=$desc
+Mb.prototype.sbO=function(v){return this.bO=v}
+Mb.prototype.gLv=function(){return this.Lv}
 function Ed(Jd){this.Jd=Jd}Ed.builtin$cls="Ed"
 if(!"name" in Ed)Ed.name="Ed"
 $desc=$collectedClasses.Ed
@@ -30643,19 +30939,19 @@
 $desc=$collectedClasses.ID
 if($desc instanceof Array)$desc=$desc[1]
 ID.prototype=$desc
-function jV(G3,v4,KL,bO,tj,Lv,k6){this.G3=G3
+function qR(G3,v4,KL,bO,tj,Lv,k6){this.G3=G3
 this.v4=v4
 this.KL=KL
 this.bO=bO
 this.tj=tj
 this.Lv=Lv
-this.k6=k6}jV.builtin$cls="jV"
-if(!"name" in jV)jV.name="jV"
-$desc=$collectedClasses.jV
+this.k6=k6}qR.builtin$cls="qR"
+if(!"name" in qR)qR.name="qR"
+$desc=$collectedClasses.qR
 if($desc instanceof Array)$desc=$desc[1]
-jV.prototype=$desc
-jV.prototype.gG3=function(receiver){return this.G3}
-jV.prototype.gv4=function(){return this.v4}
+qR.prototype=$desc
+qR.prototype.gG3=function(receiver){return this.G3}
+qR.prototype.gv4=function(){return this.v4}
 function ek(KL,bO,tj,Lv,k6){this.KL=KL
 this.bO=bO
 this.tj=tj
@@ -30677,17 +30973,17 @@
 $desc=$collectedClasses.Xm
 if($desc instanceof Array)$desc=$desc[1]
 Xm.prototype=$desc
-function Jy(wz,KL,bO,tj,Lv,k6){this.wz=wz
+function mv(wz,KL,bO,tj,Lv,k6){this.wz=wz
 this.KL=KL
 this.bO=bO
 this.tj=tj
 this.Lv=Lv
-this.k6=k6}Jy.builtin$cls="Jy"
-if(!"name" in Jy)Jy.name="Jy"
-$desc=$collectedClasses.Jy
+this.k6=k6}mv.builtin$cls="mv"
+if(!"name" in mv)mv.name="mv"
+$desc=$collectedClasses.mv
 if($desc instanceof Array)$desc=$desc[1]
-Jy.prototype=$desc
-Jy.prototype.gwz=function(){return this.wz}
+mv.prototype=$desc
+mv.prototype.gwz=function(){return this.wz}
 function mG(Bb,T8,KL,bO,tj,Lv,k6){this.Bb=Bb
 this.T8=T8
 this.KL=KL
@@ -30699,8 +30995,8 @@
 $desc=$collectedClasses.mG
 if($desc instanceof Array)$desc=$desc[1]
 mG.prototype=$desc
-mG.prototype.gBb=function(receiver){return this.Bb}
-mG.prototype.gT8=function(receiver){return this.T8}
+mG.prototype.gBb=function(){return this.Bb}
+mG.prototype.gT8=function(){return this.T8}
 function uA(a,b){this.a=a
 this.b=b}uA.builtin$cls="uA"
 if(!"name" in uA)uA.name="uA"
@@ -30796,8 +31092,8 @@
 $desc=$collectedClasses.VA
 if($desc instanceof Array)$desc=$desc[1]
 VA.prototype=$desc
-VA.prototype.gBb=function(receiver){return this.Bb}
-VA.prototype.gT8=function(receiver){return this.T8}
+VA.prototype.gBb=function(){return this.Bb}
+VA.prototype.gT8=function(){return this.T8}
 function J1(a,b){this.a=a
 this.b=b}J1.builtin$cls="J1"
 if(!"name" in J1)J1.name="J1"
@@ -30884,16 +31180,16 @@
 if($desc instanceof Array)$desc=$desc[1]
 uk.prototype=$desc
 uk.prototype.gkp=function(receiver){return this.kp}
-uk.prototype.gBb=function(receiver){return this.Bb}
-uk.prototype.gT8=function(receiver){return this.T8}
+uk.prototype.gBb=function(){return this.Bb}
+uk.prototype.gT8=function(){return this.T8}
 function K9(Bb,T8){this.Bb=Bb
 this.T8=T8}K9.builtin$cls="K9"
 if(!"name" in K9)K9.name="K9"
 $desc=$collectedClasses.K9
 if($desc instanceof Array)$desc=$desc[1]
 K9.prototype=$desc
-K9.prototype.gBb=function(receiver){return this.Bb}
-K9.prototype.gT8=function(receiver){return this.T8}
+K9.prototype.gBb=function(){return this.Bb}
+K9.prototype.gT8=function(){return this.T8}
 function zX(hP,Jn){this.hP=hP
 this.Jn=Jn}zX.builtin$cls="zX"
 if(!"name" in zX)zX.name="zX"
@@ -30910,24 +31206,24 @@
 x9.prototype=$desc
 x9.prototype.ghP=function(){return this.hP}
 x9.prototype.goc=function(receiver){return this.oc}
-function RW(hP,bP,re){this.hP=hP
+function Jy(hP,bP,re){this.hP=hP
 this.bP=bP
-this.re=re}RW.builtin$cls="RW"
-if(!"name" in RW)RW.name="RW"
-$desc=$collectedClasses.RW
+this.re=re}Jy.builtin$cls="Jy"
+if(!"name" in Jy)Jy.name="Jy"
+$desc=$collectedClasses.Jy
 if($desc instanceof Array)$desc=$desc[1]
-RW.prototype=$desc
-RW.prototype.ghP=function(){return this.hP}
-RW.prototype.gbP=function(receiver){return this.bP}
-RW.prototype.gre=function(){return this.re}
+Jy.prototype=$desc
+Jy.prototype.ghP=function(){return this.hP}
+Jy.prototype.gbP=function(receiver){return this.bP}
+Jy.prototype.gre=function(){return this.re}
 function xs(){}xs.builtin$cls="xs"
 if(!"name" in xs)xs.name="xs"
 $desc=$collectedClasses.xs
 if($desc instanceof Array)$desc=$desc[1]
 xs.prototype=$desc
-function FX(Sk,ks,ku,fL){this.Sk=Sk
-this.ks=ks
-this.ku=ku
+function FX(Sk,GP,qM,fL){this.Sk=Sk
+this.GP=GP
+this.qM=qM
 this.fL=fL}FX.builtin$cls="FX"
 if(!"name" in FX)FX.name="FX"
 $desc=$collectedClasses.FX
@@ -30965,10 +31261,10 @@
 Pn.prototype.gfY=function(receiver){return this.fY}
 Pn.prototype.gP=function(receiver){return this.P}
 Pn.prototype.gG8=function(){return this.G8}
-function hc(MV,zy,jI,x0){this.MV=MV
+function hc(MV,zy,jI,VQ){this.MV=MV
 this.zy=zy
 this.jI=jI
-this.x0=x0}hc.builtin$cls="hc"
+this.VQ=VQ}hc.builtin$cls="hc"
 if(!"name" in hc)hc.name="hc"
 $desc=$collectedClasses.hc
 if($desc instanceof Array)$desc=$desc[1]
@@ -30984,30 +31280,34 @@
 $desc=$collectedClasses.fr
 if($desc instanceof Array)$desc=$desc[1]
 fr.prototype=$desc
-function a0(){}a0.builtin$cls="a0"
-if(!"name" in a0)a0.name="a0"
-$desc=$collectedClasses.a0
+function cfS(){}cfS.builtin$cls="cfS"
+if(!"name" in cfS)cfS.name="cfS"
+$desc=$collectedClasses.cfS
 if($desc instanceof Array)$desc=$desc[1]
-a0.prototype=$desc
-function NQ(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+cfS.prototype=$desc
+function JG(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}NQ.builtin$cls="NQ"
-if(!"name" in NQ)NQ.name="NQ"
-$desc=$collectedClasses.NQ
+this.X0=X0}JG.builtin$cls="JG"
+if(!"name" in JG)JG.name="JG"
+$desc=$collectedClasses.JG
 if($desc instanceof Array)$desc=$desc[1]
-NQ.prototype=$desc
-function knI(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+JG.prototype=$desc
+function knI(zw,AP,fn,tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.zw=zw
+this.AP=AP
+this.fn=fn
+this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31015,19 +31315,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}knI.builtin$cls="knI"
+this.X0=X0}knI.builtin$cls="knI"
 if(!"name" in knI)knI.name="knI"
 $desc=$collectedClasses.knI
 if($desc instanceof Array)$desc=$desc[1]
 knI.prototype=$desc
-function fI(Uz,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Uz=Uz
+knI.prototype.gzw=function(receiver){return receiver.zw}
+knI.prototype.gzw.$reflectable=1
+knI.prototype.szw=function(receiver,v){return receiver.zw=v}
+knI.prototype.szw.$reflectable=1
+function qe(){}qe.builtin$cls="qe"
+if(!"name" in qe)qe.name="qe"
+$desc=$collectedClasses.qe
+if($desc instanceof Array)$desc=$desc[1]
+qe.prototype=$desc
+function fI(Uz,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Uz=Uz
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31035,14 +31344,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}fI.builtin$cls="fI"
+this.X0=X0}fI.builtin$cls="fI"
 if(!"name" in fI)fI.name="fI"
 $desc=$collectedClasses.fI
 if($desc instanceof Array)$desc=$desc[1]
@@ -31051,11 +31360,11 @@
 fI.prototype.gUz.$reflectable=1
 fI.prototype.sUz=function(receiver,v){return receiver.Uz=v}
 fI.prototype.sUz.$reflectable=1
-function V12(){}V12.builtin$cls="V12"
-if(!"name" in V12)V12.name="V12"
-$desc=$collectedClasses.V12
+function V13(){}V13.builtin$cls="V13"
+if(!"name" in V13)V13.name="V13"
+$desc=$collectedClasses.V13
 if($desc instanceof Array)$desc=$desc[1]
-V12.prototype=$desc
+V13.prototype=$desc
 function qq(a,b){this.a=a
 this.b=b}qq.builtin$cls="qq"
 if(!"name" in qq)qq.name="qq"
@@ -31067,8 +31376,9 @@
 $desc=$collectedClasses.FC
 if($desc instanceof Array)$desc=$desc[1]
 FC.prototype=$desc
-function xI(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function xI(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31076,14 +31386,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}xI.builtin$cls="xI"
+this.X0=X0}xI.builtin$cls="xI"
 if(!"name" in xI)xI.name="xI"
 $desc=$collectedClasses.xI
 if($desc instanceof Array)$desc=$desc[1]
@@ -31096,12 +31406,17 @@
 xI.prototype.gPe.$reflectable=1
 xI.prototype.sPe=function(receiver,v){return receiver.Pe=v}
 xI.prototype.sPe.$reflectable=1
+xI.prototype.gm0=function(receiver){return receiver.m0}
+xI.prototype.gm0.$reflectable=1
+xI.prototype.sm0=function(receiver,v){return receiver.m0=v}
+xI.prototype.sm0.$reflectable=1
 function Ds(){}Ds.builtin$cls="Ds"
 if(!"name" in Ds)Ds.name="Ds"
 $desc=$collectedClasses.Ds
 if($desc instanceof Array)$desc=$desc[1]
 Ds.prototype=$desc
-function nm(Va,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Va=Va
+function nm(Va,Mt,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Va=Va
+this.Mt=Mt
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31109,14 +31424,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}nm.builtin$cls="nm"
+this.X0=X0}nm.builtin$cls="nm"
 if(!"name" in nm)nm.name="nm"
 $desc=$collectedClasses.nm
 if($desc instanceof Array)$desc=$desc[1]
@@ -31125,12 +31440,16 @@
 nm.prototype.gVa.$reflectable=1
 nm.prototype.sVa=function(receiver,v){return receiver.Va=v}
 nm.prototype.sVa.$reflectable=1
-function V13(){}V13.builtin$cls="V13"
-if(!"name" in V13)V13.name="V13"
-$desc=$collectedClasses.V13
+nm.prototype.gMt=function(receiver){return receiver.Mt}
+nm.prototype.gMt.$reflectable=1
+nm.prototype.sMt=function(receiver,v){return receiver.Mt=v}
+nm.prototype.sMt.$reflectable=1
+function V14(){}V14.builtin$cls="V14"
+if(!"name" in V14)V14.name="V14"
+$desc=$collectedClasses.V14
 if($desc instanceof Array)$desc=$desc[1]
-V13.prototype=$desc
-function Vu(V4,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.V4=V4
+V14.prototype=$desc
+function Vu(V4,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.V4=V4
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31138,14 +31457,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Vu.builtin$cls="Vu"
+this.X0=X0}Vu.builtin$cls="Vu"
 if(!"name" in Vu)Vu.name="Vu"
 $desc=$collectedClasses.Vu
 if($desc instanceof Array)$desc=$desc[1]
@@ -31154,11 +31473,21 @@
 Vu.prototype.gV4.$reflectable=1
 Vu.prototype.sV4=function(receiver,v){return receiver.V4=v}
 Vu.prototype.sV4.$reflectable=1
-function V14(){}V14.builtin$cls="V14"
-if(!"name" in V14)V14.name="V14"
-$desc=$collectedClasses.V14
+function V15(){}V15.builtin$cls="V15"
+if(!"name" in V15)V15.name="V15"
+$desc=$collectedClasses.V15
 if($desc instanceof Array)$desc=$desc[1]
-V14.prototype=$desc
+V15.prototype=$desc
+function At(a){this.a=a}At.builtin$cls="At"
+if(!"name" in At)At.name="At"
+$desc=$collectedClasses.At
+if($desc instanceof Array)$desc=$desc[1]
+At.prototype=$desc
+function Sb(){}Sb.builtin$cls="Sb"
+if(!"name" in Sb)Sb.name="Sb"
+$desc=$collectedClasses.Sb
+if($desc instanceof Array)$desc=$desc[1]
+Sb.prototype=$desc
 function V2(N1,mD,Ck){this.N1=N1
 this.mD=mD
 this.Ck=Ck}V2.builtin$cls="V2"
@@ -31193,21 +31522,21 @@
 $desc=$collectedClasses.H2
 if($desc instanceof Array)$desc=$desc[1]
 H2.prototype=$desc
-function lP(){}lP.builtin$cls="lP"
-if(!"name" in lP)lP.name="lP"
-$desc=$collectedClasses.lP
+function YJ(){}YJ.builtin$cls="YJ"
+if(!"name" in YJ)YJ.name="YJ"
+$desc=$collectedClasses.YJ
 if($desc instanceof Array)$desc=$desc[1]
-lP.prototype=$desc
-function LfS(a){this.a=a}LfS.builtin$cls="LfS"
-if(!"name" in LfS)LfS.name="LfS"
-$desc=$collectedClasses.LfS
-if($desc instanceof Array)$desc=$desc[1]
-LfS.prototype=$desc
-function fTP(b){this.b=b}fTP.builtin$cls="fTP"
+YJ.prototype=$desc
+function fTP(a){this.a=a}fTP.builtin$cls="fTP"
 if(!"name" in fTP)fTP.name="fTP"
 $desc=$collectedClasses.fTP
 if($desc instanceof Array)$desc=$desc[1]
 fTP.prototype=$desc
+function ppY(b){this.b=b}ppY.builtin$cls="ppY"
+if(!"name" in ppY)ppY.name="ppY"
+$desc=$collectedClasses.ppY
+if($desc instanceof Array)$desc=$desc[1]
+ppY.prototype=$desc
 function NP(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
 this.qP=qP
 this.ZY=ZY
@@ -31219,17 +31548,17 @@
 $desc=$collectedClasses.NP
 if($desc instanceof Array)$desc=$desc[1]
 NP.prototype=$desc
-function Vh(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
+function jt(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
 this.qP=qP
 this.ZY=ZY
 this.xS=xS
 this.PB=PB
 this.eS=eS
-this.ay=ay}Vh.builtin$cls="Vh"
-if(!"name" in Vh)Vh.name="Vh"
-$desc=$collectedClasses.Vh
+this.ay=ay}jt.builtin$cls="jt"
+if(!"name" in jt)jt.name="jt"
+$desc=$collectedClasses.jt
 if($desc instanceof Array)$desc=$desc[1]
-Vh.prototype=$desc
+jt.prototype=$desc
 function r0(a){this.a=a}r0.builtin$cls="r0"
 if(!"name" in r0)r0.name="r0"
 $desc=$collectedClasses.r0
@@ -31304,10 +31633,10 @@
 $desc=$collectedClasses.ug
 if($desc instanceof Array)$desc=$desc[1]
 ug.prototype=$desc
-function DT(lr,xT,kr,Ds,QO,jH,mj,IT,dv,N1,mD,Ck){this.lr=lr
+function DT(lr,xT,kr,Mf,QO,jH,mj,IT,dv,N1,mD,Ck){this.lr=lr
 this.xT=xT
 this.kr=kr
-this.Ds=Ds
+this.Mf=Mf
 this.QO=QO
 this.jH=jH
 this.mj=mj
@@ -31332,11 +31661,11 @@
 $desc=$collectedClasses.OB
 if($desc instanceof Array)$desc=$desc[1]
 OB.prototype=$desc
-function Uf(){}Uf.builtin$cls="Uf"
-if(!"name" in Uf)Uf.name="Uf"
-$desc=$collectedClasses.Uf
+function DO(){}DO.builtin$cls="DO"
+if(!"name" in DO)DO.name="DO"
+$desc=$collectedClasses.DO
 if($desc instanceof Array)$desc=$desc[1]
-Uf.prototype=$desc
+DO.prototype=$desc
 function p8(ud,lr,eS,ay){this.ud=ud
 this.lr=lr
 this.eS=eS
@@ -31446,4 +31775,4 @@
 $desc=$collectedClasses.VD
 if($desc instanceof Array)$desc=$desc[1]
 VD.prototype=$desc
-return[qE,SV,Gh,rK,fY,Mr,zx,P2,Xk,W2,zJ,Az,QP,QW,n6,Nu,OM,QQ,BR,wT,d7,na,oJ,DG,vz,bY,n0,Em,rD,rV,K4,QF,hN,SL,rv,Nh,ac,cv,Fs,Ty,ea,D0,as,hH,QU,u5,Yu,W4,jP,Cz,tA,Cv,Uq,QH,So,X2,zU,wa,tX,Sg,pA,Mi,Gt,ttH,wP,eP,mF,Qj,cS,M6,El,zm,Y7,aB,fJ,BK,Rv,HO,rC,ZY,DD,la,Qb,PG,xe,Hw,bn,tH,oB,Aj,H9,o4,oU,ih,uH,yk,KY,G7,l9,Ql,Xp,bP,FH,SN,HD,ni,jg,qj,nC,KR,ew,fs,LY,BL,fe,By,j2,X4,lp,kd,I0,QR,Cp,Ta,Hd,Ul,G5,wb,fq,h4,qk,GI,Tb,tV,BT,yY,kJ,AE,xV,Dn,y6,RH,pU,OJ,Mf,dp,r4,aG,J6,u9,Bn,UL,rq,I1,kc,AK,dM,Nf,F2,VB,QV,Zv,Q7,hF,hr,Dh,ZJ,mU,NE,Fl,y5,jQ,Kg,ui,vO,DQ,Sm,LM,es,eG,lv,pf,NV,W1,HC,kK,hq,bb,NdT,lc,Xu,qM,tk,me,bO,nh,EI,MI,ca,zt,eW,kL,Fu,OE,N9,BA,zp,br,PIw,PQ,Jq,Yd,kN,lZ,Gr,XE,GH,Lx,NJ,Ue,vt,rQ,Lu,LR,GN,hy,mq,Ke,CG,Xe,y0,Rk4,Eo,tL,pyk,ZD,Rlr,wD,Wv,yz,Fi,Qr,zI,cB,uY,yR,GK,xJ,oI,Et,NC,nb,Zn,xt,tG,P0,xlX,SQ,qD,TM,I2,HY,Kq,Nn,Un,rF,Sb,UZ,yc,Aw,jx,F0,Lt,Gv,kn,PE,QI,FP,is,Q,NK,ZC,Jt,P,im,GW,vT,VP,BQ,O,Qe,PK,JO,f0,aX,cC,RA,IY,JH,jl,Iy4,Z6,Ua,ns,yo,Rd,Bj,NO,II,fP,X1,HU,oo,OW,hz,AP,yH,FA,Av,Zd,xQ,Q9,oH,LPe,bw,WT,jJ,XR,LI,Ny,IW,F3,FD,Cj,u8,Zr,W0,az,vV,Am,XO,dr,TL,KX,uZ,OQ,Tp,Bp,v,Ll,dN,GT,Pe,Eq,lb,tD,hJ,tu,fw,Zz,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,G6,Vf,kf,Ps,pv,CN,vc,Vfx,i6,Dsd,wJ,aL,nH,a7,i1,xy,MH,A8,U5,SO,kV,rR,H6,d5,U1,SJ,SU7,JJ,Iy,iK,GD,Sn,nI,TY,Lj,mb,mZ,cw,EE,Uz,NZ,IB,oP,YX,BI,vk,M2,iu,mg,bl,tB,Oo,Tc,Ax,Wf,HZT,Ei,U7,t0,Ld,Sz,Zk,fu,ng,TN,Ar,rh,jB,ye,O1,Oh,Xh,Ca,Ik,JI,Ks,dz,tK,OR,Bg,DL,b8,Ia,Zf,vs,da,xw,dm,rH,ZL,mi,jb,wB,Pu,qh,YJ,jv,LB,DO,lz,Rl,Jb,M4,Jp,h7,pr,eN,PI,uO,j4,i9,VV,Dy,lU,OC,UH,Z5,ii,ib,MO,ms,UO,Bc,vp,lk,q1,ZzD,ly,fE,O9,yU,nP,KA,Vo,qB,ez,lx,LV,DS,JF,ht,CR,Qk,dR,uR,QX,YR,fB,nO,t3,dq,tU,aY,zG,e4,JB,Id,WH,TF,K5,Cg,Hs,dv,pV,cc,pK,eM,Uez,W5,R8,k6,oi,ce,DJ,PL,Fq,jG,fG,EQ,YB,a1,ou,S9,ey,xd,v6,db,i5,N6,Rr,YO,oz,b6,ef,zQ,Yp,lN,mW,ar,lD,ZQ,Sw,o0,qv,jp,vX,Ba,An,bF,LD,S6B,OG,uM,DN,ZM,HW,JC,f1,Uk,wI,Zi,Ud,K8,by,pD,Cf,Sh,tF,z0,E3,Rw,GY,jZ,HB,CL,p4,a2,fR,iP,MF,Rq,Hn,Zl,B5,a6,P7,DW,Ge,LK,AT,bJ,Np,mp,ub,ds,lj,UV,VS,t7,HG,aE,eV,kM,EH,cX,Yl,Z0,L9,a,Od,MN,WU,Rn,wv,uq,iD,In,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,Mx,C9,kZ,JT,d9,rI,QZ,BV,E1,VG,wz,B1,M5,Jn,DM,RAp,ma,Kx,iO,bU,Yg,e7,nNL,ecX,kI,yoo,w1p,tJ,Zc,i7,nF,FK,Si,vf,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,hP,Gm,W9,vZ,dW,Dk,O7,E4,Xb,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,ej,NL,vr,D4,X9,Ms,tg,RS,RY,Ys,WS4,A2,U4,B8q,Nx,ue,GG,Y8,Bk,iY,C0A,RAK,FvP,tuj,Ir,Vct,m8,jM,D13,DKl,mk,WZq,NM,pva,bd,LS,aI,rG,yh,wO,Tm,rz,CA,YL,KC,xL,Ay,GE,rl,uQ,D7,hT,GS,pR,hx,cda,u7,fW,E7,waa,RR,EL,St,V0,vj,V4,LU,CX,V6,TJ,dG,qV,HV,em,Lb,PF,fA,tz,jA,Jo,c5,qT,Xd,V10,mL,Kf,qu,bv,eS,IQ,TI,pt,Ub,dY,vY,zZ,dS,dZ,us,DP,WAE,N8,kx,CM,xn,ct,hM,vu,Ja,c2,rj,R2,Q4,aJ,u4,pF,Q2,tb,Rb,F1,V11,uL,LP,Pi,z2,qI,J3,E5,o5,b5,u3,Zb,id,iV,DA,nd,vly,d3,X6,xh,wn,uF,cj,HA,qC,zT,Lo,WR,qL,Px,C4,Md,km,lI,u2,q7,Qt,No,v5,OO,OF,rM,IV,Zj,XP,q6,CK,LJ,ZG,Oc,MX,w11,ppY,yL,zs,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,Sa,Ao,k8,HJ,S0,V3,Bl,Fn,e3,pM,jh,W6,Lf,fT,pp,Nq,nl,mf,ik,HK,o8,ex,e9,Xy,uK,mY,GX,mB,XF,iH,Ra,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,w9,w10,c4,z6,dE,Ed,G1,Os,B8,Wh,x5,ev,ID,jV,ek,Qv,Xm,Jy,mG,uA,vl,Li,WK,iT,ja,zw,fa,WW,vQ,a9,VA,J1,fk,wL,B0,tc,hw,EZ,no,kB,ae,XC,w6,jK,uk,K9,zX,x9,RW,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,a0,NQ,knI,fI,V12,qq,FC,xI,Ds,nm,V13,Vu,V14,V2,D8,jY,H2,lP,LfS,fTP,NP,Vh,r0,jz,SA,hB,nv,ee,XI,hs,yp,ug,DT,OB,Uf,p8,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,wl,T4,TR,VD]}
\ No newline at end of file
+return[qE,SV,Gh,A0,na,Mr,zx,P2,Xk,W2,it,Az,QP,QW,jr,Ny,nx,QQ,BR,di,d7,yJ,He,vz,vHT,n0,Em,pt,rV,K4,QF,Aj,cm,Nh,wj,cv,Fs,Ty,ea,D0,as,hH,Aa,u5,h4,W4,jP,Hd,tA,wa,Uq,QH,Rt,X2,zU,pk,tX,Sg,pA,Mi,Gt,In,wP,eP,mF,Qj,cS,YI,El,zm,Y7,aB,fJ,BK,Rv,HO,Kk,ZY,DD,EeC,Qb,PG,xe,Hw,bn,Imr,Ve,Oq,H9,o4,oU,ih,KV,yk,KY,G7,l9,Ql,Xp,bP,FH,iL,HD,ni,jg,qj,nC,KR,ew,fs,LY,BL,fe,By,j2,X4,lp,pD,I0,QR,Cp,Ta,zD9,Ul,G5,bk,fq,Er,qk,GI,Tb,tV,BT,yY,kJ,AE,xV,Dn,y6,RH,ho,OJ,Mf,dp,vw,aG,J6,u9,Bn,hq,UL,tZ,kc,AK,ty,Nf,F2,VB,QV,Zv,Q7,hF,OF,Dh,ZJ,mU,NE,lC,y5,jQ,Kg,ui,mk,DQ,Sm,LM,es,eG,lv,pf,NV,W1,mCz,kK,n5,bb,NdT,lc,Xu,qM,tk,me,oB,nh,EI,MI,ca,um,eW,kL,Fu,QN,N9,BA,d0,zp,br,PIw,vd,Jq,Yd,kN,lZ,Gr,XE,GH,lo,NJ,Ue,vt,rQ,Lx,LR,d5,hy,mq,Ke,CG,Xe,y0,Rk4,Eo,tL,pyk,ZD,rD,wD,Wv,yz,Fi,Ja,mj,cB,Mh,yR,GK,xJ,Nn,Et,NC,nb,Zn,xt,wx,P0,xlX,SQ,qD,TM,WZ,rn,df,Hg,L3,xj,dE,Eb,dT,N2,eE,V6,Lt,Gv,kn,ht,QI,FP,is,Q,nM,ZC,Jt,P,im,GW,vT,VP,BQ,O,PK,JO,f0,aX,cC,RA,IY,JH,jl,Iy,Z6,Ua,ns,yo,NA,NO,II,fP,X1,HU,oo,OW,hz,iY,yH,FA,Av,ku,Zd,xQ,F0,oH,LPe,bw,WT,jJ,XR,LI,A2,IW,F3,FD,Cj,u8,Zr,W0,az,vV,Am,XO,dr,TL,KX,uZ,OQ,Tp,Bp,v,Ll,dN,GT,Pe,Eq,lb,tD,hJ,tu,fw,Zz,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,G6,Vf,Tg,Ps,pv,CN,vc,Vfx,i6,Dsd,wJ,aL,nH,a7,i1,xy,MH,A8,U5,SO,kV,rR,H6,wB,U1,SJ,SU7,Qr,w2Y,iK,GD,Sn,nI,TY,Lj,mb,am,cw,EE,Uz,uh,IB,oP,YX,BI,Un,M2,iu,mg,bl,tB,Oo,Tc,Ax,Wf,vk,Ei,U7,t0,Ld,Sz,Zk,fu,wt,ng,TN,Ar,rh,jB,ye,O1,Oh,Xh,Ca,Ik,JI,Ks,dz,tK,OR,Bg,DL,b8,Ia,Zf,vs,da,xw,dm,rH,ZL,rq,RW,RT,jZ,FZ,OM,qh,tG,jv,LB,zn,lz,Rl,Jb,M4,Jp,h7,pr,eN,PI,uO,j4,i9,VV,Dy,lU,OC,UH,Z5,ii,ib,MO,O9,oh,nP,KA,Vo,qB,ez,lx,LV,DS,JF,Je,CR,Qk,v1y,uR,Q0,YR,fB,nO,t3,dq,lO,aY,zG,e4,JB,Id,WH,TF,K5,Cg,Hs,dv,pV,uo,pK,eM,Uez,nU,R8,k6,oi,ce,DJ,PL,Fq,jG,fG,EQ,YB,a1,ou,S9,ey,xd,v6,db,i5,N6,Rr,YO,oz,b6,ef,zQ,Yp,lN,mW,ar,lD,ZQ,Sw,o0,qv,jp,vX,Ba,An,bF,LD,S6B,OG,uM,DN,ZM,HW,JC,f1,Uk,wI,Zi,Ud,K8,by,dI,Cf,Sh,tF,z0,E3,Rw,HB,CL,p4,a2,fR,iP,MF,Rq,Hn,Zl,B5,a6,P7,DW,Ge,LK,AT,bJ,Np,mp,ub,ds,lj,UV,VS,t7,HG,aE,eV,kM,EH,cX,Yl,Z0,L9,a,Od,MN,WU,Rn,wv,uq,iD,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,Mx,C9,kZ,JT,d9,rI,QZ,VG,wz,B1,M5,Jn,DM,RAp,Gb,Kx,iO,bU,Yg,e7,nNL,ecX,kI,yoo,w1p,tJ,Zc,i7,nF,FK,Si,vf,Iw,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,bO,Gm,Of,Qg,W9,vZ,dW,Dk,O7,IU,E4,Gn,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,ej,NL,vr,D4,X9,Ms,ac,RS,RY,Ys,WS4,Gj,U4,B8q,Nx,LZ,Dg,Ob,Ip,Pg,Nb,nA,Fv,tuj,E9,Vct,m8,Gk,D13,GG,yb,WZq,NM,pva,bd,LS,aI,rG,yh,wO,Tm,q1,CA,YL,KC,xL,As,GE,rl,uQ,D7,hT,GS,pR,T5,YE,we,hx,cda,u7,fW,qm,vO,E7,waa,RR,EL,St,V0,vj,V4,LU,T2,V10,TJ,dG,qV,HV,em,Lb,PF,fA,tz,jA,PO,c5,qT,Xd,V11,mL,Kf,qu,bv,eS,IQ,TI,yU,Ub,dY,vY,zZ,dS,dZ,Qe,DP,WAE,N8,Vi,kx,fx,CM,xn,vu,c2,rj,Nu,Q4,aJ,u4,pF,Q2,r1,Rb,Y2,XN,F1,V12,uL,LP,Pi,z2,qI,J3,E5,o5,b5,zI,Zb,id,iV,DA,nd,vly,d3,lS,xh,wn,Ay,Bj,HA,qC,zT,Lo,WR,qL,Px,C4,Md,km,Zj,XP,q6,CK,LJ,ZG,Oc,MX,w9,r3y,yL,zs,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,jpR,GN,bS,HJ,S0,V3,Bl,Fn,e3,pM,jh,W6,Lf,fT,pp,nl,ik,mf,LfS,HK,o8,ex,e9,Xy,G0,mY,GX,mB,XF,bX,lP,Uf,Ra,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,c4,z6,Mb,Ed,G1,Os,B8,Wh,x5,ev,ID,qR,ek,Qv,Xm,mv,mG,uA,vl,Li,WK,iT,ja,zw,fa,WW,vQ,a9,VA,J1,fk,wL,B0,tc,hw,EZ,no,kB,ae,XC,w6,jK,uk,K9,zX,x9,Jy,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,cfS,JG,knI,qe,fI,V13,qq,FC,xI,Ds,nm,V14,Vu,V15,At,Sb,V2,D8,jY,H2,YJ,fTP,ppY,NP,jt,r0,jz,SA,hB,nv,ee,XI,hs,yp,ug,DT,OB,DO,p8,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,wl,T4,TR,VD]}
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/deployed/web/index_devtools.html b/runtime/bin/vmservice/client/deployed/web/index_devtools.html
index d92fc28..39f599b 100644
--- a/runtime/bin/vmservice/client/deployed/web/index_devtools.html
+++ b/runtime/bin/vmservice/client/deployed/web/index_devtools.html
@@ -71,20 +71,75 @@
 </template>
 
 </polymer-element><polymer-element name="instance-ref" extends="service-ref">
-<template>
-<div>
-  <template if="{{ (ref['type'] == 'null') }}">
-    unexpected null
-  </template>
-  <template if="{{ (ref['type'] == '@Null') }}">
-    {{ name }}
-  </template>
-  <template if="{{ (ref['type'] != 'null') &amp;&amp; ref['type'] != '@Null' }}">
-    <a href="{{ url }}">{{ name }} </a>
-  </template>
- </div>
-</template>
+  <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
+    <div>
+      <template if="{{ isUnexpectedRef(ref['type']) }}">
+        unexpected reference type &lt;{{ ref['type'] }}&gt;
+      </template>
 
+      <template if="{{ isNullRef(ref['type']) }}">
+        {{ name }}
+      </template>
+
+      <template if="{{ (isStringRef(ref['type']) ||
+                        isBoolRef(ref['type']) ||
+                        isIntRef(ref['type'])) }}">
+        <a href="{{ url }}">{{ name }}</a>
+      </template>
+
+      <template if="{{ isClosureRef(ref['type']) }}">
+        <a href="{{ url }}">
+          {{ ref['closureFunc']['user_name'] }}
+        </a>
+      </template>
+
+      <template if="{{ isInstanceRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em></a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ field in ref['fields'] }}">
+
+              <td class="member">{{ field['decl']['user_name'] }}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+      </template>
+
+      <template if="{{ isListRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em> ({{ ref['length']}})</a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ element in ref['elements'] }}">
+              <td class="member">[{{ element['index']}}]</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ element['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+      </template>
+
+    </div>
+  </template>
+  
 </polymer-element>
 <polymer-element name="library-ref" extends="service-ref">
 <template>
@@ -301,7 +356,13 @@
   </div>
   </template>
   
-</polymer-element><polymer-element name="isolate-summary" extends="observatory-element">
+</polymer-element><polymer-element name="script-ref" extends="service-ref">
+<template>
+  <a title="{{ hoverText }}" href="{{ url }}">{{ name }}</a>
+</template>
+
+</polymer-element>
+<polymer-element name="isolate-summary" extends="observatory-element">
   <template>
     <div class="row">
       <div class="col-md-1">
@@ -381,12 +442,8 @@
       </div>
       <div class="col-md-6">
         <template if="{{ isolate.topFrame != null }}">
-          <a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['function']['id']) }}">
-            {{ isolate.topFrame['function']['user_name'] }}
-          </a>
-          (<a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['script']['id']) }}">
-            {{ isolate.topFrame | fileAndLine }}
-          </a>)
+          <function-ref app="{{ app }}" isolate="{{ isolate }}" ref="{{ isolate.topFrame['function'] }}"></function-ref>
+          (<script-ref app="{{ app }}" isolate="{{ isolate }}" ref="{{ isolate.topFrame['script'] }}" line="{{ isolate.topFrame['line'] }}"></script-ref>)
           <br>
           <pre>{{ isolate.topFrame['line'] }} &nbsp; {{ isolate.topFrame['lineString'] }}</pre>
         </template>
@@ -433,7 +490,7 @@
             <table class="table table-hover">
              <tbody>
                 <tr template="" repeat="{{ field in instance['fields'] }}">
-                  <td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
+                  <td><field-ref app="{{ app }}" ref="{{ field['decl'] }}"></field-ref></td>
                   <td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
                 </tr>
               </tbody>
@@ -479,12 +536,7 @@
   </template>
   
 </polymer-element>
-<polymer-element name="script-ref" extends="service-ref">
-<template>
-  <a href="{{ url }}">{{ name }}</a>
-</template>
-
-</polymer-element><polymer-element name="library-view" extends="observatory-element">
+<polymer-element name="library-view" extends="observatory-element">
   <template>
   <div class="alert alert-success">Library {{ library['name'] }}</div>
   <div class="alert alert-info">Scripts</div>
@@ -620,7 +672,7 @@
           <tr template="" repeat="{{ line in script.linesForDisplay }}">
             <td style="{{ hitsStyle(line) }}">  </td>
             <td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{line.line}}</td>
-            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;">{{line.text}}</td>
+            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{line.text}}</td>
           </tr>
           </tbody>
         </table>
@@ -631,6 +683,17 @@
 
 </polymer-element><polymer-element name="stack-frame" extends="observatory-element">
   <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
     <div class="row">
       <div class="col-md-1"></div>
       <div class="col-md-1">
@@ -638,29 +701,33 @@
       </div>
       <div class="col-md-9">
         <function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref>
-        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref>:{{ frame['line'] }} )
+        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}" line="{{ frame['line'] }}">
+        </script-ref> ) {
+        <a on-click="{{ toggleExpand }}">...</a>
+
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tbody><tr template="" repeat="{{ v in frame['vars'] }}">
+              <td class="member">{{ v['name']}}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </tbody></table>
+        </template>
+        }
+
       </div>
       <div class="col-md-1"></div>
     </div>
 
-    <template repeat="{{ v in frame['vars'] }}">
-      <div class="row">
-        <div class="col-md-3"></div>
-        <div class="col-md-1">
-          {{ v['name'] }}
-        </div>
-        <div class="col-md-6">
-          <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
-        </div>
-        <div class="col-md-2"></div>
-      </div>
-    </template>
 
   </template>
   
 </polymer-element>
 <polymer-element name="stack-trace" extends="observatory-element">
   <template>
+    <button type="button" on-click="{{refresh}}">Refresh</button>
     <template if="{{ trace['members'].isEmpty }}">
       <div class="col-md-1"></div>
       <div class="col-md-11">
@@ -708,6 +775,9 @@
     <template if="{{ messageType == 'Field' }}">
       <field-view app="{{ app }}" field="{{ message }}"></field-view>
     </template>
+    <template if="{{ messageType == 'Closure' }}">
+      <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
+    </template>
     <template if="{{ messageType == 'Instance' }}">
       <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
     </template>
@@ -744,7 +814,8 @@
     <!-- Add new views and message types in the future here. -->
   </template>
   
-</polymer-element><polymer-element name="navigation-bar-isolate" extends="observatory-element">
+</polymer-element>
+<polymer-element name="navigation-bar-isolate" extends="observatory-element">
     <template>
       <ul class="nav navbar-nav">
         <li><a href="{{ currentIsolateLink('') }}"> {{currentIsolateName()}}</a></li>
@@ -770,34 +841,34 @@
   
 </polymer-element><polymer-element name="isolate-profile" extends="observatory-element">
   <template>
-    <p> P R O F I L E </p>
     <div>
       <button type="button" on-click="{{refreshData}}">Refresh profile data</button>
       <span>Top</span>
       <select selectedindex="{{methodCountSelected}}" value="{{methodCounts[methodCountSelected]}}">
         <option template="" repeat="{{count in methodCounts}}">{{count}}</option>
       </select>
-      <span>methods</span>
+      <span>exclusive methods</span>
     </div>
-    <blockquote><strong>Top Exclusive</strong></blockquote>
-    <table class="table table-hover">
+    <table id="tableTree" class="table table-hover">
       <thead>
         <tr>
-          <th>Ticks</th>
-          <th>Percent</th>
           <th>Method</th>
+          <th>Exclusive</th>
+          <th>Caller</th>
+          <th>Inclusive</th>
         </tr>
       </thead>
       <tbody>
-        <tr template="" repeat="{{ code in topExclusiveCodes }}">
-            <td>{{ codeTicks(code, false) }}</td>
-            <td>{{ codePercent(code, false) }}</td>
-            <td>
-            <span>{{ codeName(code) }}</span>
-            <code-ref app="{{ app }}" ref="{{ code.codeRef }}"></code-ref>
-            </td>
+        <tr template="" repeat="{{row in tree.rows }}" style="{{}}">
+          <td on-click="{{toggleExpanded}}" class="{{ coloring(row) }}" style="{{ padding(row) }}">
+            <code-ref app="{{ app }}" ref="{{ row.code.codeRef }}"></code-ref>
+          </td>
+          <td class="{{ coloring(row) }}">{{row.columns[0]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[1]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[2]}}</td>
         </tr>
-    </tbody></table>
+      </tbody>
+    </table>
   </template>
   
 </polymer-element>
diff --git a/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js b/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
index 545be5f..7740667 100644
--- a/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
@@ -197,7 +197,7 @@
       this.push(part);
     }, this);
 
-    if (hasEval && !hasObserve && this.length) {
+    if (hasEval && this.length) {
       this.getValueFrom = this.compiledGetValueFromFn();
     }
   }
@@ -235,17 +235,25 @@
       return this.join('.');
     },
 
-    getValueFrom: function(obj, observedSet) {
+    getValueFrom: function(obj, directObserver) {
       for (var i = 0; i < this.length; i++) {
         if (obj == null)
           return;
-        if (observedSet)
-          observedSet.observe(obj);
         obj = obj[this[i]];
       }
       return obj;
     },
 
+    iterateObjects: function(obj, observe) {
+      for (var i = 0; i < this.length; i++) {
+        if (i)
+          obj = obj[this[i - 1]];
+        if (!obj)
+          return;
+        observe(obj);
+      }
+    },
+
     compiledGetValueFromFn: function() {
       var accessors = this.map(function(ident) {
         return isIndex(ident) ? '["' + ident + '"]' : '.' + ident;
@@ -294,12 +302,13 @@
 
   function dirtyCheck(observer) {
     var cycles = 0;
-    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check()) {
-      observer.report();
+    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {
       cycles++;
     }
     if (global.testingExposeCycleCount)
       global.dirtyCheckCycleCount = cycles;
+
+    return cycles > 0;
   }
 
   function objectIsEmpty(object) {
@@ -352,104 +361,280 @@
     };
   }
 
-  function copyObject(object, opt_copy) {
-    var copy = opt_copy || (Array.isArray(object) ? [] : {});
-    for (var prop in object) {
-      copy[prop] = object[prop];
-    };
-    if (Array.isArray(object))
-      copy.length = object.length;
-    return copy;
+  var eomTasks = [];
+  function runEOMTasks() {
+    if (!eomTasks.length)
+      return false;
+
+    for (var i = 0; i < eomTasks.length; i++) {
+      eomTasks[i]();
+    }
+    eomTasks.length = 0;
+    return true;
   }
 
-  function Observer(object, callback, target, token) {
-    this.closed = false;
-    this.object = object;
-    this.callback = callback;
-    // TODO(rafaelw): Hold this.target weakly when WeakRef is available.
-    this.target = target;
-    this.token = token;
-    this.reporting = true;
-    if (hasObserve) {
-      var self = this;
-      this.boundInternalCallback = function(records) {
-        self.internalCallback(records);
-      };
+  var runEOM = hasObserve ? (function(){
+    var eomObj = { pingPong: true };
+    var eomRunScheduled = false;
+
+    Object.observe(eomObj, function() {
+      runEOMTasks();
+      eomRunScheduled = false;
+    });
+
+    return function(fn) {
+      eomTasks.push(fn);
+      if (!eomRunScheduled) {
+        eomRunScheduled = true;
+        eomObj.pingPong = !eomObj.pingPong;
+      }
+    };
+  })() :
+  (function() {
+    return function(fn) {
+      eomTasks.push(fn);
+    };
+  })();
+
+  var observedObjectCache = [];
+
+  function newObservedObject() {
+    var observer;
+    var object;
+    var discardRecords = false;
+    var first = true;
+
+    function callback(records) {
+      if (observer && observer.state_ === OPENED && !discardRecords)
+        observer.check_(records);
     }
 
-    addToAll(this);
+    return {
+      open: function(obs) {
+        if (observer)
+          throw Error('ObservedObject in use');
+
+        if (!first)
+          Object.deliverChangeRecords(callback);
+
+        observer = obs;
+        first = false;
+      },
+      observe: function(obj, arrayObserve) {
+        object = obj;
+        if (arrayObserve)
+          Array.observe(object, callback);
+        else
+          Object.observe(object, callback);
+      },
+      deliver: function(discard) {
+        discardRecords = discard;
+        Object.deliverChangeRecords(callback);
+        discardRecords = false;
+      },
+      close: function() {
+        observer = undefined;
+        Object.unobserve(object, callback);
+        observedObjectCache.push(this);
+      }
+    };
+  }
+
+  function getObservedObject(observer, object, arrayObserve) {
+    var dir = observedObjectCache.pop() || newObservedObject();
+    dir.open(observer);
+    dir.observe(object, arrayObserve);
+    return dir;
+  }
+
+  var emptyArray = [];
+  var observedSetCache = [];
+
+  function newObservedSet() {
+    var observers = [];
+    var observerCount = 0;
+    var objects = [];
+    var toRemove = emptyArray;
+    var resetNeeded = false;
+    var resetScheduled = false;
+
+    function observe(obj) {
+      if (!isObject(obj))
+        return;
+
+      var index = toRemove.indexOf(obj);
+      if (index >= 0) {
+        toRemove[index] = undefined;
+        objects.push(obj);
+      } else if (objects.indexOf(obj) < 0) {
+        objects.push(obj);
+        Object.observe(obj, callback);
+      }
+
+      observe(Object.getPrototypeOf(obj));
+    }
+
+    function reset() {
+      resetScheduled = false;
+      if (!resetNeeded)
+        return;
+
+      var objs = toRemove === emptyArray ? [] : toRemove;
+      toRemove = objects;
+      objects = objs;
+
+      var observer;
+      for (var id in observers) {
+        observer = observers[id];
+        if (!observer || observer.state_ != OPENED)
+          continue;
+
+        observer.iterateObjects_(observe);
+      }
+
+      for (var i = 0; i < toRemove.length; i++) {
+        var obj = toRemove[i];
+        if (obj)
+          Object.unobserve(obj, callback);
+      }
+
+      toRemove.length = 0;
+    }
+
+    function scheduleReset() {
+      if (resetScheduled)
+        return;
+
+      resetNeeded = true;
+      resetScheduled = true;
+      runEOM(reset);
+    }
+
+    function callback() {
+      var observer;
+
+      for (var id in observers) {
+        observer = observers[id];
+        if (!observer || observer.state_ != OPENED)
+          continue;
+
+        observer.check_();
+      }
+
+      scheduleReset();
+    }
+
+    var record = {
+      object: undefined,
+      objects: objects,
+      open: function(obs) {
+        observers[obs.id_] = obs;
+        observerCount++;
+        obs.iterateObjects_(observe);
+      },
+      close: function(obs) {
+        var anyLeft = false;
+
+        observers[obs.id_] = undefined;
+        observerCount--;
+
+        if (observerCount) {
+          scheduleReset();
+          return;
+        }
+        resetNeeded = false;
+
+        for (var i = 0; i < objects.length; i++) {
+          Object.unobserve(objects[i], callback);
+          Observer.unobservedCount++;
+        }
+
+        observers.length = 0;
+        objects.length = 0;
+        observedSetCache.push(this);
+      },
+      reset: scheduleReset
+    };
+
+    return record;
+  }
+
+  var lastObservedSet;
+
+  function getObservedSet(observer, obj) {
+    if (!lastObservedSet || lastObservedSet.object !== obj) {
+      lastObservedSet = observedSetCache.pop() || newObservedSet();
+      lastObservedSet.object = obj;
+    }
+    lastObservedSet.open(observer);
+    return lastObservedSet;
+  }
+
+  var UNOPENED = 0;
+  var OPENED = 1;
+  var CLOSED = 2;
+  var RESETTING = 3;
+
+  var nextObserverId = 1;
+
+  function Observer() {
+    this.state_ = UNOPENED;
+    this.callback_ = undefined;
+    this.target_ = undefined; // TODO(rafaelw): Should be WeakRef
+    this.directObserver_ = undefined;
+    this.value_ = undefined;
+    this.id_ = nextObserverId++;
   }
 
   Observer.prototype = {
-    internalCallback: function(records) {
-      if (this.closed)
-        return;
-      if (this.reporting && this.check(records)) {
-        this.report();
-        if (this.testingResults)
-          this.testingResults.anyChanged = true;
-      }
+    open: function(callback, target) {
+      if (this.state_ != UNOPENED)
+        throw Error('Observer has already been opened.');
+
+      addToAll(this);
+      this.callback_ = callback;
+      this.target_ = target;
+      this.state_ = OPENED;
+      this.connect_();
+      return this.value_;
     },
 
     close: function() {
-      if (this.closed)
-        return;
-      if (this.object && typeof this.object.close === 'function')
-        this.object.close();
-
-      this.disconnect();
-      this.object = undefined;
-      this.closed = true;
-    },
-
-    deliver: function(testingResults) {
-      if (this.closed)
-        return;
-      if (hasObserve) {
-        this.testingResults = testingResults;
-        Object.deliverChangeRecords(this.boundInternalCallback);
-        this.testingResults = undefined;
-      } else {
-        dirtyCheck(this);
-      }
-    },
-
-    report: function() {
-      if (!this.reporting)
+      if (this.state_ != OPENED)
         return;
 
-      this.sync(false);
-      if (this.callback) {
-        this.reportArgs.push(this.token);
-        this.invokeCallback(this.reportArgs);
-      }
-      this.reportArgs = undefined;
+      removeFromAll(this);
+      this.state_ = CLOSED;
+      this.disconnect_();
+      this.value_ = undefined;
+      this.callback_ = undefined;
+      this.target_ = undefined;
     },
 
-    invokeCallback: function(args) {
+    deliver: function() {
+      if (this.state_ != OPENED)
+        return;
+
+      dirtyCheck(this);
+    },
+
+    report_: function(changes) {
       try {
-        this.callback.apply(this.target, args);
+        this.callback_.apply(this.target_, changes);
       } catch (ex) {
         Observer._errorThrownDuringCallback = true;
-        console.error('Exception caught during observer callback: ' + (ex.stack || ex));
+        console.error('Exception caught during observer callback: ' +
+                       (ex.stack || ex));
       }
     },
 
-    reset: function() {
-      if (this.closed)
-        return;
-
-      if (hasObserve) {
-        this.reporting = false;
-        Object.deliverChangeRecords(this.boundInternalCallback);
-        this.reporting = true;
-      }
-
-      this.sync(true);
+    discardChanges: function() {
+      this.check_(undefined, true);
+      return this.value_;
     }
   }
 
-  var collectObservers = !hasObserve || global.forceCollectObservers;
+  var collectObservers = !hasObserve;
   var allObservers;
   Observer._allObserversCount = 0;
 
@@ -458,11 +643,15 @@
   }
 
   function addToAll(observer) {
+    Observer._allObserversCount++;
     if (!collectObservers)
       return;
 
     allObservers.push(observer);
-    Observer._allObserversCount++;
+  }
+
+  function removeFromAll(observer) {
+    Observer._allObserversCount--;
   }
 
   var runningMicrotaskCheckpoint = false;
@@ -486,34 +675,31 @@
     runningMicrotaskCheckpoint = true;
 
     var cycles = 0;
-    var results = {};
+    var anyChanged, toCheck;
 
     do {
       cycles++;
-      var toCheck = allObservers;
+      toCheck = allObservers;
       allObservers = [];
-      results.anyChanged = false;
+      anyChanged = false;
 
       for (var i = 0; i < toCheck.length; i++) {
         var observer = toCheck[i];
-        if (observer.closed)
+        if (observer.state_ != OPENED)
           continue;
 
-        if (hasObserve) {
-          observer.deliver(results);
-        } else if (observer.check()) {
-          results.anyChanged = true;
-          observer.report();
-        }
+        if (observer.check_())
+          anyChanged = true;
 
         allObservers.push(observer);
       }
-    } while (cycles < MAX_DIRTY_CHECK_CYCLES && results.anyChanged);
+      if (runEOMTasks())
+        anyChanged = true;
+    } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
 
     if (global.testingExposeCycleCount)
       global.dirtyCheckCycleCount = cycles;
 
-    Observer._allObserversCount = allObservers.length;
     runningMicrotaskCheckpoint = false;
   };
 
@@ -523,26 +709,38 @@
     };
   }
 
-  function ObjectObserver(object, callback, target, token) {
-    Observer.call(this, object, callback, target, token);
-    this.connect();
-    this.sync(true);
+  function ObjectObserver(object) {
+    Observer.call(this);
+    this.value_ = object;
+    this.oldObject_ = undefined;
   }
 
   ObjectObserver.prototype = createObject({
     __proto__: Observer.prototype,
 
-    connect: function() {
-      if (hasObserve)
-        Object.observe(this.object, this.boundInternalCallback);
+    arrayObserve: false,
+
+    connect_: function(callback, target) {
+      if (hasObserve) {
+        this.directObserver_ = getObservedObject(this, this.value_,
+                                                 this.arrayObserve);
+      } else {
+        this.oldObject_ = this.copyObject(this.value_);
+      }
+
     },
 
-    sync: function(hard) {
-      if (!hasObserve)
-        this.oldObject = copyObject(this.object);
+    copyObject: function(object) {
+      var copy = Array.isArray(object) ? [] : {};
+      for (var prop in object) {
+        copy[prop] = object[prop];
+      };
+      if (Array.isArray(object))
+        copy.length = object.length;
+      return copy;
     },
 
-    check: function(changeRecords) {
+    check_: function(changeRecords, skipChanges) {
       var diff;
       var oldValues;
       if (hasObserve) {
@@ -550,67 +748,94 @@
           return false;
 
         oldValues = {};
-        diff = diffObjectFromChangeRecords(this.object, changeRecords,
+        diff = diffObjectFromChangeRecords(this.value_, changeRecords,
                                            oldValues);
       } else {
-        oldValues = this.oldObject;
-        diff = diffObjectFromOldObject(this.object, this.oldObject);
+        oldValues = this.oldObject_;
+        diff = diffObjectFromOldObject(this.value_, this.oldObject_);
       }
 
       if (diffIsEmpty(diff))
         return false;
 
-      this.reportArgs =
-          [diff.added || {}, diff.removed || {}, diff.changed || {}];
-      this.reportArgs.push(function(property) {
-        return oldValues[property];
-      });
+      if (!hasObserve)
+        this.oldObject_ = this.copyObject(this.value_);
+
+      this.report_([
+        diff.added || {},
+        diff.removed || {},
+        diff.changed || {},
+        function(property) {
+          return oldValues[property];
+        }
+      ]);
 
       return true;
     },
 
-    disconnect: function() {
-      if (!hasObserve)
-        this.oldObject = undefined;
-      else if (this.object)
-        Object.unobserve(this.object, this.boundInternalCallback);
+    disconnect_: function() {
+      if (hasObserve) {
+        this.directObserver_.close();
+        this.directObserver_ = undefined;
+      } else {
+        this.oldObject_ = undefined;
+      }
+    },
+
+    deliver: function() {
+      if (this.state_ != OPENED)
+        return;
+
+      if (hasObserve)
+        this.directObserver_.deliver(false);
+      else
+        dirtyCheck(this);
+    },
+
+    discardChanges: function() {
+      if (this.directObserver_)
+        this.directObserver_.deliver(true);
+      else
+        this.oldObject_ = this.copyObject(this.value_);
+
+      return this.value_;
     }
   });
 
-  function ArrayObserver(array, callback, target, token) {
+  function ArrayObserver(array) {
     if (!Array.isArray(array))
       throw Error('Provided object is not an Array');
-    ObjectObserver.call(this, array, callback, target, token);
+    ObjectObserver.call(this, array);
   }
 
   ArrayObserver.prototype = createObject({
+
     __proto__: ObjectObserver.prototype,
 
-    connect: function() {
-      if (hasObserve)
-        Array.observe(this.object, this.boundInternalCallback);
+    arrayObserve: true,
+
+    copyObject: function(arr) {
+      return arr.slice();
     },
 
-    sync: function() {
-      if (!hasObserve)
-        this.oldObject = this.object.slice();
-    },
-
-    check: function(changeRecords) {
+    check_: function(changeRecords) {
       var splices;
       if (hasObserve) {
         if (!changeRecords)
           return false;
-        splices = projectArraySplices(this.object, changeRecords);
+        splices = projectArraySplices(this.value_, changeRecords);
       } else {
-        splices = calcSplices(this.object, 0, this.object.length,
-                              this.oldObject, 0, this.oldObject.length);
+        splices = calcSplices(this.value_, 0, this.value_.length,
+                              this.oldObject_, 0, this.oldObject_.length);
       }
 
       if (!splices || !splices.length)
         return false;
 
-      this.reportArgs = [splices];
+      if (!hasObserve)
+        this.oldObject_ = this.copyObject(this.value_);
+
+      this.report_([splices]);
       return true;
     }
   });
@@ -628,255 +853,247 @@
     });
   };
 
-  function ObservedSet(callback) {
-    this.arr = [];
-    this.callback = callback;
-    this.isObserved = true;
-  }
+  function PathObserver(object, path) {
+    Observer.call(this);
 
-  // TODO(rafaelw): Consider surfacing a way to avoid observing prototype
-  // ancestors which are expected not to change (e.g. Element, Node...).
-  var objProto = Object.getPrototypeOf({});
-  var arrayProto = Object.getPrototypeOf([]);
-  ObservedSet.prototype = {
-    reset: function() {
-      this.isObserved = !this.isObserved;
-    },
-
-    observe: function(obj) {
-      if (!isObject(obj) || obj === objProto || obj === arrayProto)
-        return;
-      var i = this.arr.indexOf(obj);
-      if (i >= 0 && this.arr[i+1] === this.isObserved)
-        return;
-
-      if (i < 0) {
-        i = this.arr.length;
-        this.arr[i] = obj;
-        Object.observe(obj, this.callback);
-      }
-
-      this.arr[i+1] = this.isObserved;
-      this.observe(Object.getPrototypeOf(obj));
-    },
-
-    cleanup: function() {
-      var i = 0, j = 0;
-      var isObserved = this.isObserved;
-      while(j < this.arr.length) {
-        var obj = this.arr[j];
-        if (this.arr[j + 1] == isObserved) {
-          if (i < j) {
-            this.arr[i] = obj;
-            this.arr[i + 1] = isObserved;
-          }
-          i += 2;
-        } else {
-          Object.unobserve(obj, this.callback);
-        }
-        j += 2;
-      }
-
-      this.arr.length = i;
-    }
-  };
-
-  function PathObserver(object, path, callback, target, token, valueFn,
-                        setValueFn) {
-    var path = path instanceof Path ? path : getPath(path);
-    if (!path || !path.length || !isObject(object)) {
-      this.value_ = path ? path.getValueFrom(object) : undefined;
-      this.value = valueFn ? valueFn(this.value_) : this.value_;
-      this.closed = true;
-      return;
-    }
-
-    Observer.call(this, object, callback, target, token);
-    this.valueFn = valueFn;
-    this.setValueFn = setValueFn;
-    this.path = path;
-
-    this.connect();
-    this.sync(true);
+    this.object_ = object;
+    this.path_ = path instanceof Path ? path : getPath(path);
+    this.directObserver_ = undefined;
   }
 
   PathObserver.prototype = createObject({
     __proto__: Observer.prototype,
 
-    connect: function() {
+    connect_: function() {
       if (hasObserve)
-        this.observedSet = new ObservedSet(this.boundInternalCallback);
+        this.directObserver_ = getObservedSet(this, this.object_);
+
+      this.check_(undefined, true);
     },
 
-    disconnect: function() {
-      this.value = undefined;
+    disconnect_: function() {
       this.value_ = undefined;
-      if (this.observedSet) {
-        this.observedSet.reset();
-        this.observedSet.cleanup();
-        this.observedSet = undefined;
+
+      if (this.directObserver_) {
+        this.directObserver_.close(this);
+        this.directObserver_ = undefined;
       }
     },
 
-    check: function() {
-      // Note: Extracting this to a member function for use here and below
-      // regresses dirty-checking path perf by about 25% =-(.
-      if (this.observedSet)
-        this.observedSet.reset();
+    iterateObjects_: function(observe) {
+      this.path_.iterateObjects(this.object_, observe);
+    },
 
-      this.value_ = this.path.getValueFrom(this.object, this.observedSet);
-
-      if (this.observedSet)
-        this.observedSet.cleanup();
-
-      if (areSameValue(this.value_, this.oldValue_))
+    check_: function(changeRecords, skipChanges) {
+      var oldValue = this.value_;
+      this.value_ = this.path_.getValueFrom(this.object_);
+      if (skipChanges || areSameValue(this.value_, oldValue))
         return false;
 
-      this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
-      this.reportArgs = [this.value, this.oldValue];
+      this.report_([this.value_, oldValue]);
       return true;
     },
 
-    sync: function(hard) {
-      if (hard) {
-        if (this.observedSet)
-          this.observedSet.reset();
-
-        this.value_ = this.path.getValueFrom(this.object, this.observedSet);
-        this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
-
-        if (this.observedSet)
-          this.observedSet.cleanup();
-      }
-
-      this.oldValue_ = this.value_;
-      this.oldValue = this.value;
-    },
-
     setValue: function(newValue) {
-      if (!this.path)
-        return;
-      if (typeof this.setValueFn === 'function')
-        newValue = this.setValueFn(newValue);
-      this.path.setValueFrom(this.object, newValue);
+      if (this.path_)
+        this.path_.setValueFrom(this.object_, newValue);
     }
   });
 
-  function CompoundPathObserver(callback, target, token, valueFn) {
-    Observer.call(this, undefined, callback, target, token);
-    this.valueFn = valueFn;
+  function CompoundObserver() {
+    Observer.call(this);
 
-    this.observed = [];
-    this.values = [];
-    this.value = undefined;
-    this.oldValue = undefined;
-    this.oldValues = undefined;
-    this.changeFlags = undefined;
-    this.started = false;
+    this.value_ = [];
+    this.directObserver_ = undefined;
+    this.observed_ = [];
   }
 
-  CompoundPathObserver.prototype = createObject({
-    __proto__: PathObserver.prototype,
+  var observerSentinel = {};
 
-    // TODO(rafaelw): Consider special-casing when |object| is a PathObserver
-    // and path 'value' to avoid explicit observation.
-    addPath: function(object, path) {
-      if (this.started)
-        throw Error('Cannot add more paths once started.');
+  CompoundObserver.prototype = createObject({
+    __proto__: Observer.prototype,
 
-      var path = path instanceof Path ? path : getPath(path);
-      var value = path ? path.getValueFrom(object) : undefined;
+    connect_: function() {
+      this.check_(undefined, true);
 
-      this.observed.push(object, path);
-      this.values.push(value);
-    },
+      if (!hasObserve)
+        return;
 
-    start: function() {
-      this.started = true;
-      this.connect();
-      this.sync(true);
-    },
-
-    getValues: function() {
-      if (this.observedSet)
-        this.observedSet.reset();
-
-      var anyChanged = false;
-      for (var i = 0; i < this.observed.length; i = i+2) {
-        var path = this.observed[i+1];
-        if (!path)
-          continue;
-        var object = this.observed[i];
-        var value = path.getValueFrom(object, this.observedSet);
-        var oldValue = this.values[i/2];
-        if (!areSameValue(value, oldValue)) {
-          if (!anyChanged && !this.valueFn) {
-            this.oldValues = this.oldValues || [];
-            this.changeFlags = this.changeFlags || [];
-            for (var j = 0; j < this.values.length; j++) {
-              this.oldValues[j] = this.values[j];
-              this.changeFlags[j] = false;
-            }
-          }
-
-          if (!this.valueFn)
-            this.changeFlags[i/2] = true;
-
-          this.values[i/2] = value;
-          anyChanged = true;
+      var object;
+      var needsDirectObserver = false;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        object = this.observed_[i]
+        if (object !== observerSentinel) {
+          needsDirectObserver = true;
+          break;
         }
       }
 
-      if (this.observedSet)
-        this.observedSet.cleanup();
-
-      return anyChanged;
-    },
-
-    check: function() {
-      if (!this.getValues())
+      if (this.directObserver_) {
+        if (needsDirectObserver) {
+          this.directObserver_.reset();
+          return;
+        }
+        this.directObserver_.close();
+        this.directObserver_ = undefined;
         return;
-
-      if (this.valueFn) {
-        this.value = this.valueFn(this.values);
-
-        if (areSameValue(this.value, this.oldValue))
-          return false;
-
-        this.reportArgs = [this.value, this.oldValue];
-      } else {
-        this.reportArgs = [this.values, this.oldValues, this.changeFlags,
-                           this.observed];
       }
 
-      return true;
+      if (needsDirectObserver)
+        this.directObserver_ = getObservedSet(this, object);
     },
 
-    sync: function(hard) {
-      if (hard) {
-        this.getValues();
-        if (this.valueFn)
-          this.value = this.valueFn(this.values);
+    closeObservers_: function() {
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        if (this.observed_[i] === observerSentinel)
+          this.observed_[i + 1].close();
+      }
+      this.observed_.length = 0;
+    },
+
+    disconnect_: function() {
+      this.value_ = undefined;
+
+      if (this.directObserver_) {
+        this.directObserver_.close(this);
+        this.directObserver_ = undefined;
       }
 
-      if (this.valueFn)
-        this.oldValue = this.value;
+      this.closeObservers_();
+    },
+
+    addPath: function(object, path) {
+      if (this.state_ != UNOPENED && this.state_ != RESETTING)
+        throw Error('Cannot add paths once started.');
+
+      this.observed_.push(object, path instanceof Path ? path : getPath(path));
+    },
+
+    addObserver: function(observer) {
+      if (this.state_ != UNOPENED && this.state_ != RESETTING)
+        throw Error('Cannot add observers once started.');
+
+      observer.open(this.deliver, this);
+      this.observed_.push(observerSentinel, observer);
+    },
+
+    startReset: function() {
+      if (this.state_ != OPENED)
+        throw Error('Can only reset while open');
+
+      this.state_ = RESETTING;
+      this.closeObservers_();
+    },
+
+    finishReset: function() {
+      if (this.state_ != RESETTING)
+        throw Error('Can only finishReset after startReset');
+      this.state_ = OPENED;
+      this.connect_();
+
+      return this.value_;
+    },
+
+    iterateObjects_: function(observe) {
+      var object;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        object = this.observed_[i]
+        if (object !== observerSentinel)
+          this.observed_[i + 1].iterateObjects(object, observe)
+      }
+    },
+
+    check_: function(changeRecords, skipChanges) {
+      var oldValues;
+      for (var i = 0; i < this.observed_.length; i += 2) {
+        var pathOrObserver = this.observed_[i+1];
+        var object = this.observed_[i];
+        var value = object === observerSentinel ?
+            pathOrObserver.discardChanges() :
+            pathOrObserver.getValueFrom(object)
+
+        if (skipChanges) {
+          this.value_[i / 2] = value;
+          continue;
+        }
+
+        if (areSameValue(value, this.value_[i / 2]))
+          continue;
+
+        oldValues = oldValues || [];
+        oldValues[i / 2] = this.value_[i / 2];
+        this.value_[i / 2] = value;
+      }
+
+      if (!oldValues)
+        return false;
+
+      // TODO(rafaelw): Having observed_ as the third callback arg here is
+      // pretty lame API. Fix.
+      this.report_([this.value_, oldValues, this.observed_]);
+      return true;
+    }
+  });
+
+  function identFn(value) { return value; }
+
+  function ObserverTransform(observable, getValueFn, setValueFn,
+                             dontPassThroughSet) {
+    this.callback_ = undefined;
+    this.target_ = undefined;
+    this.value_ = undefined;
+    this.observable_ = observable;
+    this.getValueFn_ = getValueFn || identFn;
+    this.setValueFn_ = setValueFn || identFn;
+    // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this
+    // at the moment because of a bug in it's dependency tracking.
+    this.dontPassThroughSet_ = dontPassThroughSet;
+  }
+
+  ObserverTransform.prototype = {
+    open: function(callback, target) {
+      this.callback_ = callback;
+      this.target_ = target;
+      this.value_ =
+          this.getValueFn_(this.observable_.open(this.observedCallback_, this));
+      return this.value_;
+    },
+
+    observedCallback_: function(value) {
+      value = this.getValueFn_(value);
+      if (areSameValue(value, this.value_))
+        return;
+      var oldValue = this.value_;
+      this.value_ = value;
+      this.callback_.call(this.target_, this.value_, oldValue);
+    },
+
+    discardChanges: function() {
+      this.value_ = this.getValueFn_(this.observable_.discardChanges());
+      return this.value_;
+    },
+
+    deliver: function() {
+      return this.observable_.deliver();
+    },
+
+    setValue: function(value) {
+      value = this.setValueFn_(value);
+      if (!this.dontPassThroughSet_ && this.observable_.setValue)
+        return this.observable_.setValue(value);
     },
 
     close: function() {
-      if (this.observed) {
-        for (var i = 0; i < this.observed.length; i = i + 2) {
-          var object = this.observed[i];
-          if (object && typeof object.close === 'function')
-            object.close();
-        }
-        this.observed = undefined;
-        this.values = undefined;
-      }
-
-      Observer.prototype.close.call(this);
+      if (this.observable_)
+        this.observable_.close();
+      this.callback_ = undefined;
+      this.target_ = undefined;
+      this.observable_ = undefined;
+      this.value_ = undefined;
+      this.getValueFn_ = undefined;
+      this.setValueFn_ = undefined;
     }
-  });
+  }
 
   var expectedRecordTypes = {};
   expectedRecordTypes[PROP_ADD_TYPE] = true;
@@ -900,40 +1117,31 @@
     }
   }
 
-  // TODO(rafaelw): It should be possible for the Object.observe case to have
-  // every PathObserver used by defineProperty share a single Object.observe
-  // callback, and thus get() can simply call observer.deliver() and any changes
-  // to any dependent value will be observed.
-  PathObserver.defineProperty = function(target, name, object, path) {
-    // TODO(rafaelw): Validate errors
-    path = getPath(path);
+  Observer.defineComputedProperty = function(target, name, observable) {
     var notify = notifyFunction(target, name);
-
-    var observer = new PathObserver(object, path,
-        function(newValue, oldValue) {
-          if (notify)
-            notify(PROP_UPDATE_TYPE, oldValue);
-        }
-    );
+    var value = observable.open(function(newValue, oldValue) {
+      value = newValue;
+      if (notify)
+        notify(PROP_UPDATE_TYPE, oldValue);
+    });
 
     Object.defineProperty(target, name, {
       get: function() {
-        return path.getValueFrom(object);
+        observable.deliver();
+        return value;
       },
       set: function(newValue) {
-        path.setValueFrom(object, newValue);
+        observable.setValue(newValue);
+        return newValue;
       },
       configurable: true
     });
 
     return {
       close: function() {
-        var oldValue = path.getValueFrom(object);
-        if (notify)
-          observer.deliver();
-        observer.close();
+        observable.close();
         Object.defineProperty(target, name, {
-          value: oldValue,
+          value: value,
           writable: true,
           configurable: true
         });
@@ -1397,6 +1605,7 @@
   }
 
   global.Observer = Observer;
+  global.Observer.runEOM_ = runEOM;
   global.Observer.hasObjectObserve = hasObserve;
   global.ArrayObserver = ArrayObserver;
   global.ArrayObserver.calculateSplices = function(current, previous) {
@@ -1406,8 +1615,9 @@
   global.ArraySplice = ArraySplice;
   global.ObjectObserver = ObjectObserver;
   global.PathObserver = PathObserver;
-  global.CompoundPathObserver = CompoundPathObserver;
+  global.CompoundObserver = CompoundObserver;
   global.Path = Path;
+  global.ObserverTransform = ObserverTransform;
 
   // TODO(rafaelw): Only needed for testing until new change record names
   // make it to release.
@@ -1418,7 +1628,7 @@
     'delete': PROP_DELETE_TYPE,
     splice: ARRAY_SPLICE_TYPE
   };
-})(typeof global !== 'undefined' && global ? global : this || window);
+})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
 
 /*
  * Copyright 2012 The Polymer Authors. All rights reserved.
@@ -1708,12 +1918,14 @@
   }
 
   var OriginalDOMImplementation = window.DOMImplementation;
+  var OriginalEventTarget = window.EventTarget;
   var OriginalEvent = window.Event;
   var OriginalNode = window.Node;
   var OriginalWindow = window.Window;
   var OriginalRange = window.Range;
   var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
   var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+  var OriginalSVGElementInstance = window.SVGElementInstance;
 
   function isWrapper(object) {
     return object instanceof wrappers.EventTarget ||
@@ -1726,14 +1938,17 @@
   }
 
   function isNative(object) {
-    return object instanceof OriginalNode ||
+    return OriginalEventTarget && object instanceof OriginalEventTarget ||
+           object instanceof OriginalNode ||
            object instanceof OriginalEvent ||
            object instanceof OriginalWindow ||
            object instanceof OriginalRange ||
            object instanceof OriginalDOMImplementation ||
            object instanceof OriginalCanvasRenderingContext2D ||
            OriginalWebGLRenderingContext &&
-               object instanceof OriginalWebGLRenderingContext;
+               object instanceof OriginalWebGLRenderingContext ||
+           OriginalSVGElementInstance &&
+               object instanceof OriginalSVGElementInstance;
   }
 
   /**
@@ -1832,6 +2047,7 @@
   scope.defineGetter = defineGetter;
   scope.defineWrapGetter = defineWrapGetter;
   scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+  scope.isWrapper = isWrapper;
   scope.isWrapperFor = isWrapperFor;
   scope.mixin = mixin;
   scope.nativePrototypeTable = nativePrototypeTable;
@@ -2287,6 +2503,7 @@
   var wrappedFuns = new WeakMap();
   var listenersTable = new WeakMap();
   var handledEventsTable = new WeakMap();
+  var currentlyDispatchingEvents = new WeakMap();
   var targetTable = new WeakMap();
   var currentTargetTable = new WeakMap();
   var relatedTargetTable = new WeakMap();
@@ -2458,16 +2675,16 @@
       return;
     handledEventsTable.set(originalEvent, true);
 
-    // Render before dispatching the event to ensure that the event path is
-    // correct.
-    scope.renderAllPending();
-
-    var target = wrap(originalEvent.target);
-    var event = wrap(originalEvent);
-    return dispatchEvent(event, target);
+    return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
   }
 
   function dispatchEvent(event, originalWrapperTarget) {
+    if (currentlyDispatchingEvents.get(event))
+      throw new Error('InvalidStateError')
+    currentlyDispatchingEvents.set(event, true);
+
+    // Render to ensure that the event path is correct.
+    scope.renderAllPending();
     var eventPath = retarget(originalWrapperTarget);
 
     // For window load events the load event is dispatched at the window but
@@ -2491,7 +2708,8 @@
     }
 
     eventPhaseTable.set(event, Event.NONE);
-    currentTargetTable.set(event, null);
+    currentTargetTable.delete(event, null);
+    currentlyDispatchingEvents.delete(event);
 
     return event.defaultPrevented;
   }
@@ -2630,7 +2848,12 @@
   };
 
   var OriginalEvent = window.Event;
-  OriginalEvent.prototype.polymerBlackList_ = {returnValue: true};
+  OriginalEvent.prototype.polymerBlackList_ = {
+    returnValue: true,
+    // TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not
+    // support constructable KeyboardEvent so we keep it here for now.
+    keyLocation: true
+  };
 
   /**
    * Creates a new Event wrapper or wraps an existin native Event object.
@@ -2705,14 +2928,16 @@
     if (prototype)
       mixin(GenericEvent.prototype, prototype);
     if (OriginalEvent) {
-      // IE does not support event constructors but FocusEvent can only be
-      // created using new FocusEvent in Firefox.
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=882165
-      if (OriginalEvent.prototype['init' + name]) {
+      // - Old versions of Safari fails on new FocusEvent (and others?).
+      // - IE does not support event constructors.
+      // - createEvent('FocusEvent') throws in Firefox.
+      // => Try the best practice solution first and fallback to the old way
+      // if needed.
+      try {
+        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
+      } catch (ex) {
         registerWrapper(OriginalEvent, GenericEvent,
                         document.createEvent(name));
-      } else {
-        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
       }
     }
     return GenericEvent;
@@ -2753,7 +2978,7 @@
 
   var supportsEventConstructors = (function() {
     try {
-      new window.MouseEvent('click');
+      new window.FocusEvent('focus');
     } catch (ex) {
       return false;
     }
@@ -2924,16 +3149,62 @@
       }
     },
     dispatchEvent: function(event) {
-      var target = getTargetToListenAt(this);
+      // We want to use the native dispatchEvent because it triggers the default
+      // actions (like checking a checkbox). However, if there are no listeners
+      // in the composed tree then there are no events that will trigger and
+      // listeners in the non composed tree that are part of the event path are
+      // not notified.
+      //
+      // If we find out that there are no listeners in the composed tree we add
+      // a temporary listener to the target which makes us get called back even
+      // in that case.
+
       var nativeEvent = unwrap(event);
+      var eventType = nativeEvent.type;
+
       // Allow dispatching the same event again. This is safe because if user
       // code calls this during an existing dispatch of the same event the
       // native dispatchEvent throws (that is required by the spec).
       handledEventsTable.set(nativeEvent, false);
-      return target.dispatchEvent_(nativeEvent);
+
+      // Force rendering since we prefer native dispatch and that works on the
+      // composed tree.
+      scope.renderAllPending();
+
+      var tempListener;
+      if (!hasListenerInAncestors(this, eventType)) {
+        tempListener = function() {};
+        this.addEventListener(eventType, tempListener, true);
+      }
+
+      try {
+        return unwrap(this).dispatchEvent_(nativeEvent);
+      } finally {
+        if (tempListener)
+          this.removeEventListener(eventType, tempListener, true);
+      }
     }
   };
 
+  function hasListener(node, type) {
+    var listeners = listenersTable.get(node);
+    if (listeners) {
+      for (var i = 0; i < listeners.length; i++) {
+        if (!listeners[i].removed && listeners[i].type === type)
+          return true;
+      }
+    }
+    return false;
+  }
+
+  function hasListenerInAncestors(target, type) {
+    for (var node = unwrap(target); node; node = node.parentNode) {
+      if (hasListener(wrap(node), type))
+        return true;
+    }
+    return false;
+  }
+
   if (OriginalEventTarget)
     registerWrapper(OriginalEventTarget, EventTarget);
 
@@ -3081,6 +3352,7 @@
   var assert = scope.assert;
   var defineWrapGetter = scope.defineWrapGetter;
   var enqueueMutation = scope.enqueueMutation;
+  var isWrapper = scope.isWrapper;
   var mixin = scope.mixin;
   var registerTransientObservers = scope.registerTransientObservers;
   var registerWrapper = scope.registerWrapper;
@@ -3254,6 +3526,18 @@
     return df;
   }
 
+  function clearChildNodes(wrapper) {
+    if (wrapper.firstChild_ !== undefined) {
+      var child = wrapper.firstChild_;
+      while (child) {
+        var tmp = child;
+        child = child.nextSibling_;
+        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+      }
+    }
+    wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+  }
+
   function removeAllChildNodes(wrapper) {
     if (wrapper.invalidateShadowRenderer()) {
       var childWrapper = wrapper.firstChild;
@@ -3286,6 +3570,13 @@
     return p && p.invalidateShadowRenderer();
   }
 
+  function cleanupNodes(nodes) {
+    for (var i = 0, n; i < nodes.length; i++) {
+      n = nodes[i];
+      n.parentNode.removeChild(n);
+    }
+  }
+
   var OriginalNode = window.Node;
 
   /**
@@ -3332,7 +3623,7 @@
      * @private
      */
     this.previousSibling_ = undefined;
-  };
+  }
 
   var OriginalDocumentFragment = window.DocumentFragment;
   var originalAppendChild = OriginalNode.prototype.appendChild;
@@ -3366,8 +3657,19 @@
     insertBefore: function(childWrapper, refWrapper) {
       assertIsNodeWrapper(childWrapper);
 
-      refWrapper = refWrapper || null;
-      refWrapper && assertIsNodeWrapper(refWrapper);
+      var refNode;
+      if (refWrapper) {
+        if (isWrapper(refWrapper)) {
+          refNode = unwrap(refWrapper);
+        } else {
+          refNode = refWrapper;
+          refWrapper = wrap(refNode);
+        }
+      } else {
+        refWrapper = null;
+        refNode = null;
+      }
+
       refWrapper && assert(refWrapper.parentNode === this);
 
       var nodes;
@@ -3384,15 +3686,14 @@
 
       if (useNative) {
         ensureSameOwnerDocument(this, childWrapper);
-        originalInsertBefore.call(this.impl, unwrap(childWrapper),
-                                  unwrap(refWrapper));
+        clearChildNodes(this);
+        originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);
       } else {
         if (!previousNode)
           this.firstChild_ = nodes[0];
         if (!refWrapper)
           this.lastChild_ = nodes[nodes.length - 1];
 
-        var refNode = unwrap(refWrapper);
         var parentNode = refNode ? refNode.parentNode : this.impl;
 
         // insertBefore refWrapper no matter what the parent is?
@@ -3463,6 +3764,7 @@
         childWrapper.previousSibling_ = childWrapper.nextSibling_ =
             childWrapper.parentNode_ = undefined;
       } else {
+        clearChildNodes(this);
         removeChildOriginalHelper(this.impl, childNode);
       }
 
@@ -3481,14 +3783,20 @@
 
     replaceChild: function(newChildWrapper, oldChildWrapper) {
       assertIsNodeWrapper(newChildWrapper);
-      assertIsNodeWrapper(oldChildWrapper);
+
+      var oldChildNode;
+      if (isWrapper(oldChildWrapper)) {
+        oldChildNode = unwrap(oldChildWrapper);
+      } else {
+        oldChildNode = oldChildWrapper;
+        oldChildWrapper = wrap(oldChildNode);
+      }
 
       if (oldChildWrapper.parentNode !== this) {
         // TODO(arv): DOMException
         throw new Error('NotFoundError');
       }
 
-      var oldChildNode = unwrap(oldChildWrapper);
       var nextNode = oldChildWrapper.nextSibling;
       var previousNode = oldChildWrapper.previousSibling;
       var nodes;
@@ -3522,6 +3830,7 @@
         }
       } else {
         ensureSameOwnerDocument(this, newChildWrapper);
+        clearChildNodes(this);
         originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
                                   oldChildNode);
       }
@@ -3598,7 +3907,9 @@
       // are no shadow trees below or above the context node.
       var s = '';
       for (var child = this.firstChild; child; child = child.nextSibling) {
-        s += child.textContent;
+        if (child.nodeType != Node.COMMENT_NODE) {
+          s += child.textContent;
+        }
       }
       return s;
     },
@@ -3612,6 +3923,7 @@
           this.appendChild(textNode);
         }
       } else {
+        clearChildNodes(this);
         this.impl.textContent = textContent;
       }
 
@@ -3666,6 +3978,43 @@
       // This only wraps, it therefore only operates on the composed DOM and not
       // the logical DOM.
       return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));
+    },
+
+    normalize: function() {
+      var nodes = snapshotNodeList(this.childNodes);
+      var remNodes = [];
+      var s = '';
+      var modNode;
+
+      for (var i = 0, n; i < nodes.length; i++) {
+        n = nodes[i];
+        if (n.nodeType === Node.TEXT_NODE) {
+          if (!modNode && !n.data.length)
+            this.removeNode(n);
+          else if (!modNode)
+            modNode = n;
+          else {
+            s += n.data;
+            remNodes.push(n);
+          }
+        } else {
+          if (modNode && remNodes.length) {
+            modNode.data += s;
+            cleanUpNodes(remNodes);
+          }
+          remNodes = [];
+          s = '';
+          modNode = null;
+          if (n.childNodes.length)
+            n.normalize();
+        }
+      }
+
+      // handle case where >1 text nodes are the last children
+      if (modNode && remNodes.length) {
+        modNode.data += s;
+        cleanupNodes(remNodes);
+      }
     }
   });
 
@@ -3878,6 +4227,49 @@
   scope.wrappers.CharacterData = CharacterData;
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var CharacterData = scope.wrappers.CharacterData;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+
+  function toUInt32(x) {
+    return x >>> 0;
+  }
+
+  var OriginalText = window.Text;
+
+  function Text(node) {
+    CharacterData.call(this, node);
+  }
+  Text.prototype = Object.create(CharacterData.prototype);
+  mixin(Text.prototype, {
+    splitText: function(offset) {
+      offset = toUInt32(offset);
+      var s = this.data;
+      if (offset > s.length)
+        throw new Error('IndexSizeError');
+      var head = s.slice(0, offset);
+      var tail = s.slice(offset);
+      this.data = head;
+      var newTextNode = this.ownerDocument.createTextNode(tail);
+      if (this.parentNode)
+        this.parentNode.insertBefore(newTextNode, this.nextSibling);
+      return newTextNode;
+    }
+  });
+
+  registerWrapper(OriginalText, Text, document.createTextNode(''));
+
+  scope.wrappers.Text = Text;
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -3899,12 +4291,16 @@
 
   var OriginalElement = window.Element;
 
-  var matchesName = oneOf(OriginalElement.prototype, [
-    'matches',
+  var matchesNames = [
+    'matches',  // needs to come first.
     'mozMatchesSelector',
     'msMatchesSelector',
     'webkitMatchesSelector',
-  ]);
+  ].filter(function(name) {
+    return OriginalElement.prototype[name];
+  });
+
+  var matchesName = matchesNames[0];
 
   var originalMatches = OriginalElement.prototype[matchesName];
 
@@ -3968,9 +4364,13 @@
     }
   });
 
-  Element.prototype[matchesName] = function(selector) {
-    return this.matches(selector);
-  };
+  matchesNames.forEach(function(name) {
+    if (name !== 'matches') {
+      Element.prototype[name] = function(selector) {
+        return this.matches(selector);
+      };
+    }
+  });
 
   if (OriginalElement.prototype.webkitCreateShadowRoot) {
     Element.prototype.webkitCreateShadowRoot =
@@ -4004,11 +4404,12 @@
   mixin(Element.prototype, ParentNodeInterface);
   mixin(Element.prototype, SelectorsInterface);
 
-  registerWrapper(OriginalElement, Element);
+  registerWrapper(OriginalElement, Element,
+                  document.createElementNS(null, 'x'));
 
   // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
   // that reflect attributes.
-  scope.matchesName = matchesName;
+  scope.matchesNames = matchesNames;
   scope.wrappers.Element = Element;
 })(window.ShadowDOMPolyfill);
 
@@ -4033,7 +4434,9 @@
   /////////////////////////////////////////////////////////////////////////////
   // innerHTML and outerHTML
 
-  var escapeRegExp = /&|<|"/g;
+  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
+  var escapeAttrRegExp = /[&\u00A0"]/g;
+  var escapeDataRegExp = /[&\u00A0<>]/g;
 
   function escapeReplace(c) {
     switch (c) {
@@ -4041,43 +4444,70 @@
         return '&amp;';
       case '<':
         return '&lt;';
+      case '>':
+        return '&gt;';
       case '"':
         return '&quot;'
+      case '\u00A0':
+        return '&nbsp;';
     }
   }
 
-  function escape(s) {
-    return s.replace(escapeRegExp, escapeReplace);
+  function escapeAttr(s) {
+    return s.replace(escapeAttrRegExp, escapeReplace);
+  }
+
+  function escapeData(s) {
+    return s.replace(escapeDataRegExp, escapeReplace);
+  }
+
+  function makeSet(arr) {
+    var set = {};
+    for (var i = 0; i < arr.length; i++) {
+      set[arr[i]] = true;
+    }
+    return set;
   }
 
   // http://www.whatwg.org/specs/web-apps/current-work/#void-elements
-  var voidElements = {
-    'area': true,
-    'base': true,
-    'br': true,
-    'col': true,
-    'command': true,
-    'embed': true,
-    'hr': true,
-    'img': true,
-    'input': true,
-    'keygen': true,
-    'link': true,
-    'meta': true,
-    'param': true,
-    'source': true,
-    'track': true,
-    'wbr': true
-  };
+  var voidElements = makeSet([
+    'area',
+    'base',
+    'br',
+    'col',
+    'command',
+    'embed',
+    'hr',
+    'img',
+    'input',
+    'keygen',
+    'link',
+    'meta',
+    'param',
+    'source',
+    'track',
+    'wbr'
+  ]);
 
-  function getOuterHTML(node) {
+  var plaintextParents = makeSet([
+    'style',
+    'script',
+    'xmp',
+    'iframe',
+    'noembed',
+    'noframes',
+    'plaintext',
+    'noscript'
+  ]);
+
+  function getOuterHTML(node, parentNode) {
     switch (node.nodeType) {
       case Node.ELEMENT_NODE:
         var tagName = node.tagName.toLowerCase();
         var s = '<' + tagName;
         var attrs = node.attributes;
         for (var i = 0, attr; attr = attrs[i]; i++) {
-          s += ' ' + attr.name + '="' + escape(attr.value) + '"';
+          s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
         }
         s += '>';
         if (voidElements[tagName])
@@ -4086,10 +4516,14 @@
         return s + getInnerHTML(node) + '</' + tagName + '>';
 
       case Node.TEXT_NODE:
-        return escape(node.nodeValue);
+        var data = node.data;
+        if (parentNode && plaintextParents[parentNode.localName])
+          return data;
+        return escapeData(data);
 
       case Node.COMMENT_NODE:
-        return '<!--' + escape(node.nodeValue) + '-->';
+        return '<!--' + node.data + '-->';
+
       default:
         console.error(node);
         throw new Error('not implemented');
@@ -4099,7 +4533,7 @@
   function getInnerHTML(node) {
     var s = '';
     for (var child = node.firstChild; child; child = child.nextSibling) {
-      s += getOuterHTML(child);
+      s += getOuterHTML(child, node);
     }
     return s;
   }
@@ -4115,6 +4549,9 @@
     }
   }
 
+  // IE11 does not have MSIE in the user agent string.
+  var oldIe = /MSIE/.test(navigator.userAgent);
+
   var OriginalHTMLElement = window.HTMLElement;
 
   function HTMLElement(node) {
@@ -4128,6 +4565,17 @@
       return getInnerHTML(this);
     },
     set innerHTML(value) {
+      // IE9 does not handle set innerHTML correctly on plaintextParents. It
+      // creates element children. For example
+      //
+      //   scriptElement.innerHTML = '<a>test</a>'
+      //
+      // Creates a single HTMLAnchorElement child.
+      if (oldIe && plaintextParents[this.localName]) {
+        this.textContent = value;
+        return;
+      }
+
       var removedNodes = snapshotNodeList(this.childNodes);
 
       if (this.invalidateShadowRenderer())
@@ -4146,19 +4594,57 @@
     },
 
     get outerHTML() {
-      // TODO(arv): This should fallback to HTMLElement_prototype.outerHTML if there
-      // are no shadow trees below or above the context node.
-      return getOuterHTML(this);
+      return getOuterHTML(this, this.parentNode);
     },
     set outerHTML(value) {
       var p = this.parentNode;
       if (p) {
         p.invalidateShadowRenderer();
-        this.impl.outerHTML = value;
+        var df = frag(p, value);
+        p.replaceChild(df, this);
       }
+    },
+
+    insertAdjacentHTML: function(position, text) {
+      var contextElement, refNode;
+      switch (String(position).toLowerCase()) {
+        case 'beforebegin':
+          contextElement = this.parentNode;
+          refNode = this;
+          break;
+        case 'afterend':
+          contextElement = this.parentNode;
+          refNode = this.nextSibling;
+          break;
+        case 'afterbegin':
+          contextElement = this;
+          refNode = this.firstChild;
+          break;
+        case 'beforeend':
+          contextElement = this;
+          refNode = null;
+          break;
+        default:
+          return;
+      }
+
+      var df = frag(contextElement, text);
+      contextElement.insertBefore(df, refNode);
     }
   });
 
+  function frag(contextElement, html) {
+    // TODO(arv): This does not work with SVG and other non HTML elements.
+    var p = unwrap(contextElement.cloneNode(false));
+    p.innerHTML = html;
+    var df = unwrap(document.createDocumentFragment());
+    var c;
+    while (c = p.firstChild) {
+      df.appendChild(c);
+    }
+    return wrap(df);
+  }
+
   function getter(name) {
     return function() {
       scope.renderAllPending();
@@ -4616,6 +5102,138 @@
   scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var registerObject = scope.registerObject;
+
+  var SVG_NS = 'http://www.w3.org/2000/svg';
+  var svgTitleElement = document.createElementNS(SVG_NS, 'title');
+  var SVGTitleElement = registerObject(svgTitleElement);
+  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+
+  scope.wrappers.SVGElement = SVGElement;
+})(window.ShadowDOMPolyfill);
+
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+
+  var OriginalSVGUseElement = window.SVGUseElement;
+
+  // IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses
+  // SVGGraphicsElement. Use the <g> element to get the right prototype.
+
+  var SVG_NS = 'http://www.w3.org/2000/svg';
+  var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));
+  var useElement = document.createElementNS(SVG_NS, 'use');
+  var SVGGElement = gWrapper.constructor;
+  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+  var parentInterface = parentInterfacePrototype.constructor;
+
+  function SVGUseElement(impl) {
+    parentInterface.call(this, impl);
+  }
+
+  SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+
+  // Firefox does not expose instanceRoot.
+  if ('instanceRoot' in useElement) {
+    mixin(SVGUseElement.prototype, {
+      get instanceRoot() {
+        return wrap(unwrap(this).instanceRoot);
+      },
+      get animatedInstanceRoot() {
+        return wrap(unwrap(this).animatedInstanceRoot);
+      },
+    });
+  }
+
+  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+
+  scope.wrappers.SVGUseElement = SVGUseElement;
+})(window.ShadowDOMPolyfill);
+
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var EventTarget = scope.wrappers.EventTarget;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var wrap = scope.wrap;
+
+  var OriginalSVGElementInstance = window.SVGElementInstance;
+  if (!OriginalSVGElementInstance)
+    return;
+
+  function SVGElementInstance(impl) {
+    EventTarget.call(this, impl);
+  }
+
+  SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+  mixin(SVGElementInstance.prototype, {
+    /** @type {SVGElement} */
+    get correspondingElement() {
+      return wrap(this.impl.correspondingElement);
+    },
+
+    /** @type {SVGUseElement} */
+    get correspondingUseElement() {
+      return wrap(this.impl.correspondingUseElement);
+    },
+
+    /** @type {SVGElementInstance} */
+    get parentNode() {
+      return wrap(this.impl.parentNode);
+    },
+
+    /** @type {SVGElementInstanceList} */
+    get childNodes() {
+      throw new Error('Not implemented');
+    },
+
+    /** @type {SVGElementInstance} */
+    get firstChild() {
+      return wrap(this.impl.firstChild);
+    },
+
+    /** @type {SVGElementInstance} */
+    get lastChild() {
+      return wrap(this.impl.lastChild);
+    },
+
+    /** @type {SVGElementInstance} */
+    get previousSibling() {
+      return wrap(this.impl.previousSibling);
+    },
+
+    /** @type {SVGElementInstance} */
+    get nextSibling() {
+      return wrap(this.impl.nextSibling);
+    }
+  });
+
+  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+
+  scope.wrappers.SVGElementInstance = SVGElementInstance;
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -4785,6 +5403,9 @@
     },
     intersectsNode: function(node) {
       return this.impl.intersectsNode(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return this.impl.toString();
     }
   };
 
@@ -4819,12 +5440,10 @@
   mixin(DocumentFragment.prototype, SelectorsInterface);
   mixin(DocumentFragment.prototype, GetElementsByInterface);
 
-  var Text = registerObject(document.createTextNode(''));
   var Comment = registerObject(document.createComment(''));
 
   scope.wrappers.Comment = Comment;
   scope.wrappers.DocumentFragment = DocumentFragment;
-  scope.wrappers.Text = Text;
 
 })(window.ShadowDOMPolyfill);
 
@@ -4846,6 +5465,8 @@
   var shadowHostTable = new WeakMap();
   var nextOlderShadowTreeTable = new WeakMap();
 
+  var spaceCharRe = /[ \t\n\r\f]/;
+
   function ShadowRoot(hostWrapper) {
     var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
     DocumentFragment.call(this, node);
@@ -4886,7 +5507,9 @@
     },
 
     getElementById: function(id) {
-      return this.querySelector('#' + id);
+      if (spaceCharRe.test(id))
+        return null;
+      return this.querySelector('[id="' + id + '"]');
     }
   });
 
@@ -5086,10 +5709,18 @@
     if (!(node instanceof Element))
       return false;
 
+    // The native matches function in IE9 does not correctly work with elements
+    // that are not in the document.
+    // TODO(arv): Implement matching in JS.
+    // https://github.com/Polymer/ShadowDOM/issues/361
+    if (select === '*' || select === node.localName)
+      return true;
+
     // TODO(arv): This does not seem right. Need to check for a simple selector.
     if (!selectorMatchRegExp.test(select))
       return false;
 
+    // TODO(arv): This no longer matches the spec.
     if (select[0] === ':' && !allowedPseudoRegExp.test(select))
       return false;
 
@@ -5606,6 +6237,74 @@
 
 })(window.ShadowDOMPolyfill);
 
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(function(scope) {
+  'use strict';
+
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+
+  var OriginalSelection = window.Selection;
+
+  function Selection(impl) {
+    this.impl = impl;
+  }
+  Selection.prototype = {
+    get anchorNode() {
+      return wrap(this.impl.anchorNode);
+    },
+    get focusNode() {
+      return wrap(this.impl.focusNode);
+    },
+    addRange: function(range) {
+      this.impl.addRange(unwrap(range));
+    },
+    collapse: function(node, index) {
+      this.impl.collapse(unwrapIfNeeded(node), index);
+    },
+    containsNode: function(node, allowPartial) {
+      return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);
+    },
+    extend: function(node, offset) {
+      this.impl.extend(unwrapIfNeeded(node), offset);
+    },
+    getRangeAt: function(index) {
+      return wrap(this.impl.getRangeAt(index));
+    },
+    removeRange: function(range) {
+      this.impl.removeRange(unwrap(range));
+    },
+    selectAllChildren: function(node) {
+      this.impl.selectAllChildren(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return this.impl.toString();
+    }
+  };
+
+  // WebKit extensions. Not implemented.
+  // readonly attribute Node baseNode;
+  // readonly attribute long baseOffset;
+  // readonly attribute Node extentNode;
+  // readonly attribute long extentOffset;
+  // [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
+  //                       [Default=Undefined] optional long baseOffset,
+  //                       [Default=Undefined] optional Node extentNode,
+  //                       [Default=Undefined] optional long extentOffset);
+  // [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,
+  //                  [Default=Undefined] optional long offset);
+
+  registerWrapper(window.Selection, Selection, window.getSelection());
+
+  scope.wrappers.Selection = Selection;
+
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
@@ -5616,14 +6315,17 @@
   var GetElementsByInterface = scope.GetElementsByInterface;
   var Node = scope.wrappers.Node;
   var ParentNodeInterface = scope.ParentNodeInterface;
+  var Selection = scope.wrappers.Selection;
   var SelectorsInterface = scope.SelectorsInterface;
   var ShadowRoot = scope.wrappers.ShadowRoot;
   var defineWrapGetter = scope.defineWrapGetter;
   var elementFromPoint = scope.elementFromPoint;
   var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-  var matchesName = scope.matchesName;
+  var matchesNames = scope.matchesNames;
   var mixin = scope.mixin;
   var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
+  var rewrap = scope.rewrap;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
   var wrapEventTargetMethods = scope.wrapEventTargetMethods;
@@ -5662,7 +6364,7 @@
     'createEventNS',
     'createRange',
     'createTextNode',
-    'getElementById',
+    'getElementById'
   ].forEach(wrapMethod);
 
   var originalAdoptNode = document.adoptNode;
@@ -5689,6 +6391,7 @@
   }
 
   var originalImportNode = document.importNode;
+  var originalGetSelection = document.getSelection;
 
   mixin(Document.prototype, {
     adoptNode: function(node) {
@@ -5710,12 +6413,16 @@
         }
       }
       return clone;
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
     }
   });
 
-  if (document.register) {
-    var originalRegister = document.register;
-    Document.prototype.register = function(tagName, object) {
+  if (document.registerElement) {
+    var originalRegisterElement = document.registerElement;
+    Document.prototype.registerElement = function(tagName, object) {
       var prototype = object.prototype;
 
       // If we already used the object as a prototype for another custom
@@ -5759,14 +6466,19 @@
       // and not from the spec since the spec is out of date.
       [
         'createdCallback',
-        'enteredViewCallback',
-        'leftViewCallback',
+        'attachedCallback',
+        'detachedCallback',
         'attributeChangedCallback',
       ].forEach(function(name) {
         var f = prototype[name];
         if (!f)
           return;
         newPrototype[name] = function() {
+          // if this element has been wrapped prior to registration,
+          // the wrapper is stale; in this case rewrap
+          if (!(wrap(this) instanceof CustomElementConstructor)) {
+            rewrap(this);
+          }
           f.apply(wrap(this), arguments);
         };
       });
@@ -5774,9 +6486,8 @@
       var p = {prototype: newPrototype};
       if (object.extends)
         p.extends = object.extends;
-      var nativeConstructor = originalRegister.call(unwrap(this), tagName, p);
 
-      function GeneratedWrapper(node) {
+      function CustomElementConstructor(node) {
         if (!node) {
           if (object.extends) {
             return document.createElement(object.extends, tagName);
@@ -5786,19 +6497,22 @@
         }
         this.impl = node;
       }
-      GeneratedWrapper.prototype = prototype;
-      GeneratedWrapper.prototype.constructor = GeneratedWrapper;
+      CustomElementConstructor.prototype = prototype;
+      CustomElementConstructor.prototype.constructor = CustomElementConstructor;
 
-      scope.constructorTable.set(newPrototype, GeneratedWrapper);
+      scope.constructorTable.set(newPrototype, CustomElementConstructor);
       scope.nativePrototypeTable.set(prototype, newPrototype);
 
-      return GeneratedWrapper;
+      // registration is synchronous so do it last
+      var nativeConstructor = originalRegisterElement.call(unwrap(this),
+          tagName, p);
+      return CustomElementConstructor;
     };
 
     forwardMethodsToWrapper([
       window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
     ], [
-      'register',
+      'registerElement',
     ]);
   }
 
@@ -5821,8 +6535,7 @@
     'querySelectorAll',
     'removeChild',
     'replaceChild',
-    matchesName,
-  ]);
+  ].concat(matchesNames));
 
   forwardMethodsToWrapper([
     window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
@@ -5840,6 +6553,7 @@
     'createTextNode',
     'elementFromPoint',
     'getElementById',
+    'getSelection',
   ]);
 
   mixin(Document.prototype, GetElementsByInterface);
@@ -5920,40 +6634,56 @@
   'use strict';
 
   var EventTarget = scope.wrappers.EventTarget;
+  var Selection = scope.wrappers.Selection;
   var mixin = scope.mixin;
   var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
   var unwrap = scope.unwrap;
   var unwrapIfNeeded = scope.unwrapIfNeeded;
   var wrap = scope.wrap;
-  var renderAllPending = scope.renderAllPending;
 
   var OriginalWindow = window.Window;
+  var originalGetComputedStyle = window.getComputedStyle;
+  var originalGetSelection = window.getSelection;
 
   function Window(impl) {
     EventTarget.call(this, impl);
   }
   Window.prototype = Object.create(EventTarget.prototype);
 
-  var originalGetComputedStyle = window.getComputedStyle;
   OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
-    renderAllPending();
-    return originalGetComputedStyle.call(this || window, unwrapIfNeeded(el),
-                                         pseudo);
+    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
   };
 
+  OriginalWindow.prototype.getSelection = function() {
+    return wrap(this || window).getSelection();
+  };
+
+  // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
+  delete window.getComputedStyle;
+  delete window.getSelection;
+
   ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
       function(name) {
         OriginalWindow.prototype[name] = function() {
           var w = wrap(this || window);
           return w[name].apply(w, arguments);
         };
+
+        // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
+        delete window[name];
       });
 
   mixin(Window.prototype, {
     getComputedStyle: function(el, pseudo) {
+      renderAllPending();
       return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),
                                            pseudo);
-    }
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
+    },
   });
 
   registerWrapper(OriginalWindow, Window);
@@ -5975,7 +6705,12 @@
   // for.
   var elements = {
     'a': 'HTMLAnchorElement',
-    'applet': 'HTMLAppletElement',
+
+    // Do not create an applet element by default since it shows a warning in
+    // IE.
+    // https://github.com/Polymer/polymer/issues/217
+    // 'applet': 'HTMLAppletElement',
+
     'area': 'HTMLAreaElement',
     'br': 'HTMLBRElement',
     'base': 'HTMLBaseElement',
@@ -6083,6 +6818,10 @@
     }
   });
 
+  // ShadowCSS needs this:
+  window.wrap = window.ShadowDOMPolyfill.wrap;
+  window.unwrap = window.ShadowDOMPolyfill.unwrap;
+
   //TODO(sjmiles): review method alias with Arv
   HTMLElement.prototype.webkitCreateShadowRoot =
       HTMLElement.prototype.createShadowRoot;
@@ -6290,6 +7029,8 @@
 */
 (function(scope) {
 
+var loader = scope.loader;
+
 var ShadowCSS = {
   strictStyling: false,
   registry: {},
@@ -6307,14 +7048,8 @@
     if (this.strictStyling) {
       this.applyScopeToContent(root, name);
     }
-    // insert @polyfill and @polyfill-rule rules into style elements
-    // scoping process takes care of shimming these
-    this.insertPolyfillDirectives(def.rootStyles);
-    this.insertPolyfillRules(def.rootStyles);
-    var cssText = this.stylesToShimmedCssText(def.scopeStyles, name,
-        typeExtension);
-    // note: we only need to do rootStyles since these are unscoped.
-    cssText += this.extractPolyfillUnscopedRules(def.rootStyles);
+    var cssText = this.stylesToShimmedCssText(def.rootStyles, def.scopeStyles,
+        name, typeExtension);
     // provide shimmedStyle for user extensibility
     def.shimmedStyle = cssTextToStyle(cssText);
     if (root) {
@@ -6328,6 +7063,20 @@
     // add style to document
     addCssToDocument(cssText);
   },
+  // apply @polyfill rules + @host and scope shimming
+  stylesToShimmedCssText: function(rootStyles, scopeStyles, name,
+      typeExtension) {
+    name = name || '';
+    // insert @polyfill and @polyfill-rule rules into style elements
+    // scoping process takes care of shimming these
+    this.insertPolyfillDirectives(rootStyles);
+    this.insertPolyfillRules(rootStyles);
+    var cssText = this.shimAtHost(scopeStyles, name, typeExtension) +
+        this.shimScoping(scopeStyles, name, typeExtension);
+    // note: we only need to do rootStyles since these are unscoped.
+    cssText += this.extractPolyfillUnscopedRules(rootStyles);
+    return cssText;
+  },
   registerDefinition: function(root, name, extendsName) {
     var def = this.registry[name] = {
       root: root,
@@ -6446,11 +7195,6 @@
     }
     return r;
   },
-  // apply @host and scope shimming
-  stylesToShimmedCssText: function(styles, name, typeExtension) {
-    return this.shimAtHost(styles, name, typeExtension) +
-        this.shimScoping(styles, name, typeExtension);
-  },
   // form: @host { .foo { declarations } }
   // becomes: scopeName.foo { declarations }
   shimAtHost: function(styles, name, typeExtension) {
@@ -6519,11 +7263,16 @@
     var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
     cssText = this.insertPolyfillHostInCssText(cssText);
     cssText = this.convertColonHost(cssText);
+    cssText = this.convertColonAncestor(cssText);
+    // TODO(sorvell): deprecated, remove
     cssText = this.convertPseudos(cssText);
+    // TODO(sorvell): deprecated, remove
     cssText = this.convertParts(cssText);
     cssText = this.convertCombinators(cssText);
     var rules = cssToRules(cssText);
-    cssText = this.scopeRules(rules, name, typeExtension);
+    if (name) {
+      cssText = this.scopeRules(rules, name, typeExtension);
+    }
     return cssText;
   },
   convertPseudos: function(cssText) {
@@ -6537,29 +7286,40 @@
    *
    * to
    *
+   * scopeName.foo > .bar
+  */
+  convertColonHost: function(cssText) {
+    return this.convertColonRule(cssText, cssColonHostRe,
+        this.colonHostPartReplacer);
+  },
+  /*
+   * convert a rule like :ancestor(.foo) > .bar { }
+   *
+   * to
+   *
    * scopeName.foo > .bar, .foo scopeName > .bar { }
    * 
    * and
    *
-   * :host(.foo:host) .bar { ... }
+   * :ancestor(.foo:host) .bar { ... }
    * 
    * to
    * 
    * scopeName.foo .bar { ... }
   */
-  convertColonHost: function(cssText) {
+  convertColonAncestor: function(cssText) {
+    return this.convertColonRule(cssText, cssColonAncestorRe,
+        this.colonAncestorPartReplacer);
+  },
+  convertColonRule: function(cssText, regExp, partReplacer) {
     // p1 = :host, p2 = contents of (), p3 rest of rule
-    return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
+    return cssText.replace(regExp, function(m, p1, p2, p3) {
       p1 = polyfillHostNoCombinator;
       if (p2) {
         var parts = p2.split(','), r = [];
         for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
           p = p.trim();
-          if (p.match(polyfillHost)) {
-            r.push(p1 + p.replace(polyfillHost, '') + p3);
-          } else {
-            r.push(p1 + p + p3 + ', ' + p + ' ' + p1 + p3);
-          }
+          r.push(partReplacer(p1, p, p3));
         }
         return r.join(',');
       } else {
@@ -6567,6 +7327,16 @@
       }
     });
   },
+  colonAncestorPartReplacer: function(host, part, suffix) {
+    if (part.match(polyfillHost)) {
+      return this.colonHostPartReplacer(host, part, suffix);
+    } else {
+      return host + part + suffix + ', ' + part + ' ' + host + suffix;
+    }
+  },
+  colonHostPartReplacer: function(host, part, suffix) {
+    return host + part.replace(polyfillHost, '') + suffix;
+  },
   /*
    * Convert ^ and ^^ combinators by replacing with space.
   */
@@ -6643,9 +7413,15 @@
   },
   insertPolyfillHostInCssText: function(selector) {
     return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
-        polyfillHost);
+        polyfillHost).replace(colonAncestorRe, polyfillAncestor);
   },
   propertiesFromRule: function(rule) {
+    // TODO(sorvell): Safari cssom incorrectly removes quotes from the content
+    // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
+    if (rule.style.content && !rule.style.content.match(/['"]+/)) {
+      return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' + 
+          rule.style.content + '\';');
+    }
     return rule.style.cssText;
   }
 };
@@ -6662,16 +7438,21 @@
     cssPartRe = /::part\(([^)]*)\)/gim,
     // note: :host pre-processed to -shadowcsshost.
     polyfillHost = '-shadowcsshost',
-    cssColonHostRe = new RegExp('(' + polyfillHost +
-        ')(?:\\((' +
+    // note: :ancestor pre-processed to -shadowcssancestor.
+    polyfillAncestor = '-shadowcssancestor',
+    parenSuffix = ')(?:\\((' +
         '(?:\\([^)(]*\\)|[^)(]*)+?' +
-        ')\\))?([^,{]*)', 'gim'),
+        ')\\))?([^,{]*)';
+    cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),
+    cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim'),
     selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
     hostRe = /@host/gim,
     colonHostRe = /\:host/gim,
+    colonAncestorRe = /\:ancestor/gim,
     /* host name without combinator */
     polyfillHostNoCombinator = polyfillHost + '-no-combinator',
     polyfillHostRe = new RegExp(polyfillHost, 'gim');
+    polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim');
 
 function stylesToCssText(styles, preserveComments) {
   var cssText = '';
@@ -6717,6 +7498,7 @@
   if (!sheet) {
     sheet = document.createElement("style");
     sheet.setAttribute('ShadowCSSShim', '');
+    sheet.shadowCssShim = true;
   }
   return sheet;
 }
@@ -6724,8 +7506,42 @@
 // add polyfill stylesheet to document
 if (window.ShadowDOMPolyfill) {
   addCssToDocument('style { display: none !important; }\n');
-  var head = document.querySelector('head');
+  var doc = wrap(document);
+  var head = doc.querySelector('head');
   head.insertBefore(getSheet(), head.childNodes[0]);
+
+  document.addEventListener('DOMContentLoaded', function() {
+    if (window.HTMLImports && !HTMLImports.useNative) {
+      HTMLImports.importer.preloadSelectors += 
+          ', link[rel=stylesheet]:not([nopolyfill])';
+      HTMLImports.parser.parseGeneric = function(elt) {
+        if (elt.shadowCssShim) {
+          return;
+        }
+        var style = elt;
+        if (!elt.hasAttribute('nopolyfill')) {
+          if (elt.__resource) {
+            style = elt.ownerDocument.createElement('style');
+            style.textContent = Platform.loader.resolveUrlsInCssText(
+                elt.__resource, elt.href);
+            // remove links from main document
+            if (elt.ownerDocument === doc) {
+              elt.parentNode.removeChild(elt);
+            }
+          } else {
+            Platform.loader.resolveUrlsInStyle(style);  
+          }
+          var styles = [style];
+          style.textContent = ShadowCSS.stylesToShimmedCssText(styles, styles);
+          style.shadowCssShim = true;
+        }
+        // place in document
+        if (style.parentNode !== head) {
+          head.appendChild(style);
+        }
+      }
+    }
+  });
 }
 
 // exports
@@ -6790,555 +7606,11 @@
   })();
 }
 
-(function(global) {
-
-  var registrationsTable = new WeakMap();
-
-  // We use setImmediate or postMessage for our future callback.
-  var setImmediate = window.msSetImmediate;
-
-  // Use post message to emulate setImmediate.
-  if (!setImmediate) {
-    var setImmediateQueue = [];
-    var sentinel = String(Math.random());
-    window.addEventListener('message', function(e) {
-      if (e.data === sentinel) {
-        var queue = setImmediateQueue;
-        setImmediateQueue = [];
-        queue.forEach(function(func) {
-          func();
-        });
-      }
-    });
-    setImmediate = function(func) {
-      setImmediateQueue.push(func);
-      window.postMessage(sentinel, '*');
-    };
-  }
-
-  // This is used to ensure that we never schedule 2 callas to setImmediate
-  var isScheduled = false;
-
-  // Keep track of observers that needs to be notified next time.
-  var scheduledObservers = [];
-
-  /**
-   * Schedules |dispatchCallback| to be called in the future.
-   * @param {MutationObserver} observer
-   */
-  function scheduleCallback(observer) {
-    scheduledObservers.push(observer);
-    if (!isScheduled) {
-      isScheduled = true;
-      setImmediate(dispatchCallbacks);
-    }
-  }
-
-  function wrapIfNeeded(node) {
-    return window.ShadowDOMPolyfill &&
-        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
-        node;
-  }
-
-  function dispatchCallbacks() {
-    // http://dom.spec.whatwg.org/#mutation-observers
-
-    isScheduled = false; // Used to allow a new setImmediate call above.
-
-    var observers = scheduledObservers;
-    scheduledObservers = [];
-    // Sort observers based on their creation UID (incremental).
-    observers.sort(function(o1, o2) {
-      return o1.uid_ - o2.uid_;
-    });
-
-    var anyNonEmpty = false;
-    observers.forEach(function(observer) {
-
-      // 2.1, 2.2
-      var queue = observer.takeRecords();
-      // 2.3. Remove all transient registered observers whose observer is mo.
-      removeTransientObserversFor(observer);
-
-      // 2.4
-      if (queue.length) {
-        observer.callback_(queue, observer);
-        anyNonEmpty = true;
-      }
-    });
-
-    // 3.
-    if (anyNonEmpty)
-      dispatchCallbacks();
-  }
-
-  function removeTransientObserversFor(observer) {
-    observer.nodes_.forEach(function(node) {
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        return;
-      registrations.forEach(function(registration) {
-        if (registration.observer === observer)
-          registration.removeTransientObservers();
-      });
-    });
-  }
-
-  /**
-   * This function is used for the "For each registered observer observer (with
-   * observer's options as options) in target's list of registered observers,
-   * run these substeps:" and the "For each ancestor ancestor of target, and for
-   * each registered observer observer (with options options) in ancestor's list
-   * of registered observers, run these substeps:" part of the algorithms. The
-   * |options.subtree| is checked to ensure that the callback is called
-   * correctly.
-   *
-   * @param {Node} target
-   * @param {function(MutationObserverInit):MutationRecord} callback
-   */
-  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
-    for (var node = target; node; node = node.parentNode) {
-      var registrations = registrationsTable.get(node);
-
-      if (registrations) {
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          var options = registration.options;
-
-          // Only target ignores subtree.
-          if (node !== target && !options.subtree)
-            continue;
-
-          var record = callback(options);
-          if (record)
-            registration.enqueue(record);
-        }
-      }
-    }
-  }
-
-  var uidCounter = 0;
-
-  /**
-   * The class that maps to the DOM MutationObserver interface.
-   * @param {Function} callback.
-   * @constructor
-   */
-  function JsMutationObserver(callback) {
-    this.callback_ = callback;
-    this.nodes_ = [];
-    this.records_ = [];
-    this.uid_ = ++uidCounter;
-  }
-
-  JsMutationObserver.prototype = {
-    observe: function(target, options) {
-      target = wrapIfNeeded(target);
-
-      // 1.1
-      if (!options.childList && !options.attributes && !options.characterData ||
-
-          // 1.2
-          options.attributeOldValue && !options.attributes ||
-
-          // 1.3
-          options.attributeFilter && options.attributeFilter.length &&
-              !options.attributes ||
-
-          // 1.4
-          options.characterDataOldValue && !options.characterData) {
-
-        throw new SyntaxError();
-      }
-
-      var registrations = registrationsTable.get(target);
-      if (!registrations)
-        registrationsTable.set(target, registrations = []);
-
-      // 2
-      // If target's list of registered observers already includes a registered
-      // observer associated with the context object, replace that registered
-      // observer's options with options.
-      var registration;
-      for (var i = 0; i < registrations.length; i++) {
-        if (registrations[i].observer === this) {
-          registration = registrations[i];
-          registration.removeListeners();
-          registration.options = options;
-          break;
-        }
-      }
-
-      // 3.
-      // Otherwise, add a new registered observer to target's list of registered
-      // observers with the context object as the observer and options as the
-      // options, and add target to context object's list of nodes on which it
-      // is registered.
-      if (!registration) {
-        registration = new Registration(this, target, options);
-        registrations.push(registration);
-        this.nodes_.push(target);
-      }
-
-      registration.addListeners();
-    },
-
-    disconnect: function() {
-      this.nodes_.forEach(function(node) {
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.observer === this) {
-            registration.removeListeners();
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-      this.records_ = [];
-    },
-
-    takeRecords: function() {
-      var copyOfRecords = this.records_;
-      this.records_ = [];
-      return copyOfRecords;
-    }
-  };
-
-  /**
-   * @param {string} type
-   * @param {Node} target
-   * @constructor
-   */
-  function MutationRecord(type, target) {
-    this.type = type;
-    this.target = target;
-    this.addedNodes = [];
-    this.removedNodes = [];
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this.attributeName = null;
-    this.attributeNamespace = null;
-    this.oldValue = null;
-  }
-
-  function copyMutationRecord(original) {
-    var record = new MutationRecord(original.type, original.target);
-    record.addedNodes = original.addedNodes.slice();
-    record.removedNodes = original.removedNodes.slice();
-    record.previousSibling = original.previousSibling;
-    record.nextSibling = original.nextSibling;
-    record.attributeName = original.attributeName;
-    record.attributeNamespace = original.attributeNamespace;
-    record.oldValue = original.oldValue;
-    return record;
-  };
-
-  // We keep track of the two (possibly one) records used in a single mutation.
-  var currentRecord, recordWithOldValue;
-
-  /**
-   * Creates a record without |oldValue| and caches it as |currentRecord| for
-   * later use.
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecord(type, target) {
-    return currentRecord = new MutationRecord(type, target);
-  }
-
-  /**
-   * Gets or creates a record with |oldValue| based in the |currentRecord|
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecordWithOldValue(oldValue) {
-    if (recordWithOldValue)
-      return recordWithOldValue;
-    recordWithOldValue = copyMutationRecord(currentRecord);
-    recordWithOldValue.oldValue = oldValue;
-    return recordWithOldValue;
-  }
-
-  function clearRecords() {
-    currentRecord = recordWithOldValue = undefined;
-  }
-
-  /**
-   * @param {MutationRecord} record
-   * @return {boolean} Whether the record represents a record from the current
-   * mutation event.
-   */
-  function recordRepresentsCurrentMutation(record) {
-    return record === recordWithOldValue || record === currentRecord;
-  }
-
-  /**
-   * Selects which record, if any, to replace the last record in the queue.
-   * This returns |null| if no record should be replaced.
-   *
-   * @param {MutationRecord} lastRecord
-   * @param {MutationRecord} newRecord
-   * @param {MutationRecord}
-   */
-  function selectRecord(lastRecord, newRecord) {
-    if (lastRecord === newRecord)
-      return lastRecord;
-
-    // Check if the the record we are adding represents the same record. If
-    // so, we keep the one with the oldValue in it.
-    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
-      return recordWithOldValue;
-
-    return null;
-  }
-
-  /**
-   * Class used to represent a registered observer.
-   * @param {MutationObserver} observer
-   * @param {Node} target
-   * @param {MutationObserverInit} options
-   * @constructor
-   */
-  function Registration(observer, target, options) {
-    this.observer = observer;
-    this.target = target;
-    this.options = options;
-    this.transientObservedNodes = [];
-  }
-
-  Registration.prototype = {
-    enqueue: function(record) {
-      var records = this.observer.records_;
-      var length = records.length;
-
-      // There are cases where we replace the last record with the new record.
-      // For example if the record represents the same mutation we need to use
-      // the one with the oldValue. If we get same record (this can happen as we
-      // walk up the tree) we ignore the new record.
-      if (records.length > 0) {
-        var lastRecord = records[length - 1];
-        var recordToReplaceLast = selectRecord(lastRecord, record);
-        if (recordToReplaceLast) {
-          records[length - 1] = recordToReplaceLast;
-          return;
-        }
-      } else {
-        scheduleCallback(this.observer);
-      }
-
-      records[length] = record;
-    },
-
-    addListeners: function() {
-      this.addListeners_(this.target);
-    },
-
-    addListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.addEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.addEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.addEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.addEventListener('DOMNodeRemoved', this, true);
-    },
-
-    removeListeners: function() {
-      this.removeListeners_(this.target);
-    },
-
-    removeListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.removeEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.removeEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.removeEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.removeEventListener('DOMNodeRemoved', this, true);
-    },
-
-    /**
-     * Adds a transient observer on node. The transient observer gets removed
-     * next time we deliver the change records.
-     * @param {Node} node
-     */
-    addTransientObserver: function(node) {
-      // Don't add transient observers on the target itself. We already have all
-      // the required listeners set up on the target.
-      if (node === this.target)
-        return;
-
-      this.addListeners_(node);
-      this.transientObservedNodes.push(node);
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        registrationsTable.set(node, registrations = []);
-
-      // We know that registrations does not contain this because we already
-      // checked if node === this.target.
-      registrations.push(this);
-    },
-
-    removeTransientObservers: function() {
-      var transientObservedNodes = this.transientObservedNodes;
-      this.transientObservedNodes = [];
-
-      transientObservedNodes.forEach(function(node) {
-        // Transient observers are never added to the target.
-        this.removeListeners_(node);
-
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          if (registrations[i] === this) {
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-    },
-
-    handleEvent: function(e) {
-      // Stop propagation since we are managing the propagation manually.
-      // This means that other mutation events on the page will not work
-      // correctly but that is by design.
-      e.stopImmediatePropagation();
-
-      switch (e.type) {
-        case 'DOMAttrModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes
-
-          var name = e.attrName;
-          var namespace = e.relatedNode.namespaceURI;
-          var target = e.target;
-
-          // 1.
-          var record = new getRecord('attributes', target);
-          record.attributeName = name;
-          record.attributeNamespace = namespace;
-
-          // 2.
-          var oldValue =
-              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.attributes)
-              return;
-
-            // 3.2, 4.3
-            if (options.attributeFilter && options.attributeFilter.length &&
-                options.attributeFilter.indexOf(name) === -1 &&
-                options.attributeFilter.indexOf(namespace) === -1) {
-              return;
-            }
-            // 3.3, 4.4
-            if (options.attributeOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.4, 4.5
-            return record;
-          });
-
-          break;
-
-        case 'DOMCharacterDataModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
-          var target = e.target;
-
-          // 1.
-          var record = getRecord('characterData', target);
-
-          // 2.
-          var oldValue = e.prevValue;
-
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.characterData)
-              return;
-
-            // 3.2, 4.3
-            if (options.characterDataOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.3, 4.4
-            return record;
-          });
-
-          break;
-
-        case 'DOMNodeRemoved':
-          this.addTransientObserver(e.target);
-          // Fall through.
-        case 'DOMNodeInserted':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist
-          var target = e.relatedNode;
-          var changedNode = e.target;
-          var addedNodes, removedNodes;
-          if (e.type === 'DOMNodeInserted') {
-            addedNodes = [changedNode];
-            removedNodes = [];
-          } else {
-
-            addedNodes = [];
-            removedNodes = [changedNode];
-          }
-          var previousSibling = changedNode.previousSibling;
-          var nextSibling = changedNode.nextSibling;
-
-          // 1.
-          var record = getRecord('childList', target);
-          record.addedNodes = addedNodes;
-          record.removedNodes = removedNodes;
-          record.previousSibling = previousSibling;
-          record.nextSibling = nextSibling;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 2.1, 3.2
-            if (!options.childList)
-              return;
-
-            // 2.2, 3.3
-            return record;
-          });
-
-      }
-
-      clearRecords();
-    }
-  };
-
-  global.JsMutationObserver = JsMutationObserver;
-
-  // Provide unprefixed MutationObserver with native or JS implementation
-  if (!global.MutationObserver && global.WebKitMutationObserver)
-    global.MutationObserver = global.WebKitMutationObserver;
-
-  if (!global.MutationObserver)
-    global.MutationObserver = JsMutationObserver;
-
-
-})(this);
-
 window.CustomElements = window.CustomElements || {flags:{}};
 (function(scope){

 

 var logFlags = window.logFlags || {};

+var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';

 

 // walk the subtree rooted at node, applying 'find(element, data)' function

 // to each element

@@ -7430,11 +7702,11 @@
 }

 

 

-// TODO(sorvell): on platforms without MutationObserver, mutations may not be

-// reliable and therefore entered/leftView are not reliable.

+// TODO(sorvell): on platforms without MutationObserver, mutations may not be 

+// reliable and therefore attached/detached are not reliable.

 // To make these callbacks less likely to fail, we defer all inserts and removes

-// to give a chance for elements to be inserted into dom.

-// This ensures enteredViewCallback fires for elements that are created and

+// to give a chance for elements to be inserted into dom. 

+// This ensures attachedCallback fires for elements that are created and 

 // immediately added to dom.

 var hasPolyfillMutations = (!window.MutationObserver ||

     (window.MutationObserver === window.JsMutationObserver));

@@ -7483,7 +7755,7 @@
   // TODO(sjmiles): when logging, do work on all custom elements so we can

   // track behavior even when callbacks not defined

   //console.log('inserted: ', element.localName);

-  if (element.enteredViewCallback || (element.__upgraded__ && logFlags.dom)) {

+  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {

     logFlags.dom && console.group('inserted:', element.localName);

     if (inDocument(element)) {

       element.__inserted = (element.__inserted || 0) + 1;

@@ -7495,9 +7767,9 @@
       if (element.__inserted > 1) {

         logFlags.dom && console.warn('inserted:', element.localName,

           'insert/remove count:', element.__inserted)

-      } else if (element.enteredViewCallback) {

+      } else if (element.attachedCallback) {

         logFlags.dom && console.log('inserted:', element.localName);

-        element.enteredViewCallback();

+        element.attachedCallback();

       }

     }

     logFlags.dom && console.groupEnd();

@@ -7524,8 +7796,8 @@
 function _removed(element) {

   // TODO(sjmiles): temporary: do work on all custom elements so we can track

   // behavior even when callbacks not defined

-  if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) {

-    logFlags.dom && console.log('removed:', element.localName);

+  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {

+    logFlags.dom && console.group('removed:', element.localName);

     if (!inDocument(element)) {

       element.__inserted = (element.__inserted || 0) - 1;

       // if we are in a 'inserted' state, bluntly adjust to an 'removed' state

@@ -7536,17 +7808,24 @@
       if (element.__inserted < 0) {

         logFlags.dom && console.warn('removed:', element.localName,

             'insert/remove count:', element.__inserted)

-      } else if (element.leftViewCallback) {

-        element.leftViewCallback();

+      } else if (element.detachedCallback) {

+        element.detachedCallback();

       }

     }

+    logFlags.dom && console.groupEnd();

   }

 }

 

+// SD polyfill intrustion due mainly to the fact that 'document'

+// is not entirely wrapped

+function wrapIfNeeded(node) {

+  return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)

+      : node;

+}

+

 function inDocument(element) {

   var p = element;

-  var doc = window.ShadowDOMPolyfill &&

-      window.ShadowDOMPolyfill.wrapIfNeeded(document) || document;

+  var doc = wrapIfNeeded(document);

   while (p) {

     if (p == doc) {

       return true;

@@ -7630,19 +7909,33 @@
   observer.observe(inRoot, {childList: true, subtree: true});

 }

 

-function observeDocument(document) {

-  observe(document);

+function observeDocument(doc) {

+  observe(doc);

 }

 

-function upgradeDocument(document) {

-  logFlags.dom && console.group('upgradeDocument: ', (document.URL || document._URL || '').split('/').pop());

-  addedNode(document);

+function upgradeDocument(doc) {

+  logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());

+  addedNode(doc);

   logFlags.dom && console.groupEnd();

 }

 

-// exports

+function upgradeDocumentTree(doc) {

+  doc = wrapIfNeeded(doc);

+  upgradeDocument(doc);

+  //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());

+  // upgrade contained imported documents

+  var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');

+  for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {

+    if (n.import && n.import.__parsed) {

+      upgradeDocumentTree(n.import);

+    }

+  }

+}

 

+// exports

+scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;

 scope.watchShadow = watchShadow;

+scope.upgradeDocumentTree = upgradeDocumentTree;

 scope.upgradeAll = addedNode;

 scope.upgradeSubtree = addedSubtree;

 

@@ -7672,10 +7965,15 @@
 }
 var flags = scope.flags;
 
-// native document.register?
+// native document.registerElement?
 
-var hasNative = Boolean(document.register);
-var useNative = !flags.register && hasNative;
+var hasNative = Boolean(document.registerElement);
+// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399
+// we'll address this by defaulting to CE polyfill in the presence of the SD
+// polyfill. This will avoid spamming excess attached/detached callbacks.
+// If there is a compelling need to run CE native with SD polyfill, 
+// we'll need to fix this issue.
+var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;
 
 if (useNative) {
 
@@ -7722,7 +8020,7 @@
    *      element.
    *
    * @example
-   *      FancyButton = document.register("fancy-button", {
+   *      FancyButton = document.registerElement("fancy-button", {
    *        extends: 'button',
    *        prototype: Object.create(HTMLButtonElement.prototype, {
    *          readyCallback: {
@@ -7735,19 +8033,19 @@
    * @return {Function} Constructor for the newly registered type.
    */
   function register(name, options) {
-    //console.warn('document.register("' + name + '", ', options, ')');
+    //console.warn('document.registerElement("' + name + '", ', options, ')');
     // construct a defintion out of options
     // TODO(sjmiles): probably should clone options instead of mutating it
     var definition = options || {};
     if (!name) {
       // TODO(sjmiles): replace with more appropriate error (EricB can probably
       // offer guidance)
-      throw new Error('document.register: first argument `name` must not be empty');
+      throw new Error('document.registerElement: first argument `name` must not be empty');
     }
     if (name.indexOf('-') < 0) {
       // TODO(sjmiles): replace with more appropriate error (EricB can probably
       // offer guidance)
-      throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
+      throw new Error('document.registerElement: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
     }
     // elements may only be registered once
     if (getRegisteredDefinition(name)) {
@@ -7761,7 +8059,7 @@
       throw new Error('Options missing required prototype property');
     }
     // record name
-    definition.name = name.toLowerCase();
+    definition.__name = name.toLowerCase();
     // ensure a lifecycle object so we don't have to null test it
     definition.lifecycle = definition.lifecycle || {};
     // build a list of ancestral custom elements (for native base detection)
@@ -7777,7 +8075,7 @@
     // overrides to implement attributeChanged callback
     overrideAttributeApi(definition.prototype);
     // 7.1.5: Register the DEFINITION with DOCUMENT
-    registerDefinition(definition.name, definition);
+    registerDefinition(definition.__name, definition);
     // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
     // 7.1.8. Return the output of the previous step.
     definition.ctor = generateConstructor(definition);
@@ -7787,7 +8085,7 @@
     // if initial parsing is complete
     if (scope.ready || scope.performedInitialDocumentUpgrade) {
       // upgrade any pre-existing nodes of this type
-      scope.upgradeAll(document);
+      scope.upgradeDocumentTree(document);
     }
     return definition.ctor;
   }
@@ -7810,10 +8108,10 @@
       baseTag = a.is && a.tag;
     }
     // our tag is our baseTag, if it exists, and otherwise just our name
-    definition.tag = baseTag || definition.name;
+    definition.tag = baseTag || definition.__name;
     if (baseTag) {
       // if there is a base tag, use secondary 'is' specifier
-      definition.is = definition.name;
+      definition.is = definition.__name;
     }
   }
 
@@ -8039,7 +8337,7 @@
 
   // exports
 
-  document.register = register;
+  document.registerElement = register;
   document.createElement = createElement; // override
   Node.prototype.cloneNode = cloneNode; // override
 
@@ -8059,16 +8357,19 @@
   scope.upgrade = upgradeElement;
 }
 
+// bc
+document.register = document.registerElement;
+
 scope.hasNative = hasNative;
 scope.useNative = useNative;
 
 })(window.CustomElements);
 
-(function() {
+(function(scope) {
 
 // import
 
-var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
+var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
 
 // highlander object for parsing a document tree
 
@@ -8103,8 +8404,8 @@
     }
   },
   parseImport: function(linkElt) {
-    if (linkElt.content) {
-      parser.parse(linkElt.content);
+    if (linkElt.import) {
+      parser.parse(linkElt.import);
     }
   }
 };
@@ -8118,9 +8419,10 @@
 
 // exports
 
-CustomElements.parser = parser;
+scope.parser = parser;
+scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
 
-})();
+})(window.CustomElements);
 (function(scope){
 
 // bootstrap parsing
@@ -8135,7 +8437,7 @@
     Platform.endOfMicrotask :
     setTimeout;
   async(function() {
-    // set internal 'ready' flag, now document.register will trigger
+    // set internal 'ready' flag, now document.registerElement will trigger 
     // synchronous upgrades
     CustomElements.ready = true;
     // capture blunt profiling data
@@ -8144,7 +8446,7 @@
       CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
     }
     // notify the system that we are bootstrapped
-    document.body.dispatchEvent(
+    document.dispatchEvent(
       new CustomEvent('WebComponentsReady', {bubbles: true})
     );
   });
@@ -8172,8 +8474,9 @@
 // When loading at other readyStates, wait for the appropriate DOM event to
 // bootstrap.
 } else {
-  var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' :
-      document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
+  var loadEvent = window.HTMLImports && !HTMLImports.ready
+      ? 'HTMLImportsLoaded'
+      : document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
   window.addEventListener(loadEvent, bootstrap);
 }
 
@@ -8239,7 +8542,7 @@
 function DartObject(o) {
   this.o = o;
 }
-// Generated by dart2js, the Dart to JavaScript compiler version: 1.2.0-dev.1.0.
+// Generated by dart2js, the Dart to JavaScript compiler version: 1.2.0-dev.5.15.
 (function($){function dart() {}var A=new dart
 delete A.x
 var B=new dart
@@ -8294,19 +8597,20 @@
 init()
 $=I.p
 var $$={}
-;init.mangledNames={gBA:"__$methodCountSelected",gCO:"_oldPieChart",gF0:"__$cls",gGQ:"_newPieDataTable",gGj:"_message",gHX:"__$displayValue",gJ0:"_newPieChart",gKM:"$",gL4:"human",gLE:"timers",gN7:"__$library",gOc:"_oldPieDataTable",gOl:"__$profile",gP:"value",gPe:"__$internal",gPw:"__$isolate",gPy:"__$error",gRd:"line",gSw:"lines",gUy:"_collapsed",gUz:"__$script",gV4:"__$trace",gVa:"__$frame",gX3:"_first",gXR:"scripts",gXh:"__$instance",gYu:"address",gZ0:"codes",gZ6:"locationManager",gZ8:"__$function",ga:"a",gan:"_tableChart",gb:"b",gc:"c",ge6:"_tableDataTable",geE:"__$msg",geJ:"__$code",geb:"__$json",gfb:"methodCounts",ghm:"__$app",gi2:"isolates",giZ:"__$topInclusiveCodes",gk5:"__$devtools",gkf:"_count",glw:"requestManager",gm0:"__$instruction",gm7:"machine",gnI:"isolateManager",gqY:"__$topExclusiveCodes",grK:"__$links",gtY:"__$ref",gvH:"index",gva:"instructions",gvt:"__$field",gzh:"__$iconClass"};init.mangledGlobalNames={BO:"ALLOCATED_BEFORE_GC",DI:"_closeIconClass",Hg:"ALLOCATED_BEFORE_GC_SIZE",V1g:"LIVE_AFTER_GC_SIZE",Vl:"_openIconClass",d6:"ALLOCATED_SINCE_GC_SIZE",jr:"ALLOCATED_SINCE_GC",xK:"LIVE_AFTER_GC"};(function (reflectionData) {
+;init.mangledNames={gBA:"__$methodCountSelected",gBW:"__$msg",gCO:"_oldPieChart",gDF:"requestManager",gF0:"__$cls",gF8:"__$instruction",gGQ:"_newPieDataTable",gGj:"_message",gHX:"__$displayValue",gHm:"tree",gJ0:"_newPieChart",gKM:"$",gL4:"human",gLE:"timers",gMt:"__$expanded",gN7:"__$library",gOc:"_oldPieDataTable",gOl:"__$profile",gP:"value",gPe:"__$internal",gPw:"__$isolate",gPy:"__$error",gRd:"line",gSw:"lines",gUy:"_collapsed",gUz:"__$script",gV4:"__$trace",gVa:"__$frame",gWT:"rows",gX3:"_first",gXR:"scripts",gXh:"__$instance",gYu:"address",gZ0:"codes",gZ6:"locationManager",gZ8:"__$function",ga:"a",gan:"_tableChart",gb:"b",gc:"c",ge6:"_tableDataTable",geJ:"__$code",geb:"__$json",gfb:"methodCounts",ghm:"__$app",gi2:"isolates",gk5:"__$devtools",gkf:"_count",gm0:"__$isolate",gm7:"machine",gnI:"isolateManager",goH:"columns",gqO:"_id",gqX:"__$expanded",gqY:"__$topExclusiveCodes",grK:"__$links",gtT:"code",gtY:"__$ref",gvH:"index",gva:"instructions",gvt:"__$field",gwd:"children",gyt:"depth",gzh:"__$iconClass",gzw:"__$line"};init.mangledGlobalNames={BO:"ALLOCATED_BEFORE_GC",DI:"_closeIconClass",V1g:"LIVE_AFTER_GC_SIZE",Vl:"_openIconClass",Xa:"ALLOCATED_BEFORE_GC_SIZE",d6:"ALLOCATED_SINCE_GC_SIZE",r1K:"ALLOCATED_SINCE_GC",xK:"LIVE_AFTER_GC"};(function (reflectionData) {
   "use strict";
   function map(x){x={x:x};delete x.x;return x}
     function processStatics(descriptor) {
       for (var property in descriptor) {
         if (!hasOwnProperty.call(descriptor, property)) continue;
-        if (property === "") continue;
+        if (property === "^") continue;
         var element = descriptor[property];
         var firstChar = property.substring(0, 1);
         var previousProperty;
         if (firstChar === "+") {
           mangledGlobalNames[previousProperty] = property.substring(1);
-          if (descriptor[property] == 1) descriptor[previousProperty].$reflectable = 1;
+          var flag = descriptor[property];
+          if (flag > 0) descriptor[previousProperty].$reflectable = flag;
           if (element && element.length) init.typeInformation[previousProperty] = element;
         } else if (firstChar === "@") {
           property = property.substring(1);
@@ -8335,7 +8639,8 @@
               processStatics(init.statics[property] = element[prop]);
             } else if (firstChar === "+") {
               mangledNames[previousProp] = prop.substring(1);
-              if (element[prop] == 1) element[previousProp].$reflectable = 1;
+              var flag = element[prop];
+              if (flag > 0) element[previousProp].$reflectable = flag;
             } else if (firstChar === "@" && prop !== "@") {
               newDesc[prop.substring(1)]["@"] = element[prop];
             } else if (firstChar === "*") {
@@ -8347,7 +8652,7 @@
               optionalMethods[prop] = previousProp;
             } else {
               var elem = element[prop];
-              if (prop && elem != null && elem.constructor === Array && prop !== "<>") {
+              if (prop !== "^" && elem != null && elem.constructor === Array && prop !== "<>") {
                 addStubs(newDesc, elem, prop, false, element, []);
               } else {
                 newDesc[previousProp = prop] = elem;
@@ -8360,29 +8665,13 @@
       }
     }
   function addStubs(descriptor, array, name, isStatic, originalDescriptor, functions) {
-    var f, funcs = [originalDescriptor[name] = descriptor[name] = f = (function() {
-  var result = array[0];
-  if (result != null && typeof result != "function") {
-    throw new Error(
-        name + ": expected value of type 'function' at index " + (0) +
-        " but got " + (typeof result));
-  }
-  return result;
-})()];
+    var f, funcs = [originalDescriptor[name] = descriptor[name] = f = array[0]];
     f.$stubName = name;
     functions.push(name);
     for (var index = 0; index < array.length; index += 2) {
       f = array[index + 1];
       if (typeof f != "function") break;
-      f.$stubName = (function() {
-  var result = array[index + 2];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (index + 2) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      f.$stubName = array[index + 2];
       funcs.push(f);
       if (f.$stubName) {
         originalDescriptor[f.$stubName] = descriptor[f.$stubName] = f;
@@ -8390,61 +8679,21 @@
       }
     }
     for (var i = 0; i < funcs.length; index++, i++) {
-      funcs[i].$callName = (function() {
-  var result = array[index + 1];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (index + 1) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      funcs[i].$callName = array[index + 1];
     }
-    var getterStubName = (function() {
-  var result = array[++index];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (++index) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var getterStubName = array[++index];
     array = array.slice(++index);
-    var requiredParameterInfo = (function() {
-  var result = array[0];
-  if (result != null && (typeof result != "number" || (result|0) !== result)) {
-    throw new Error(
-        name + ": expected value of type 'int' at index " + (0) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var requiredParameterInfo = array[0];
     var requiredParameterCount = requiredParameterInfo >> 1;
     var isAccessor = (requiredParameterInfo & 1) === 1;
     var isSetter = requiredParameterInfo === 3;
     var isGetter = requiredParameterInfo === 1;
-    var optionalParameterInfo = (function() {
-  var result = array[1];
-  if (result != null && (typeof result != "number" || (result|0) !== result)) {
-    throw new Error(
-        name + ": expected value of type 'int' at index " + (1) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+    var optionalParameterInfo = array[1];
     var optionalParameterCount = optionalParameterInfo >> 1;
     var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
     var isIntercepted = requiredParameterCount + optionalParameterCount != funcs[0].length;
-    var functionTypeIndex = (function() {
-  var result = array[2];
-  if (result != null && (typeof result != "number" || (result|0) !== result) && typeof result != "function") {
-    throw new Error(
-        name + ": expected value of type 'function or int' at index " + (2) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
-    var isReflectable = array.length > requiredParameterCount + optionalParameterCount + 3;
+    var functionTypeIndex = array[2];
+    var isReflectable = array.length > 3 * optionalParameterCount + 2 * requiredParameterCount + 3
     if (getterStubName) {
       f = tearOff(funcs, array, isStatic, name, isIntercepted);
       if (isStatic) init.globalFunctions[name] = f;
@@ -8461,16 +8710,8 @@
       }
     }
     if (isReflectable) {
-      var unmangledNameIndex = optionalParameterCount * 2 + requiredParameterCount + 3;
-      var unmangledName = (function() {
-  var result = array[unmangledNameIndex];
-  if (result != null && typeof result != "string") {
-    throw new Error(
-        name + ": expected value of type 'string' at index " + (unmangledNameIndex) +
-        " but got " + (typeof result));
-  }
-  return result;
-})();
+      var unmangledNameIndex = 3 * optionalParameterCount + 2 * requiredParameterCount + 3;
+      var unmangledName = array[unmangledNameIndex];
       var reflectionName = unmangledName + ":" + requiredParameterCount + ":" + optionalParameterCount;
       if (isGetter) {
         reflectionName = unmangledName;
@@ -8491,13 +8732,13 @@
     return isIntercepted
         ? new Function("funcs", "reflectionInfo", "name", "H", "c",
             "return function tearOff_" + name + (functionCounter++)+ "(x) {" +
-              "if (c === null) c = H.qm(" +
+              "if (c === null) c = H.Kq(" +
                   "this, funcs, reflectionInfo, false, [x], name);" +
               "return new c(this, funcs[0], x, name);" +
             "}")(funcs, reflectionInfo, name, H, null)
         : new Function("funcs", "reflectionInfo", "name", "H", "c",
             "return function tearOff_" + name + (functionCounter++)+ "() {" +
-              "if (c === null) c = H.qm(" +
+              "if (c === null) c = H.Kq(" +
                   "this, funcs, reflectionInfo, false, [], name);" +
               "return new c(this, funcs[0], null, name);" +
             "}")(funcs, reflectionInfo, name, H, null)
@@ -8506,11 +8747,11 @@
     var cache = null;
     return isIntercepted
         ? function(x) {
-            if (cache === null) cache = H.qm(this, funcs, reflectionInfo, false, [x], name);
+            if (cache === null) cache = H.Kq(this, funcs, reflectionInfo, false, [x], name);
             return new cache(this, funcs[0], x, name)
           }
         : function() {
-            if (cache === null) cache = H.qm(this, funcs, reflectionInfo, false, [], name);
+            if (cache === null) cache = H.Kq(this, funcs, reflectionInfo, false, [], name);
             return new cache(this, funcs[0], null, name)
           }
   }
@@ -8518,7 +8759,7 @@
     var cache;
     return isStatic
         ? function() {
-            if (cache === void 0) cache = H.qm(this, funcs, reflectionInfo, true, [], name).prototype;
+            if (cache === void 0) cache = H.Kq(this, funcs, reflectionInfo, true, [], name).prototype;
             return cache;
           }
         : tearOffGetter(funcs, reflectionInfo, name, isIntercepted);
@@ -8545,7 +8786,7 @@
     var globalObject = data[3];
     var descriptor = data[4];
     var isRoot = !!data[5];
-    var fields = descriptor && descriptor[""];
+    var fields = descriptor && descriptor["^"];
     var classes = [];
     var functions = [];
     processStatics(descriptor);
@@ -8554,12 +8795,12 @@
   }
 })
 ([["_foreign_helper","dart:_foreign_helper",,H,{
-"":"",
+"^":"",
 Lt:{
-"":"a;tT>"}}],["_interceptors","dart:_interceptors",,J,{
-"":"",
-x:[function(a){return void 0},"call$1","DK",2,0,null,6],
-Qu:[function(a,b,c,d){return{i: a, p: b, e: c, x: d}},"call$4","yC",8,0,null,7,8,9,10],
+"^":"a;tT>"}}],["_interceptors","dart:_interceptors",,J,{
+"^":"",
+x:[function(a){return void 0},"call$1","DK",2,0,null,6,[]],
+Qu:[function(a,b,c,d){return{i: a, p: b, e: c, x: d}},"call$4","yC",8,0,null,7,[],8,[],9,[],10,[]],
 ks:[function(a){var z,y,x,w
 z=a[init.dispatchPropertyName]
 if(z==null)if($.Bv==null){H.XD()
@@ -8570,96 +8811,96 @@
 if(y===x)return z.i
 if(z.e===x)throw H.b(P.SY("Return interceptor for "+H.d(y(a,z))))}w=H.w3(a)
 if(w==null)return C.vB
-return w},"call$1","Fd",2,0,null,6],
+return w},"call$1","mz",2,0,null,6,[]],
 e1:[function(a){var z,y,x,w
 z=$.Au
 if(z==null)return
 y=z
 for(z=y.length,x=J.x(a),w=0;w+1<z;w+=3){if(w>=z)return H.e(y,w)
-if(x.n(a,y[w]))return w}return},"call$1","kC",2,0,null,11],
-Fb:[function(a){var z,y,x
+if(x.n(a,y[w]))return w}return},"call$1","kC",2,0,null,11,[]],
+Xr:[function(a){var z,y,x
 z=J.e1(a)
 if(z==null)return
 y=$.Au
 if(typeof z!=="number")return z.g()
 x=z+1
 if(x>=y.length)return H.e(y,x)
-return y[x]},"call$1","d2",2,0,null,11],
-Dp:[function(a,b){var z,y,x
+return y[x]},"call$1","Tj",2,0,null,11,[]],
+Nq:[function(a,b){var z,y,x
 z=J.e1(a)
 if(z==null)return
 y=$.Au
 if(typeof z!=="number")return z.g()
 x=z+2
 if(x>=y.length)return H.e(y,x)
-return y[x][b]},"call$2","nc",4,0,null,11,12],
+return y[x][b]},"call$2","BJ",4,0,null,11,[],12,[]],
 Gv:{
-"":"a;",
-n:[function(a,b){return a===b},"call$1","gUJ",2,0,null,104],
+"^":"a;",
+n:[function(a,b){return a===b},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return H.eQ(a)},
 bu:[function(a){return H.a5(a)},"call$0","gXo",0,0,null],
-T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,332],
+T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,326,[]],
 gbx:function(a){return new H.cu(H.dJ(a),null)},
 $isGv:true,
 "%":"DOMImplementation|SVGAnimatedEnumeration|SVGAnimatedNumberList|SVGAnimatedString"},
 kn:{
-"":"bool/Gv;",
+"^":"bool/Gv;",
 bu:[function(a){return String(a)},"call$0","gXo",0,0,null],
 giO:function(a){return a?519018:218159},
 gbx:function(a){return C.HL},
 $isbool:true},
-PE:{
-"":"Gv;",
-n:[function(a,b){return null==b},"call$1","gUJ",2,0,null,104],
+ht:{
+"^":"Null/Gv;",
+n:[function(a,b){return null==b},"call$1","gUJ",2,0,null,104,[]],
 bu:[function(a){return"null"},"call$0","gXo",0,0,null],
 giO:function(a){return 0},
 gbx:function(a){return C.Qf}},
 QI:{
-"":"Gv;",
+"^":"Gv;",
 giO:function(a){return 0},
 gbx:function(a){return C.CS}},
 FP:{
-"":"QI;"},
+"^":"QI;"},
 is:{
-"":"QI;"},
+"^":"QI;"},
 Q:{
-"":"List/Gv;",
+"^":"List/Gv;",
 h:[function(a,b){if(!!a.fixed$length)H.vh(P.f("add"))
-a.push(b)},"call$1","ght",2,0,null,23],
+a.push(b)},"call$1","ght",2,0,null,23,[]],
+KI:[function(a,b){if(b<0||b>=a.length)throw H.b(new P.bJ("value "+b))
+if(!!a.fixed$length)H.vh(P.f("removeAt"))
+return a.splice(b,1)[0]},"call$1","gNM",2,0,null,47,[]],
 xe:[function(a,b,c){if(b<0||b>a.length)throw H.b(new P.bJ("value "+b))
 if(!!a.fixed$length)H.vh(P.f("insert"))
-a.splice(b,0,c)},"call$2","gQG",4,0,null,47,23],
-mv:[function(a){if(!!a.fixed$length)H.vh(P.f("removeLast"))
-if(a.length===0)throw H.b(new P.bJ("value -1"))
-return a.pop()},"call$0","gdc",0,0,null],
+a.splice(b,0,c)},"call$2","gQG",4,0,null,47,[],23,[]],
 Rz:[function(a,b){var z
 if(!!a.fixed$length)H.vh(P.f("remove"))
 for(z=0;z<a.length;++z)if(J.de(a[z],b)){a.splice(z,1)
-return!0}return!1},"call$1","gRI",2,0,null,124],
-ev:[function(a,b){return H.VM(new H.U5(a,b),[null])},"call$1","gIR",2,0,null,110],
+return!0}return!1},"call$1","gRI",2,0,null,124,[]],
+ev:[function(a,b){return H.VM(new H.U5(a,b),[null])},"call$1","gIR",2,0,null,110,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(a,z.gl())},"call$1","gDY",2,0,null,333],
+for(z=J.GP(b);z.G();)this.h(a,z.gl())},"call$1","gDY",2,0,null,327,[]],
 V1:[function(a){this.sB(a,0)},"call$0","gyP",0,0,null],
-aN:[function(a,b){return H.bQ(a,b)},"call$1","gjw",2,0,null,110],
-ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110],
+aN:[function(a,b){return H.bQ(a,b)},"call$1","gjw",2,0,null,110,[]],
+ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
 zV:[function(a,b){var z,y,x,w
 z=a.length
 y=Array(z)
 y.fixed$length=init
 for(x=0;x<a.length;++x){w=H.d(a[x])
 if(x>=z)return H.e(y,x)
-y[x]=w}return y.join(b)},"call$1","gnr",0,2,null,334,335],
-eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gVQ",2,0,null,292],
+y[x]=w}return y.join(b)},"call$1","gnr",0,2,null,328,329,[]],
+eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gZo",2,0,null,287,[]],
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 D6:[function(a,b,c){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b<0||b>a.length)throw H.b(P.TE(b,0,a.length))
 if(c==null)c=a.length
 else{if(typeof c!=="number"||Math.floor(c)!==c)throw H.b(new P.AT(c))
 if(c<b||c>a.length)throw H.b(P.TE(c,b,a.length))}if(b===c)return H.VM([],[H.Kp(a,0)])
-return H.VM(a.slice(b,c),[H.Kp(a,0)])},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
-Mu:[function(a,b,c){H.S6(a,b,c)
-return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,116],
+return H.VM(a.slice(b,c),[H.Kp(a,0)])},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+Mu:[function(a,b,c){H.K0(a,b,c)
+return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,[],116,[]],
 gtH:function(a){if(a.length>0)return a[0]
 throw H.b(new P.lj("No elements"))},
 grZ:function(a){var z=a.length
@@ -8673,17 +8914,17 @@
 y=J.Wx(c)
 if(y.C(c,b)||y.D(c,z))throw H.b(P.TE(c,b,z))
 if(typeof c!=="number")return H.s(c)
-H.Gj(a,c,a,b,z-c)
+H.tb(a,c,a,b,z-c)
 if(typeof b!=="number")return H.s(b)
-this.sB(a,z-(c-b))},"call$2","gYH",4,0,null,115,116],
-Vr:[function(a,b){return H.Ck(a,b)},"call$1","gG2",2,0,null,110],
-So:[function(a,b){if(!!a.immutable$list)H.vh(P.f("sort"))
-H.ZE(a,0,a.length-1,b)},"call$1","gH7",0,2,null,77,128],
-XU:[function(a,b,c){return H.Ri(a,b,c,a.length)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,124,115],
-Pk:[function(a,b,c){return H.lO(a,b,a.length-1)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,124,115],
+this.sB(a,z-(c-b))},"call$2","gYH",4,0,null,115,[],116,[]],
+Vr:[function(a,b){return H.Ck(a,b)},"call$1","gG2",2,0,null,110,[]],
+GT:[function(a,b){if(!!a.immutable$list)H.vh(P.f("sort"))
+H.ZE(a,0,a.length-1,b)},"call$1","gH7",0,2,null,77,128,[]],
+XU:[function(a,b,c){return H.TK(a,b,c,a.length)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],115,[]],
+Pk:[function(a,b,c){return H.eX(a,b,a.length-1)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],115,[]],
 tg:[function(a,b){var z
 for(z=0;z<a.length;++z)if(J.de(a[z],b))return!0
-return!1},"call$1","gdj",2,0,null,104],
+return!1},"call$1","gdj",2,0,null,104,[]],
 gl0:function(a){return a.length===0},
 gor:function(a){return a.length!==0},
 bu:[function(a){return H.mx(a,"[","]")},"call$0","gXo",0,0,null],
@@ -8691,7 +8932,7 @@
 if(b)return H.VM(a.slice(),[H.Kp(a,0)])
 else{z=H.VM(a.slice(),[H.Kp(a,0)])
 z.fixed$length=init
-return z}},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+return z}},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 gA:function(a){return H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)])},
 giO:function(a){return H.eQ(a)},
 gB:function(a){return a.length},
@@ -8701,11 +8942,11 @@
 a.length=b},
 t:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b>=a.length||b<0)throw H.b(P.N(b))
-return a[b]},"call$1","gIA",2,0,null,47],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){if(!!a.immutable$list)H.vh(P.f("indexed set"))
 if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
-if(b>=a.length||b<0)throw H.b(P.N(b))
-a[b]=c},"call$2","gj3",4,0,null,47,23],
+if(b>=a.length||b<0)throw H.b(new P.bJ("value "+H.d(b)))
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
 $isList:true,
 $isList:true,
 $asWO:null,
@@ -8717,16 +8958,16 @@
 z=H.VM(new Array(a),[b])
 z.fixed$length=init
 return z}}},
-NK:{
-"":"Q;",
-$isNK:true},
+nM:{
+"^":"Q;",
+$isnM:true},
 ZC:{
-"":"NK;"},
+"^":"nM;"},
 Jt:{
-"":"NK;",
+"^":"nM;",
 $isJt:true},
 P:{
-"":"num/Gv;",
+"^":"num/Gv;",
 iM:[function(a,b){var z
 if(typeof b!=="number")throw H.b(new P.AT(b))
 if(a<b)return-1
@@ -8735,11 +8976,11 @@
 if(this.gzP(a)===z)return 0
 if(this.gzP(a))return-1
 return 1}return 0}else if(isNaN(a)){if(this.gG0(b))return 0
-return 1}else return-1},"call$1","gYc",2,0,null,180],
+return 1}else return-1},"call$1","gYc",2,0,null,180,[]],
 gzP:function(a){return a===0?1/a<0:a<0},
 gG0:function(a){return isNaN(a)},
 gx8:function(a){return isFinite(a)},
-JV:[function(a,b){return a%b},"call$1","gKG",2,0,null,180],
+JV:[function(a,b){return a%b},"call$1","gKG",2,0,null,180,[]],
 yu:[function(a){var z
 if(a>=-2147483648&&a<=2147483647)return a|0
 if(isFinite(a)){z=a<0?Math.ceil(a):Math.floor(a)
@@ -8751,77 +8992,79 @@
 if(b>20)throw H.b(P.C3(b))
 z=a.toFixed(b)
 if(a===0&&this.gzP(a))return"-"+z
-return z},"call$1","gfE",2,0,null,339],
+return z},"call$1","gfE",2,0,null,333,[]],
 WZ:[function(a,b){if(b<2||b>36)throw H.b(P.C3(b))
-return a.toString(b)},"call$1","gEI",2,0,null,28],
+return a.toString(b)},"call$1","gEI",2,0,null,28,[]],
 bu:[function(a){if(a===0&&1/a<0)return"-0.0"
 else return""+a},"call$0","gXo",0,0,null],
 giO:function(a){return a&0x1FFFFFFF},
 J:[function(a){return-a},"call$0","gVd",0,0,null],
 g:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a+b},"call$1","gF1n",2,0,null,104],
+return a+b},"call$1","gF1n",2,0,null,104,[]],
 W:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a-b},"call$1","gTG",2,0,null,104],
+return a-b},"call$1","gTG",2,0,null,104,[]],
 V:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a/b},"call$1","gJj",2,0,null,104],
+return a/b},"call$1","gJj",2,0,null,104,[]],
 U:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a*b},"call$1","gEH",2,0,null,104],
+return a*b},"call$1","gEH",2,0,null,104,[]],
 Y:[function(a,b){var z=a%b
 if(z===0)return 0
 if(z>0)return z
 if(b<0)return z-b
-else return z+b},"call$1","gQR",2,0,null,104],
+else return z+b},"call$1","gQR",2,0,null,104,[]],
 Z:[function(a,b){if((a|0)===a&&(b|0)===b&&0!==b&&-1!==b)return a/b|0
-else return this.yu(a/b)},"call$1","gdG",2,0,null,104],
-cU:[function(a,b){return(a|0)===a?a/b|0:this.yu(a/b)},"call$1","gPf",2,0,null,104],
+else return this.yu(a/b)},"call$1","gdG",2,0,null,104,[]],
+cU:[function(a,b){return(a|0)===a?a/b|0:this.yu(a/b)},"call$1","gPf",2,0,null,104,[]],
 O:[function(a,b){if(b<0)throw H.b(new P.AT(b))
-return b>31?0:a<<b>>>0},"call$1","gq8",2,0,null,104],
-W4:[function(a,b){return b>31?0:a<<b>>>0},"call$1","gGu",2,0,null,104],
+return b>31?0:a<<b>>>0},"call$1","gq8",2,0,null,104,[]],
+W4:[function(a,b){return b>31?0:a<<b>>>0},"call$1","gGu",2,0,null,104,[]],
 m:[function(a,b){var z
 if(b<0)throw H.b(new P.AT(b))
 if(a>0)z=b>31?0:a>>>b
 else{z=b>31?31:b
-z=a>>z>>>0}return z},"call$1","gyp",2,0,null,104],
+z=a>>z>>>0}return z},"call$1","gyp",2,0,null,104,[]],
 GG:[function(a,b){var z
 if(a>0)z=b>31?0:a>>>b
 else{z=b>31?31:b
-z=a>>z>>>0}return z},"call$1","gMe",2,0,null,104],
+z=a>>z>>>0}return z},"call$1","gMe",2,0,null,104,[]],
 i:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return(a&b)>>>0},"call$1","gAp",2,0,null,104],
+return(a&b)>>>0},"call$1","gAp",2,0,null,104,[]],
+w:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
+return(a^b)>>>0},"call$1","gttE",2,0,null,104,[]],
 C:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a<b},"call$1","gix",2,0,null,104],
+return a<b},"call$1","gix",2,0,null,104,[]],
 D:[function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
-return a>b},"call$1","gh1",2,0,null,104],
+return a>b},"call$1","gh1",2,0,null,104,[]],
 E:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a<=b},"call$1","gf5",2,0,null,104],
+return a<=b},"call$1","gf5",2,0,null,104,[]],
 F:[function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
-return a>=b},"call$1","gNH",2,0,null,104],
+return a>=b},"call$1","gNH",2,0,null,104,[]],
 $isnum:true,
-static:{"":"xr,LN"}},
+static:{"^":"zc,LN"}},
 im:{
-"":"int/P;",
+"^":"int/P;",
 gbx:function(a){return C.yw},
 $isdouble:true,
 $isnum:true,
 $isint:true},
 GW:{
-"":"double/P;",
+"^":"double/P;",
 gbx:function(a){return C.O4},
 $isdouble:true,
 $isnum:true},
 vT:{
-"":"im;"},
+"^":"im;"},
 VP:{
-"":"vT;"},
+"^":"vT;"},
 BQ:{
-"":"VP;"},
+"^":"VP;"},
 O:{
-"":"String/Gv;",
+"^":"String/Gv;",
 j:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(P.u(b))
 if(b<0)throw H.b(P.N(b))
 if(b>=a.length)throw H.b(P.N(b))
-return a.charCodeAt(b)},"call$1","gSu",2,0,null,47],
-dd:[function(a,b){return H.ZT(a,b)},"call$1","gYv",2,0,null,340],
+return a.charCodeAt(b)},"call$1","gSu",2,0,null,47,[]],
+dd:[function(a,b){return H.ZT(a,b)},"call$1","gYv",2,0,null,334,[]],
 wL:[function(a,b,c){var z,y,x,w
 if(c<0||c>b.length)throw H.b(P.TE(c,0,b.length))
 z=a.length
@@ -8832,21 +9075,21 @@
 if(w>=y)H.vh(P.N(w))
 w=b.charCodeAt(w)
 if(x>=z)H.vh(P.N(x))
-if(w!==a.charCodeAt(x))return}return new H.tQ(c,b,a)},"call$2","grS",2,2,null,336,26,115],
+if(w!==a.charCodeAt(x))return}return new H.tQ(c,b,a)},"call$2","grS",2,2,null,330,26,[],115,[]],
 g:[function(a,b){if(typeof b!=="string")throw H.b(new P.AT(b))
-return a+b},"call$1","gF1n",2,0,null,104],
+return a+b},"call$1","gF1n",2,0,null,104,[]],
 Tc:[function(a,b){var z,y
 z=b.length
 y=a.length
 if(z>y)return!1
-return b===this.yn(a,y-z)},"call$1","gvi",2,0,null,104],
-h8:[function(a,b,c){return H.ys(a,b,c)},"call$2","gpd",4,0,null,105,106],
-Fr:[function(a,b){return a.split(b)},"call$1","gOG",2,0,null,98],
+return b===this.yn(a,y-z)},"call$1","gvi",2,0,null,104,[]],
+h8:[function(a,b,c){return H.ys(a,b,c)},"call$2","gpd",4,0,null,105,[],106,[]],
+Fr:[function(a,b){return a.split(b)},"call$1","gOG",2,0,null,98,[]],
 Qi:[function(a,b,c){var z
 if(c>a.length)throw H.b(P.TE(c,0,a.length))
 if(typeof b==="string"){z=c+b.length
 if(z>a.length)return!1
-return b===a.substring(c,z)}return J.I8(b,a,c)!=null},function(a,b){return this.Qi(a,b,0)},"nC","call$2",null,"gcV",2,2,null,336,98,47],
+return b===a.substring(c,z)}return J.I8(b,a,c)!=null},function(a,b){return this.Qi(a,b,0)},"nC","call$2",null,"gcV",2,2,null,330,98,[],47,[]],
 Nj:[function(a,b,c){var z
 if(typeof b!=="number"||Math.floor(b)!==b)H.vh(P.u(b))
 if(c==null)c=a.length
@@ -8855,7 +9098,7 @@
 if(z.C(b,0))throw H.b(P.N(b))
 if(z.D(b,c))throw H.b(P.N(b))
 if(J.z8(c,a.length))throw H.b(P.N(c))
-return a.substring(b,c)},function(a,b){return this.Nj(a,b,null)},"yn","call$2",null,"gKj",2,2,null,77,80,125],
+return a.substring(b,c)},function(a,b){return this.Nj(a,b,null)},"yn","call$2",null,"gKj",2,2,null,77,80,[],125,[]],
 hc:[function(a){return a.toLowerCase()},"call$0","gCW",0,0,null],
 bS:[function(a){var z,y,x,w,v
 for(z=a.length,y=0;y<z;){if(y>=z)H.vh(P.N(y))
@@ -8868,9 +9111,14 @@
 x=a.charCodeAt(v)
 if(x===32||x===13||J.Ga(x));else break}if(y===0&&w===z)return a
 return a.substring(y,w)},"call$0","gZH",0,0,null],
-gZm:function(a){return new J.Qe(a)},
-XU:[function(a,b,c){if(c<0||c>a.length)throw H.b(P.TE(c,0,a.length))
-return a.indexOf(b,c)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,98,115],
+XU:[function(a,b,c){var z,y,x,w
+if(b==null)H.vh(new P.AT(null))
+if(c<0||c>a.length)throw H.b(P.TE(c,0,a.length))
+if(typeof b==="string")return a.indexOf(b,c)
+z=J.rY(b)
+if(typeof b==="object"&&b!==null&&!!z.$isVR){y=b.yk(a,c)
+return y==null?-1:y.QK.index}for(x=a.length,w=c;w<=x;++w)if(z.wL(b,a,w)!=null)return w
+return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,98,[],115,[]],
 Pk:[function(a,b,c){var z,y,x
 c=a.length
 if(typeof b==="string"){z=b.length
@@ -8881,17 +9129,17 @@
 x=c
 while(!0){if(typeof x!=="number")return x.F()
 if(!(x>=0))break
-if(z.wL(b,a,x)!=null)return x;--x}return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,98,115],
+if(z.wL(b,a,x)!=null)return x;--x}return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,98,[],115,[]],
 Is:[function(a,b,c){if(b==null)H.vh(new P.AT(null))
 if(c>a.length)throw H.b(P.TE(c,0,a.length))
-return H.m2(a,b,c)},function(a,b){return this.Is(a,b,0)},"tg","call$2",null,"gdj",2,2,null,336,104,80],
+return H.m2(a,b,c)},function(a,b){return this.Is(a,b,0)},"tg","call$2",null,"gdj",2,2,null,330,104,[],80,[]],
 gl0:function(a){return a.length===0},
 gor:function(a){return a.length!==0},
 iM:[function(a,b){var z
 if(typeof b!=="string")throw H.b(new P.AT(b))
 if(a===b)z=0
 else z=a<b?-1:1
-return z},"call$1","gYc",2,0,null,104],
+return z},"call$1","gYc",2,0,null,104,[]],
 bu:[function(a){return a},"call$0","gXo",0,0,null],
 giO:function(a){var z,y,x
 for(z=a.length,y=0,x=0;x<z;++x){y=536870911&y+a.charCodeAt(x)
@@ -8903,30 +9151,16 @@
 gB:function(a){return a.length},
 t:[function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
 if(b>=a.length||b<0)throw H.b(P.N(b))
-return a[b]},"call$1","gIA",2,0,null,47],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 $isString:true,
 static:{Ga:[function(a){if(a<256)switch(a){case 9:case 10:case 11:case 12:case 13:case 32:case 133:case 160:return!0
 default:return!1}switch(a){case 5760:case 6158:case 8192:case 8193:case 8194:case 8195:case 8196:case 8197:case 8198:case 8199:case 8200:case 8201:case 8202:case 8232:case 8233:case 8239:case 8287:case 12288:case 65279:return!0
-default:return!1}},"call$1","BD",2,0,null,13]}},
-Qe:{
-"":"Iy;iN",
-gB:function(a){return this.iN.length},
-t:[function(a,b){var z,y
-z=this.iN
-if(typeof b!=="number"||Math.floor(b)!==b)H.vh(new P.AT(b))
-y=J.Wx(b)
-if(y.C(b,0))H.vh(new P.bJ("value "+H.d(b)))
-if(y.F(b,z.length))H.vh(new P.bJ("value "+H.d(b)))
-return z.charCodeAt(b)},"call$1","gIA",2,0,null,341],
-$asIy:function(){return[J.im]},
-$asar:function(){return[J.im]},
-$asWO:function(){return[J.im]},
-$ascX:function(){return[J.im]}}}],["_isolate_helper","dart:_isolate_helper",,H,{
-"":"",
+default:return!1}},"call$1","BD",2,0,null,13,[]]}}}],["_isolate_helper","dart:_isolate_helper",,H,{
+"^":"",
 zd:[function(a,b){var z=a.vV(b)
 init.globalState.Xz.bL()
-return z},"call$2","Ag",4,0,null,14,15],
-oT:[function(a){var z,y,x
+return z},"call$2","Ag",4,0,null,14,[],15,[]],
+oT:[function(a){var z,y,x,w,v
 z=new H.f0(0,0,1,null,null,null,null,null,null,null,null,null,a)
 z.i6(a)
 init.globalState=z
@@ -8934,15 +9168,20 @@
 z=init.globalState
 y=z.Hg
 z.Hg=y+1
-x=new H.aX(y,P.L5(null,null,null,J.im,H.yo),P.Ls(null,null,null,J.im),new I())
-init.globalState.Nr=x
-init.globalState.N0=x
+z=P.L5(null,null,null,J.im,H.yo)
+x=P.Ls(null,null,null,J.im)
+w=new H.yo(0,null,!1)
+v=new H.aX(y,z,x,new I(),w,P.Jz(),!1,[],P.Ls(null,null,null,null))
+x.h(0,0)
+v.aU(0,w)
+init.globalState.Nr=v
+init.globalState.N0=v
 z=H.N7()
 y=H.KT(z,[z]).BD(a)
-if(y)x.vV(new H.PK(a))
+if(y)v.vV(new H.PK(a))
 else{z=H.KT(z,[z,z]).BD(a)
-if(z)x.vV(new H.JO(a))
-else x.vV(a)}init.globalState.Xz.bL()},"call$1","wr",2,0,null,16],
+if(z)v.vV(new H.JO(a))
+else v.vV(a)}init.globalState.Xz.bL()},"call$1","wr",2,0,null,16,[]],
 yl:[function(){var z=init.currentScript
 if(z!=null)return String(z.src)
 if(typeof version=="function"&&typeof os=="object"&&"system" in os)return H.ZV()
@@ -8969,26 +9208,31 @@
 y=init.globalState
 r=y.Hg
 y.Hg=r+1
-q=new H.aX(r,P.L5(null,null,null,J.im,H.yo),P.Ls(null,null,null,J.im),new I())
-init.globalState.Xz.Rk.NZ(0,new H.IY(q,new H.jl(w,v,u,t,s),"worker-start"))
-init.globalState.N0=q
+y=P.L5(null,null,null,J.im,H.yo)
+q=P.Ls(null,null,null,J.im)
+p=new H.yo(0,null,!1)
+o=new H.aX(r,y,q,new I(),p,P.Jz(),!1,[],P.Ls(null,null,null,null))
+q.h(0,0)
+o.aU(0,p)
+init.globalState.Xz.Rk.NZ(0,new H.IY(o,new H.jl(w,v,u,t,s),"worker-start"))
+init.globalState.N0=o
 init.globalState.Xz.bL()
 break
 case"spawn-worker":r=y.t(z,"functionName")
-p=y.t(z,"uri")
-o=y.t(z,"args")
-n=y.t(z,"msg")
+n=y.t(z,"uri")
+q=y.t(z,"args")
+p=y.t(z,"msg")
 m=y.t(z,"isSpawnUri")
 y=y.t(z,"replyPort")
-if(p==null)p=$.Cl()
-l=new Worker(p)
+if(n==null)n=$.Cl()
+l=new Worker(n)
 l.onmessage=function(e) { H.Mg(l, e); }
 k=init.globalState
 j=k.hJ
 k.hJ=j+1
 $.p6().u(0,l,j)
 init.globalState.XC.u(0,j,l)
-l.postMessage(H.Gy(H.B7(["command","start","id",j,"replyTo",H.Gy(y),"args",o,"msg",H.Gy(n),"isSpawnUri",m,"functionName",r],P.L5(null,null,null,null,null))))
+l.postMessage(H.Gy(H.B7(["command","start","id",j,"replyTo",H.Gy(y),"args",q,"msg",H.Gy(p),"isSpawnUri",m,"functionName",r],P.L5(null,null,null,null,null))))
 break
 case"message":if(y.t(z,"port")!=null)J.H4(y.t(z,"port"),y.t(z,"msg"))
 init.globalState.Xz.bL()
@@ -8999,40 +9243,40 @@
 break
 case"log":H.ZF(y.t(z,"msg"))
 break
-case"print":if(init.globalState.EF===!0){y=init.globalState.my
+case"print":if(init.globalState.EF===!0){y=init.globalState.vd
 r=H.Gy(H.B7(["command","print","msg",z],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(r)}else P.JS(y.t(z,"msg"))
 break
 case"error":throw H.b(y.t(z,"msg"))
-default:}},"call$2","NB",4,0,null,17,18],
+default:}},"call$2","NB",4,0,null,17,[],18,[]],
 ZF:[function(a){var z,y,x,w
-if(init.globalState.EF===!0){y=init.globalState.my
+if(init.globalState.EF===!0){y=init.globalState.vd
 x=H.Gy(H.B7(["command","log","msg",a],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(x)}else try{$.jk().console.log(a)}catch(w){H.Ru(w)
 z=new H.XO(w,null)
-throw H.b(P.FM(z))}},"call$1","o3",2,0,null,19],
+throw H.b(P.FM(z))}},"call$1","o3",2,0,null,19,[]],
 Gy:[function(a){var z
-if(init.globalState.ji===!0){z=new H.Bj(0,new H.X1())
+if(init.globalState.ji===!0){z=new H.NA(0,new H.X1())
 z.il=new H.fP(null)
 return z.h7(a)}else{z=new H.NO(new H.X1())
 z.il=new H.fP(null)
-return z.h7(a)}},"call$1","hX",2,0,null,20],
+return z.h7(a)}},"call$1","hX",2,0,null,20,[]],
 Hh:[function(a){if(init.globalState.ji===!0)return new H.II(null).QS(a)
-else return a},"call$1","m6",2,0,null,20],
-VO:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","vP",2,0,null,21],
-ZR:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","WZ",2,0,null,21],
+else return a},"call$1","m6",2,0,null,20,[]],
+VO:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","vP",2,0,null,21,[]],
+ZR:[function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},"call$1","dD",2,0,null,21,[]],
 PK:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){this.a.call$1([])},"call$0",null,0,0,null,"call"],
 $isEH:true},
 JO:{
-"":"Tp:108;b",
+"^":"Tp:108;b",
 call$0:[function(){this.b.call$2([],null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 f0:{
-"":"a;Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2@,my,XC,w2<",
+"^":"a;Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2@,vd,XC,w2<",
 i6:function(a){var z,y,x,w
 z=$.Qm()==null
 y=$.Nl()
@@ -9042,140 +9286,164 @@
 else y=!0
 this.ji=y
 this.vu=z&&!x
-y=H.IY
-x=H.VM(new P.Sw(null,0,0,0),[y])
-x.Eo(null,y)
-this.Xz=new H.cC(x,0)
+this.Xz=new H.cC(P.NZ(null,H.IY),0)
 this.i2=P.L5(null,null,null,J.im,H.aX)
 this.XC=P.L5(null,null,null,J.im,null)
 if(this.EF===!0){z=new H.JH()
-this.my=z
+this.vd=z
 w=function (e) { H.Mg(z, e); }
 $.jk().onmessage=w
 $.jk().dartPrint = function (object) {}}}},
 aX:{
-"":"a;jO>,Gx,fW,En<",
+"^":"a;jO>,Gx,fW,En<,EE<,Qy,RW<,C9<,lJ",
+v8:[function(a,b){if(!this.Qy.n(0,a))return
+if(this.lJ.h(0,b)&&!this.RW)this.RW=!0},"call$2","gfU",4,0,null,335,[],336,[]],
+NR:[function(a){var z,y,x,w,v,u
+if(!this.RW)return
+z=this.lJ
+z.Rz(0,a)
+if(z.X5===0){for(z=this.C9;y=z.length,y!==0;){if(0>=y)return H.e(z,0)
+x=z.pop()
+y=init.globalState.Xz.Rk
+w=y.av
+v=y.v5
+u=v.length
+w=(w-1&u-1)>>>0
+y.av=w
+if(w<0||w>=u)return H.e(v,w)
+v[w]=x
+if(w===y.eZ)y.VW()
+y.qT=y.qT+1}this.RW=!1}},"call$1","gtS",2,0,null,336,[]],
 vV:[function(a){var z,y
 z=init.globalState.N0
 init.globalState.N0=this
 $=this.En
 y=null
 try{y=a.call$0()}finally{init.globalState.N0=z
-if(z!=null)$=z.gEn()}return y},"call$1","goR",2,0,null,136],
-Zt:[function(a){return this.Gx.t(0,a)},"call$1","gQB",2,0,null,342],
-jT:[function(a,b,c){var z=this.Gx
-if(z.x4(b))throw H.b(P.FM("Registry: ports must be registered only once."))
-z.u(0,b,c)
-this.PC()},"call$2","gKI",4,0,null,342,343],
+if(z!=null)$=z.gEn()}return y},"call$1","gZm",2,0,null,136,[]],
+Ds:[function(a){var z=J.U6(a)
+switch(z.t(a,0)){case"pause":this.v8(z.t(a,1),z.t(a,2))
+break
+case"resume":this.NR(z.t(a,1))
+break
+default:P.JS("UNKOWN MESSAGE: "+H.d(a))}},"call$1","gNo",2,0,null,20,[]],
+Zt:[function(a){return this.Gx.t(0,a)},"call$1","gQB",2,0,null,337,[]],
+aU:[function(a,b){var z=this.Gx
+if(z.x4(a))throw H.b(P.FM("Registry: ports must be registered only once."))
+z.u(0,a,b)},"call$2","gPn",4,0,null,337,[],338,[]],
 PC:[function(){var z=this.jO
 if(this.Gx.X5-this.fW.X5>0)init.globalState.i2.u(0,z,this)
 else init.globalState.i2.Rz(0,z)},"call$0","gi8",0,0,null],
 $isaX:true},
 cC:{
-"":"a;Rk,bZ",
-Jc:[function(){var z=this.Rk
-if(z.av===z.HV)return
-return z.Ux()},"call$0","glk",0,0,null],
+"^":"a;Rk,bZ",
+Jc:[function(){var z,y,x,w,v
+z=this.Rk
+y=z.av
+if(y===z.eZ)return
+z.qT=z.qT+1
+x=z.v5
+w=x.length
+if(y>=w)return H.e(x,y)
+v=x[y]
+x[y]=null
+z.av=(y+1&w-1)>>>0
+return v},"call$0","glk",0,0,null],
 xB:[function(){var z,y,x
 z=this.Jc()
 if(z==null){if(init.globalState.Nr!=null&&init.globalState.i2.x4(init.globalState.Nr.jO)&&init.globalState.vu===!0&&init.globalState.Nr.Gx.X5===0)H.vh(P.FM("Program exited with open ReceivePorts."))
 y=init.globalState
-if(y.EF===!0&&y.i2.X5===0&&y.Xz.bZ===0){y=y.my
+if(y.EF===!0&&y.i2.X5===0&&y.Xz.bZ===0){y=y.vd
 x=H.Gy(H.B7(["command","close"],P.L5(null,null,null,null,null)))
 y.toString
 self.postMessage(x)}return!1}z.VU()
-return!0},"call$0","gad",0,0,null],
-Wu:[function(){if($.Qm()!=null)new H.RA(this).call$0()
+return!0},"call$0","gUB",0,0,null],
+Js:[function(){if($.Qm()!=null)new H.RA(this).call$0()
 else for(;this.xB(););},"call$0","gVY",0,0,null],
 bL:[function(){var z,y,x,w,v
-if(init.globalState.EF!==!0)this.Wu()
-else try{this.Wu()}catch(x){w=H.Ru(x)
+if(init.globalState.EF!==!0)this.Js()
+else try{this.Js()}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-w=init.globalState.my
+w=init.globalState.vd
 v=H.Gy(H.B7(["command","error","msg",H.d(z)+"\n"+H.d(y)],P.L5(null,null,null,null,null)))
 w.toString
 self.postMessage(v)}},"call$0","gcP",0,0,null]},
 RA:{
-"":"Tp:107;a",
+"^":"Tp:107;a",
 call$0:[function(){if(!this.a.xB())return
-P.rT(C.RT,this)},"call$0",null,0,0,null,"call"],
+P.rT(C.ny,this)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 IY:{
-"":"a;Aq*,i3,G1*",
-VU:[function(){this.Aq.vV(this.i3)},"call$0","gjF",0,0,null],
+"^":"a;Aq*,i3,G1*",
+VU:[function(){if(this.Aq.gRW()){this.Aq.gC9().push(this)
+return}this.Aq.vV(this.i3)},"call$0","gjF",0,0,null],
 $isIY:true},
 JH:{
-"":"a;"},
+"^":"a;"},
 jl:{
-"":"Tp:108;a,b,c,d,e",
+"^":"Tp:108;a,b,c,d,e",
 call$0:[function(){var z,y,x,w,v,u
 z=this.a
 y=this.b
 x=this.c
-w=init.globalState.N0.jO
-$.te=$.te+("_"+w)
-$.eb=$.eb+("_"+w)
-w=$.ty
-$.ty=w+1
-v=new H.yo(w,null,!1)
-u=init.globalState.N0
-u.fW.h(0,w)
-u.jT(0,w,v)
-w=new H.Rd(v,null)
-w.no(v)
-$.D5=w
-J.H4(this.e,["spawned",new H.Z6(v,init.globalState.N0.jO)])
+w=init.globalState.N0
+v=w.jO
+$.te=$.te+("_"+v)
+$.eb=$.eb+("_"+v)
+J.H4(this.e,["spawned",new H.Z6(w.EE,init.globalState.N0.jO),w.Qy])
 if(this.d!==!0)z.call$1(x)
-else{w=H.N7()
-v=H.KT(w,[w,w]).BD(z)
-if(v)z.call$2(y,x)
-else{x=H.KT(w,[w]).BD(z)
+else{v=H.N7()
+u=H.KT(v,[v,v]).BD(z)
+if(u)z.call$2(y,x)
+else{x=H.KT(v,[v]).BD(z)
 if(x)z.call$1(y)
 else z.call$0()}}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-Iy4:{
-"":"a;",
+Iy:{
+"^":"a;",
 $isbC:true},
 Z6:{
-"":"Iy4;JE,Jz",
+"^":"Iy;JE,Jz",
 wR:[function(a,b){var z,y,x,w,v
 z={}
 y=this.Jz
 x=init.globalState.i2.t(0,y)
 if(x==null)return
-if(this.JE.gP0())return
-w=init.globalState.N0!=null&&init.globalState.N0.jO!==y
+w=this.JE
+if(w.gP0())return
+v=init.globalState.N0!=null&&init.globalState.N0.jO!==y
 z.a=b
-if(w)z.a=H.Gy(b)
-y=init.globalState.Xz
-v="receive "+H.d(b)
-y.Rk.NZ(0,new H.IY(x,new H.Ua(z,this,w),v))},"call$1","gX8",2,0,null,20],
+if(v)z.a=H.Gy(b)
+if(x.gEE()===w){x.Ds(z.a)
+return}y=init.globalState.Xz
+w="receive "+H.d(b)
+y.Rk.NZ(0,new H.IY(x,new H.Ua(z,this,v),w))},"call$1","gX8",2,0,null,20,[]],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isZ6&&J.de(this.JE,b.JE)},"call$1","gUJ",2,0,null,104],
-giO:function(a){return this.JE.gng()},
+return typeof b==="object"&&b!==null&&!!z.$isZ6&&J.de(this.JE,b.JE)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){return J.td(this.JE)},
 $isZ6:true,
 $isbC:true},
 Ua:{
-"":"Tp:108;a,b,c",
+"^":"Tp:108;a,b,c",
 call$0:[function(){var z,y
 z=this.b.JE
 if(!z.gP0()){if(this.c){y=this.a
 y.a=H.Hh(y.a)}J.t8(z,this.a.a)}},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ns:{
-"":"Iy4;hQ,bv,Jz",
+"^":"Iy;hQ,bv,Jz",
 wR:[function(a,b){var z,y
 z=H.Gy(H.B7(["command","message","port",this,"msg",b],P.L5(null,null,null,null,null)))
-if(init.globalState.EF===!0){init.globalState.my.toString
+if(init.globalState.EF===!0){init.globalState.vd.toString
 self.postMessage(z)}else{y=init.globalState.XC.t(0,this.hQ)
-if(y!=null)y.postMessage(z)}},"call$1","gX8",2,0,null,20],
+if(y!=null)y.postMessage(z)}},"call$1","gX8",2,0,null,20,[]],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isns&&J.de(this.hQ,b.hQ)&&J.de(this.Jz,b.Jz)&&J.de(this.bv,b.bv)},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$isns&&J.de(this.hQ,b.hQ)&&J.de(this.Jz,b.Jz)&&J.de(this.bv,b.bv)},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z,y,x
 z=J.c1(this.hQ,16)
 y=J.c1(this.Jz,8)
@@ -9185,43 +9453,37 @@
 $isns:true,
 $isbC:true},
 yo:{
-"":"a;ng<,bd,P0<",
+"^":"a;ng>,bd,P0<",
 wy:function(a){return this.bd.call$1(a)},
-cO:[function(a){var z
+cO:[function(a){var z,y
 if(this.P0)return
 this.P0=!0
 this.bd=null
 z=init.globalState.N0
-z.Gx.Rz(0,this.ng)
+y=this.ng
+z.Gx.Rz(0,y)
+z.fW.Rz(0,y)
 z.PC()},"call$0","gJK",0,0,null],
 FL:[function(a,b){if(this.P0)return
-this.wy(b)},"call$1","gfU",2,0,null,344],
+this.wy(b)},"call$1","gT5",2,0,null,339,[]],
 $isyo:true,
-static:{"":"ty"}},
-Rd:{
-"":"qh;vl,da",
-KR:[function(a,b,c,d){var z=this.da
-z.toString
-return H.VM(new P.O9(z),[null]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
-cO:[function(a){this.vl.cO(0)
-this.da.cO(0)},"call$0","gJK",0,0,107],
-no:function(a){var z=P.Ve(this.gJK(this),null,null,null,!0,null)
-this.da=z
-this.vl.bd=z.ght(z)},
-$asqh:function(){return[null]},
-$isqh:true},
-Bj:{
-"":"hz;CN,il",
-DE:[function(a){if(!!a.$isZ6)return["sendport",init.globalState.oL,a.Jz,a.JE.gng()]
+static:{"^":"Vz"}},
+NA:{
+"^":"hz;CN,il",
+DE:[function(a){if(!!a.$isZ6)return["sendport",init.globalState.oL,a.Jz,J.td(a.JE)]
 if(!!a.$isns)return["sendport",a.hQ,a.Jz,a.bv]
-throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21]},
+throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){if(!!a.$isku)return["capability",a.ng]
+throw H.b("Capability not serializable: "+H.d(a))},"call$1","gbM",2,0,null,21,[]]},
 NO:{
-"":"oo;il",
+"^":"oo;il",
 DE:[function(a){if(!!a.$isZ6)return new H.Z6(a.JE,a.Jz)
 if(!!a.$isns)return new H.ns(a.hQ,a.bv,a.Jz)
-throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21]},
+throw H.b("Illegal underlying port "+H.d(a))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){if(!!a.$isku)return new H.ku(a.ng)
+throw H.b("Capability not serializable: "+H.d(a))},"call$1","gbM",2,0,null,21,[]]},
 II:{
-"":"AP;RZ",
+"^":"iY;RZ",
 Vf:[function(a){var z,y,x,w,v,u
 z=J.U6(a)
 y=z.t(a,1)
@@ -9231,41 +9493,43 @@
 if(v==null)return
 u=v.Zt(w)
 if(u==null)return
-return new H.Z6(u,x)}else return new H.ns(y,w,x)},"call$1","gTm",2,0,null,68]},
+return new H.Z6(u,x)}else return new H.ns(y,w,x)},"call$1","gTm",2,0,null,68,[]],
+Op:[function(a){return new H.ku(J.UQ(a,1))},"call$1","gID",2,0,null,68,[]]},
 fP:{
-"":"a;MD",
-t:[function(a,b){return b.__MessageTraverser__attached_info__},"call$1","gIA",2,0,null,6],
+"^":"a;MD",
+t:[function(a,b){return b.__MessageTraverser__attached_info__},"call$1","gIA",2,0,null,6,[]],
 u:[function(a,b,c){this.MD.push(b)
-b.__MessageTraverser__attached_info__=c},"call$2","gj3",4,0,null,6,348],
+b.__MessageTraverser__attached_info__=c},"call$2","gj3",4,0,null,6,[],340,[]],
 Hn:[function(a){this.MD=[]},"call$0","gb6",0,0,null],
 Xq:[function(){var z,y,x
 for(z=this.MD.length,y=0;y<z;++y){x=this.MD
 if(y>=x.length)return H.e(x,y)
 x[y].__MessageTraverser__attached_info__=null}this.MD=null},"call$0","gt6",0,0,null]},
 X1:{
-"":"a;",
-t:[function(a,b){return},"call$1","gIA",2,0,null,6],
-u:[function(a,b,c){},"call$2","gj3",4,0,null,6,348],
+"^":"a;",
+t:[function(a,b){return},"call$1","gIA",2,0,null,6,[]],
+u:[function(a,b,c){},"call$2","gj3",4,0,null,6,[],340,[]],
 Hn:[function(a){},"call$0","gb6",0,0,null],
 Xq:[function(){return},"call$0","gt6",0,0,null]},
 HU:{
-"":"a;",
+"^":"a;",
 h7:[function(a){var z
 if(H.VO(a))return this.Pq(a)
 this.il.Hn(0)
 z=null
-try{z=this.I8(a)}finally{this.il.Xq()}return z},"call$1","gyU",2,0,null,21],
+try{z=this.I8(a)}finally{this.il.Xq()}return z},"call$1","gyU",2,0,null,21,[]],
 I8:[function(a){var z
 if(a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean")return this.Pq(a)
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$isList))return this.wb(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)return this.TI(a)
 if(typeof a==="object"&&a!==null&&!!z.$isbC)return this.DE(a)
-return this.I9(a)},"call$1","gRQ",2,0,null,21],
-I9:[function(a){throw H.b("Message serialization: Illegal value "+H.d(a)+" passed")},"call$1","gSG",2,0,null,21]},
+if(typeof a==="object"&&a!==null&&!!z.$isIU)return this.yf(a)
+return this.I9(a)},"call$1","gRQ",2,0,null,21,[]],
+I9:[function(a){throw H.b("Message serialization: Illegal value "+H.d(a)+" passed")},"call$1","gSG",2,0,null,21,[]]},
 oo:{
-"":"HU;",
-Pq:[function(a){return a},"call$1","gKz",2,0,null,21],
+"^":"HU;",
+Pq:[function(a){return a},"call$1","gKz",2,0,null,21,[]],
 wb:[function(a){var z,y,x,w,v,u
 z=this.il.t(0,a)
 if(z!=null)return z
@@ -9277,7 +9541,7 @@
 this.il.u(0,a,z)
 for(w=z.length,v=0;v<x;++v){u=this.I8(y.t(a,v))
 if(v>=w)return H.e(z,v)
-z[v]=u}return z},"call$1","gqb",2,0,null,68],
+z[v]=u}return z},"call$1","gqb",2,0,null,68,[]],
 TI:[function(a){var z,y
 z={}
 y=this.il.t(0,a)
@@ -9287,30 +9551,31 @@
 z.a=y
 this.il.u(0,a,y)
 a.aN(0,new H.OW(z,this))
-return z.a},"call$1","gnM",2,0,null,144],
-DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21]},
+return z.a},"call$1","gnM",2,0,null,144,[]],
+DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){return H.vh(P.SY(null))},"call$1","gbM",2,0,null,21,[]]},
 OW:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.b
-J.kW(this.a.a,z.I8(a),z.I8(b))},"call$2",null,4,0,null,42,203,"call"],
+J.kW(this.a.a,z.I8(a),z.I8(b))},"call$2",null,4,0,null,42,[],201,[],"call"],
 $isEH:true},
 hz:{
-"":"HU;",
-Pq:[function(a){return a},"call$1","gKz",2,0,null,21],
+"^":"HU;",
+Pq:[function(a){return a},"call$1","gKz",2,0,null,21,[]],
 wb:[function(a){var z,y
 z=this.il.t(0,a)
 if(z!=null)return["ref",z]
 y=this.CN
 this.CN=y+1
 this.il.u(0,a,y)
-return["list",y,this.mE(a)]},"call$1","gqb",2,0,null,68],
+return["list",y,this.mE(a)]},"call$1","gqb",2,0,null,68,[]],
 TI:[function(a){var z,y
 z=this.il.t(0,a)
 if(z!=null)return["ref",z]
 y=this.CN
 this.CN=y+1
 this.il.u(0,a,y)
-return["map",y,this.mE(J.qA(a.gvc(a))),this.mE(J.qA(a.gUQ(a)))]},"call$1","gnM",2,0,null,144],
+return["map",y,this.mE(J.qA(a.gvc(a))),this.mE(J.qA(a.gUQ(a)))]},"call$1","gnM",2,0,null,144,[]],
 mE:[function(a){var z,y,x,w,v
 z=J.U6(a)
 y=z.gB(a)
@@ -9320,13 +9585,14 @@
 w=0
 for(;w<y;++w){v=this.I8(z.t(a,w))
 if(w>=x.length)return H.e(x,w)
-x[w]=v}return x},"call$1","gBv",2,0,null,68],
-DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21]},
-AP:{
-"":"a;",
+x[w]=v}return x},"call$1","gBv",2,0,null,68,[]],
+DE:[function(a){return H.vh(P.SY(null))},"call$1","goi",2,0,null,21,[]],
+yf:[function(a){return H.vh(P.SY(null))},"call$1","gbM",2,0,null,21,[]]},
+iY:{
+"^":"a;",
 QS:[function(a){if(H.ZR(a))return a
 this.RZ=P.Py(null,null,null,null,null)
-return this.XE(a)},"call$1","gia",2,0,null,21],
+return this.XE(a)},"call$1","gia",2,0,null,21,[]],
 XE:[function(a){var z,y
 if(a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean")return a
 z=J.U6(a)
@@ -9335,7 +9601,8 @@
 case"list":return this.Dj(a)
 case"map":return this.tv(a)
 case"sendport":return this.Vf(a)
-default:return this.PR(a)}},"call$1","gN3",2,0,null,21],
+case"capability":return this.Op(a)
+default:return this.PR(a)}},"call$1","gN3",2,0,null,21,[]],
 Dj:[function(a){var z,y,x,w,v
 z=J.U6(a)
 y=z.t(a,1)
@@ -9346,7 +9613,7 @@
 if(typeof w!=="number")return H.s(w)
 v=0
 for(;v<w;++v)z.u(x,v,this.XE(z.t(x,v)))
-return x},"call$1","gMS",2,0,null,21],
+return x},"call$1","gMS",2,0,null,21,[]],
 tv:[function(a){var z,y,x,w,v,u,t,s
 z=P.L5(null,null,null,null,null)
 y=J.U6(a)
@@ -9360,10 +9627,10 @@
 t=J.U6(v)
 s=0
 for(;s<u;++s)z.u(0,this.XE(y.t(w,s)),this.XE(t.t(v,s)))
-return z},"call$1","gwq",2,0,null,21],
-PR:[function(a){throw H.b("Unexpected serialized object")},"call$1","gec",2,0,null,21]},
+return z},"call$1","gwq",2,0,null,21,[]],
+PR:[function(a){throw H.b("Unexpected serialized object")},"call$1","gec",2,0,null,21,[]]},
 yH:{
-"":"a;Kf,zu,p9",
+"^":"a;Kf,zu,p9",
 ed:[function(){var z,y,x
 z=$.jk()
 if(z.setTimeout!=null){if(this.zu)throw H.b(P.f("Timer in event loop cannot be canceled."))
@@ -9389,22 +9656,44 @@
 z.Qa(a,b)
 return z}}},
 FA:{
-"":"Tp:107;a,b",
+"^":"Tp:107;a,b",
 call$0:[function(){this.a.p9=null
 this.b.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Av:{
-"":"Tp:107;c,d",
+"^":"Tp:107;c,d",
 call$0:[function(){this.c.p9=null
 var z=init.globalState.Xz
 z.bZ=z.bZ-1
 this.d.call$0()},"call$0",null,0,0,null,"call"],
-$isEH:true}}],["_js_helper","dart:_js_helper",,H,{
-"":"",
+$isEH:true},
+ku:{
+"^":"a;ng>",
+giO:function(a){var z,y,x
+z=this.ng
+y=J.Wx(z)
+x=y.m(z,0)
+y=y.Z(z,4294967296)
+if(typeof y!=="number")return H.s(y)
+z=x^y
+z=(~z>>>0)+(z<<15>>>0)&4294967295
+z=((z^z>>>12)>>>0)*5&4294967295
+z=((z^z>>>4)>>>0)*2057&4294967295
+return(z^z>>>16)>>>0},
+n:[function(a,b){var z,y
+if(b==null)return!1
+if(b===this)return!0
+z=J.x(b)
+if(typeof b==="object"&&b!==null&&!!z.$isku){z=this.ng
+y=b.ng
+return z==null?y==null:z===y}return!1},"call$1","gUJ",2,0,null,104,[]],
+$isku:true,
+$isIU:true}}],["_js_helper","dart:_js_helper",,H,{
+"^":"",
 wV:[function(a,b){var z,y
 if(b!=null){z=b.x
 if(z!=null)return z}y=J.x(a)
-return typeof a==="object"&&a!==null&&!!y.$isXj},"call$2","b3",4,0,null,6,22],
+return typeof a==="object"&&a!==null&&!!y.$isXj},"call$2","b3",4,0,null,6,[],22,[]],
 d:[function(a){var z
 if(typeof a==="string")return a
 if(typeof a==="number"){if(a!==0)return""+a}else if(!0===a)return"true"
@@ -9412,12 +9701,12 @@
 else if(a==null)return"null"
 z=J.AG(a)
 if(typeof z!=="string")throw H.b(P.u(a))
-return z},"call$1","mQ",2,0,null,23],
-Hz:[function(a){throw H.b(P.f("Can't use '"+H.d(a)+"' in reflection because it is not included in a @MirrorsUsed annotation."))},"call$1","IT",2,0,null,24],
+return z},"call$1","Sa",2,0,null,23,[]],
+Hz:[function(a){throw H.b(P.f("Can't use '"+H.d(a)+"' in reflection because it is not included in a @MirrorsUsed annotation."))},"call$1","IT",2,0,null,24,[]],
 eQ:[function(a){var z=a.$identityHash
 if(z==null){z=Math.random()*0x3fffffff|0
-a.$identityHash=z}return z},"call$1","Y0",2,0,null,6],
-vx:[function(a){throw H.b(P.cD(a))},"call$1","Rm",2,0,25,26],
+a.$identityHash=z}return z},"call$1","Y0",2,0,null,6,[]],
+vx:[function(a){throw H.b(P.cD(a))},"call$1","Rm",2,0,25,26,[]],
 BU:[function(a,b,c){var z,y,x,w,v,u
 if(c==null)c=H.Rm()
 if(typeof a!=="string")H.vh(new P.AT(a))
@@ -9444,7 +9733,7 @@
 if(!(v<u))break
 y.j(w,0)
 if(y.j(w,v)>x)return c.call$1(a);++v}}}}if(z==null)return c.call$1(a)
-return parseInt(a,b)},"call$3","Yv",6,0,null,27,28,29],
+return parseInt(a,b)},"call$3","Yv",6,0,null,27,[],28,[],29,[]],
 IH:[function(a,b){var z,y
 if(typeof a!=="string")H.vh(new P.AT(a))
 if(b==null)b=H.Rm()
@@ -9452,30 +9741,21 @@
 z=parseFloat(a)
 if(isNaN(z)){y=J.rr(a)
 if(y==="NaN"||y==="+NaN"||y==="-NaN")return z
-return b.call$1(a)}return z},"call$2","zb",4,0,null,27,29],
+return b.call$1(a)}return z},"call$2","zb",4,0,null,27,[],29,[]],
 lh:[function(a){var z,y,x
 z=C.AS(J.x(a))
 if(z==="Object"){y=String(a.constructor).match(/^\s*function\s*(\S*)\s*\(/)[1]
 if(typeof y==="string")z=y}x=J.rY(z)
 if(x.j(z,0)===36)z=x.yn(z,1)
 x=H.oX(a)
-return H.d(z)+H.ia(x,0,null)},"call$1","Ig",2,0,null,6],
-a5:[function(a){return"Instance of '"+H.lh(a)+"'"},"call$1","V8",2,0,null,6],
-mz:[function(){var z,y,x
-if(typeof self!="undefined")return self.location.href
-if(typeof version=="function"&&typeof os=="object"&&"system" in os){z=os.system("pwd")
-y=z.length
-x=y-1
-if(x<0)return H.e(z,x)
-if(z[x]==="\n")z=C.xB.Nj(z,0,x)}else z=null
-if(typeof version=="function"&&typeof system=="function")z=environment.PWD
-return z!=null?C.xB.g("file://",z)+"/":null},"call$0","y9",0,0,null],
+return H.d(z)+H.ia(x,0,null)},"call$1","Ig",2,0,null,6,[]],
+a5:[function(a){return"Instance of '"+H.lh(a)+"'"},"call$1","jb",2,0,null,6,[]],
 VK:[function(a){var z,y,x,w,v,u
 z=a.length
 for(y=z<=500,x="",w=0;w<z;w+=500){if(y)v=a
 else{u=w+500
 u=u<z?u:z
-v=a.slice(w,u)}x+=String.fromCharCode.apply(null,v)}return x},"call$1","Xr",2,0,null,30],
+v=a.slice(w,u)}x+=String.fromCharCode.apply(null,v)}return x},"call$1","ma",2,0,null,30,[]],
 Cq:[function(a){var z,y,x
 z=[]
 z.$builtinTypeInfo=[J.im]
@@ -9485,12 +9765,12 @@
 if(typeof x!=="number"||Math.floor(x)!==x)throw H.b(P.u(x))
 if(x<=65535)z.push(x)
 else if(x<=1114111){z.push(55296+(C.jn.GG(x-65536,10)&1023))
-z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.VK(z)},"call$1","AL",2,0,null,31],
+z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.VK(z)},"call$1","AL",2,0,null,31,[]],
 eT:[function(a){var z,y
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();){y=z.lo
 if(typeof y!=="number"||Math.floor(y)!==y)throw H.b(P.u(y))
 if(y<0)throw H.b(P.u(y))
-if(y>65535)return H.Cq(a)}return H.VK(a)},"call$1","Wb",2,0,null,32],
+if(y>65535)return H.Cq(a)}return H.VK(a)},"call$1","Wb",2,0,null,32,[]],
 zW:[function(a,b,c,d,e,f,g,h){var z,y,x,w
 if(typeof a!=="number"||Math.floor(a)!==a)H.vh(new P.AT(a))
 if(typeof b!=="number"||Math.floor(b)!==b)H.vh(new P.AT(b))
@@ -9505,13 +9785,13 @@
 if(x.E(a,0)||x.C(a,100)){w=new Date(y)
 if(h)w.setUTCFullYear(a)
 else w.setFullYear(a)
-return w.valueOf()}return y},"call$8","ny",16,0,null,33,34,35,36,37,38,39,40],
+return w.valueOf()}return y},"call$8","mV",16,0,null,33,[],34,[],35,[],36,[],37,[],38,[],39,[],40,[]],
 o2:[function(a){if(a.date===void 0)a.date=new Date(a.y3)
-return a.date},"call$1","j1",2,0,null,41],
+return a.date},"call$1","j1",2,0,null,41,[]],
 of:[function(a,b){if(a==null||typeof a==="boolean"||typeof a==="number"||typeof a==="string")throw H.b(new P.AT(a))
-return a[b]},"call$2","De",4,0,null,6,42],
+return a[b]},"call$2","De",4,0,null,6,[],42,[]],
 aw:[function(a,b,c){if(a==null||typeof a==="boolean"||typeof a==="number"||typeof a==="string")throw H.b(new P.AT(a))
-a[b]=c},"call$3","aW",6,0,null,6,42,23],
+a[b]=c},"call$3","WJ",6,0,null,6,[],42,[],23,[]],
 zo:[function(a,b,c){var z,y,x
 z={}
 z.a=0
@@ -9520,7 +9800,7 @@
 if(b!=null){z.a=0+b.length
 C.Nm.FV(y,b)}z.b=""
 if(c!=null&&!c.gl0(c))c.aN(0,new H.Cj(z,y,x))
-return J.jf(a,new H.LI(C.Ka,"call$"+z.a+z.b,0,y,x,null))},"call$3","Ro",6,0,null,15,43,44],
+return J.jf(a,new H.LI(C.Ka,"call$"+z.a+z.b,0,y,x,null))},"call$3","pT",6,0,null,15,[],43,[],44,[]],
 Ek:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 if(c!=null&&!c.gl0(c)){y=J.x(a)["call*"]
@@ -9532,7 +9812,7 @@
 if(w!==b.length)return H.zo(a,b,c)
 v=P.L5(null,null,null,null,null)
 for(u=x.hG,t=x.Rn,s=0;s<u;++s){r=s+w
-v.u(0,init.metadata[t[r+u+3]],init.metadata[x.BX(0,r)])}z.a=!1
+v.u(0,init.metadata[t[2*r+u+3]],init.metadata[x.BX(0,r)])}z.a=!1
 c.aN(0,new H.u8(z,v))
 if(z.a)return H.zo(a,b,c)
 J.bj(b,v.gUQ(v))
@@ -9541,28 +9821,29 @@
 C.Nm.FV(q,b)
 y=a["call$"+p]
 if(y==null)return H.zo(a,b,c)
-return y.apply(a,q)},"call$3","ra",6,0,null,15,43,44],
+return y.apply(a,q)},"call$3","ra",6,0,null,15,[],43,[],44,[]],
 pL:[function(a){if(a=="String")return C.Kn
 if(a=="int")return C.wq
 if(a=="double")return C.yX
 if(a=="num")return C.oD
 if(a=="bool")return C.Fm
 if(a=="List")return C.l0
-return init.allClasses[a]},"call$1","Tg",2,0,null,45],
+if(a=="Null")return C.x0
+return init.allClasses[a]},"call$1","aC",2,0,null,45,[]],
 Pq:[function(){var z={x:0}
 delete z.x
 return z},"call$0","vg",0,0,null],
-s:[function(a){throw H.b(P.u(a))},"call$1","Ff",2,0,null,46],
+s:[function(a){throw H.b(P.u(a))},"call$1","Ff",2,0,null,46,[]],
 e:[function(a,b){if(a==null)J.q8(a)
 if(typeof b!=="number"||Math.floor(b)!==b)H.s(b)
-throw H.b(P.N(b))},"call$2","x3",4,0,null,41,47],
+throw H.b(P.N(b))},"call$2","x3",4,0,null,41,[],47,[]],
 b:[function(a){var z
 if(a==null)a=new P.LK()
 z=new Error()
 z.dartException=a
 if("defineProperty" in Object){Object.defineProperty(z, "message", { get: H.Ju })
 z.name=""}else z.toString=H.Ju
-return z},"call$1","Vb",2,0,null,48],
+return z},"call$1","Vb",2,0,null,48,[]],
 Ju:[function(){return J.AG(this.dartException)},"call$0","Eu",0,0,null],
 vh:[function(a){var z
 if(a==null)a=new P.LK()
@@ -9570,7 +9851,7 @@
 z.dartException=a
 if("defineProperty" in Object){Object.defineProperty(z, "message", { get: H.Ju })
 z.name=""}else z.toString=H.Ju
-throw z},"call$1","xE",2,0,null,48],
+throw z},"call$1","xE",2,0,null,48,[]],
 Ru:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=new H.Am(a)
 if(a==null)return
@@ -9610,28 +9891,28 @@
 return z.call$1(new H.W0(y,v))}}}v=typeof y==="string"?y:""
 return z.call$1(new H.vV(v))}if(a instanceof RangeError){if(typeof y==="string"&&y.indexOf("call stack")!==-1)return new P.VS()
 return z.call$1(new P.AT(null))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof y==="string"&&y==="too much recursion")return new P.VS()
-return a},"call$1","v2",2,0,null,48],
+return a},"call$1","v2",2,0,null,48,[]],
 CU:[function(a){if(a==null||typeof a!='object')return J.v1(a)
-else return H.eQ(a)},"call$1","Zs",2,0,null,6],
+else return H.eQ(a)},"call$1","Zs",2,0,null,6,[]],
 B7:[function(a,b){var z,y,x,w
 z=a.length
 for(y=0;y<z;y=w){x=y+1
 w=x+1
-b.u(0,a[y],a[x])}return b},"call$2","nD",4,0,null,50,51],
+b.u(0,a[y],a[x])}return b},"call$2","nD",4,0,null,50,[],51,[]],
 ft:[function(a,b,c,d,e,f,g){var z=J.x(c)
 if(z.n(c,0))return H.zd(b,new H.dr(a))
 else if(z.n(c,1))return H.zd(b,new H.TL(a,d))
 else if(z.n(c,2))return H.zd(b,new H.KX(a,d,e))
 else if(z.n(c,3))return H.zd(b,new H.uZ(a,d,e,f))
 else if(z.n(c,4))return H.zd(b,new H.OQ(a,d,e,f,g))
-else throw H.b(P.FM("Unsupported number of arguments for wrapped closure"))},"call$7","Le",14,0,null,52,14,53,54,55,56,57],
+else throw H.b(P.FM("Unsupported number of arguments for wrapped closure"))},"call$7","Le",14,0,null,52,[],14,[],53,[],54,[],55,[],56,[],57,[]],
 tR:[function(a,b){var z
 if(a==null)return
 z=a.$identity
 if(!!z)return z
 z=(function(closure, arity, context, invoke) {  return function(a1, a2, a3, a4) {     return invoke(closure, context, arity, a1, a2, a3, a4);  };})(a,b,init.globalState.N0,H.ft)
 a.$identity=z
-return z},"call$2","qN",4,0,null,52,58],
+return z},"call$2","qN",4,0,null,52,[],58,[]],
 iA:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=b[0]
 z.$stubName
@@ -9660,7 +9941,7 @@
 n=o.$callName
 if(n!=null){m=d?o:H.SD(o,t)
 w[n]=m}}w["call*"]=z
-return v},"call$6","Eh",12,0,null,41,59,60,61,62,63],
+return v},"call$6","Eh",12,0,null,41,[],59,[],60,[],61,[],62,[],63,[]],
 vq:[function(a,b){var z=H.eZ
 switch(a){case 0:return function(F,S){return function(){return F.call(S(this))}}(b,z)
 case 1:return function(F,S){return function(a){return F.call(S(this),a)}}(b,z)
@@ -9668,24 +9949,24 @@
 case 3:return function(F,S){return function(a,b,c){return F.call(S(this),a,b,c)}}(b,z)
 case 4:return function(F,S){return function(a,b,c,d){return F.call(S(this),a,b,c,d)}}(b,z)
 case 5:return function(F,S){return function(a,b,c,d,e){return F.call(S(this),a,b,c,d,e)}}(b,z)
-default:return function(f,s){return function(){return f.apply(s(this),arguments)}}(b,z)}},"call$2","X5",4,0,null,58,15],
+default:return function(f,s){return function(){return f.apply(s(this),arguments)}}(b,z)}},"call$2","X5",4,0,null,58,[],15,[]],
 SD:[function(a,b){var z,y,x,w
 if(b)return H.Oj(a)
 z=a.length
 if(typeof dart_precompiled=="function")return H.vq(z,a)
-else if(z===0){y=$.mJ
+else if(z===0){y=$.bf
 if(y==null){y=H.B3("self")
-$.mJ=y}y="return function(){return F.call(this."+H.d(y)+");"
+$.bf=y}y="return function(){return F.call(this."+H.d(y)+");"
 x=$.OK
 $.OK=J.WB(x,1)
 return new Function("F",y+H.d(x)+"}")(a)}else if(1<=z&&z<27){w="abcdefghijklmnopqrstuvwxyz".split("").splice(0,z).join(",")
 y="return function("+w+"){return F.call(this."
-x=$.mJ
+x=$.bf
 if(x==null){x=H.B3("self")
-$.mJ=x}x=y+H.d(x)+","+w+");"
+$.bf=x}x=y+H.d(x)+","+w+");"
 y=$.OK
 $.OK=J.WB(y,1)
-return new Function("F",x+H.d(y)+"}")(a)}else return H.vq(z,a)},"call$2","Fw",4,0,null,15,64],
+return new Function("F",x+H.d(y)+"}")(a)}else return H.vq(z,a)},"call$2","Fw",4,0,null,15,[],64,[]],
 Z4:[function(a,b,c){var z,y
 z=H.eZ
 y=H.yS
@@ -9696,7 +9977,7 @@
 case 4:return function(n,s,r){return function(a,b,c){return s(this)[n](r(this),a,b,c)}}(b,z,y)
 case 5:return function(n,s,r){return function(a,b,c,d){return s(this)[n](r(this),a,b,c,d)}}(b,z,y)
 case 6:return function(n,s,r){return function(a,b,c,d,e){return s(this)[n](r(this),a,b,c,d,e)}}(b,z,y)
-default:return function(f,s,r,a){return function(){a=[r(this)];Array.prototype.push.apply(a,arguments);return f.apply(s(this),a)}}(c,z,y)}},"call$3","SG",6,0,null,58,12,15],
+default:return function(f,s,r,a){return function(){a=[r(this)];Array.prototype.push.apply(a,arguments);return f.apply(s(this),a)}}(c,z,y)}},"call$3","VT",6,0,null,58,[],12,[],15,[]],
 Oj:[function(a){var z,y,x,w,v
 z=a.$stubName
 y=a.length
@@ -9708,39 +9989,39 @@
 x="return function("+v+"){return this."+H.d(H.oN())+"."+z+"(this."+H.d(H.Wz())+","+v+");"
 w=$.OK
 $.OK=J.WB(w,1)
-return new Function(x+H.d(w)+"}")()}else return H.Z4(y,z,a)},"call$1","S4",2,0,null,15],
-qm:[function(a,b,c,d,e,f){b.fixed$length=init
+return new Function(x+H.d(w)+"}")()}else return H.Z4(y,z,a)},"call$1","S4",2,0,null,15,[]],
+Kq:[function(a,b,c,d,e,f){b.fixed$length=init
 c.fixed$length=init
-return H.iA(a,b,c,!!d,e,f)},"call$6","Rz",12,0,null,41,59,60,61,62,12],
+return H.iA(a,b,c,!!d,e,f)},"call$6","lu",12,0,null,41,[],59,[],60,[],61,[],62,[],12,[]],
 SE:[function(a,b){var z=J.U6(b)
-throw H.b(H.aq(H.lh(a),z.Nj(b,3,z.gB(b))))},"call$2","H7",4,0,null,23,66],
+throw H.b(H.aq(H.lh(a),z.Nj(b,3,z.gB(b))))},"call$2","H7",4,0,null,23,[],66,[]],
 Go:[function(a,b){var z
 if(a!=null)z=typeof a==="object"&&J.x(a)[b]
 else z=!0
 if(z)return a
-H.SE(a,b)},"call$2","SR",4,0,null,23,66],
-ag:[function(a){throw H.b(P.Gz("Cyclic initialization for static "+H.d(a)))},"call$1","RK",2,0,null,67],
-KT:[function(a,b,c){return new H.tD(a,b,c,null)},"call$3","HN",6,0,null,69,70,71],
-Og:[function(a,b){var z=a.name
+H.SE(a,b)},"call$2","SR",4,0,null,23,[],66,[]],
+ag:[function(a){throw H.b(P.Gz("Cyclic initialization for static "+H.d(a)))},"call$1","RK",2,0,null,67,[]],
+KT:[function(a,b,c){return new H.tD(a,b,c,null)},"call$3","HN",6,0,null,69,[],70,[],71,[]],
+uK:[function(a,b){var z=a.name
 if(b==null||b.length===0)return new H.tu(z)
-return new H.fw(z,b,null)},"call$2","He",4,0,null,72,73],
+return new H.fw(z,b,null)},"call$2","iw",4,0,null,72,[],73,[]],
 N7:[function(){return C.KZ},"call$0","cI",0,0,null],
-mm:[function(a){return new H.cu(a,null)},"call$1","ut",2,0,null,12],
+mm:[function(a){return new H.cu(a,null)},"call$1","ut",2,0,null,12,[]],
 VM:[function(a,b){if(a!=null)a.$builtinTypeInfo=b
-return a},"call$2","aa",4,0,null,74,75],
+return a},"call$2","aa",4,0,null,74,[],75,[]],
 oX:[function(a){if(a==null)return
-return a.$builtinTypeInfo},"call$1","Qn",2,0,null,74],
-IM:[function(a,b){return H.Y9(a["$as"+H.d(b)],H.oX(a))},"call$2","JW",4,0,null,74,76],
+return a.$builtinTypeInfo},"call$1","Qn",2,0,null,74,[]],
+IM:[function(a,b){return H.Y9(a["$as"+H.d(b)],H.oX(a))},"call$2","PE",4,0,null,74,[],76,[]],
 ip:[function(a,b,c){var z=H.IM(a,b)
-return z==null?null:z[c]},"call$3","Cn",6,0,null,74,76,47],
+return z==null?null:z[c]},"call$3","Cn",6,0,null,74,[],76,[],47,[]],
 Kp:[function(a,b){var z=H.oX(a)
-return z==null?null:z[b]},"call$2","tC",4,0,null,74,47],
+return z==null?null:z[b]},"call$2","tC",4,0,null,74,[],47,[]],
 Ko:[function(a,b){if(a==null)return"dynamic"
 else if(typeof a==="object"&&a!==null&&a.constructor===Array)return a[0].builtin$cls+H.ia(a,1,b)
 else if(typeof a=="function")return a.builtin$cls
 else if(typeof a==="number"&&Math.floor(a)===a)if(b==null)return C.jn.bu(a)
 else return b.call$1(a)
-else return},"call$2$onTypeVariable","bR",2,3,null,77,11,78],
+else return},"call$2$onTypeVariable","bR",2,3,null,77,11,[],78,[]],
 ia:[function(a,b,c){var z,y,x,w,v,u
 if(a==null)return""
 z=P.p9("")
@@ -9750,33 +10031,33 @@
 if(v!=null)w=!1
 u=H.Ko(v,c)
 u=typeof u==="string"?u:H.d(u)
-z.vM=z.vM+u}return w?"":"<"+H.d(z)+">"},"call$3$onTypeVariable","iM",4,3,null,77,79,80,78],
+z.vM=z.vM+u}return w?"":"<"+H.d(z)+">"},"call$3$onTypeVariable","iM",4,3,null,77,79,[],80,[],78,[]],
 dJ:[function(a){var z=typeof a==="object"&&a!==null&&a.constructor===Array?"List":J.x(a).constructor.builtin$cls
-return z+H.ia(a.$builtinTypeInfo,0,null)},"call$1","Yx",2,0,null,6],
+return z+H.ia(a.$builtinTypeInfo,0,null)},"call$1","Yx",2,0,null,6,[]],
 Y9:[function(a,b){if(typeof a==="object"&&a!==null&&a.constructor===Array)b=a
 else if(typeof a=="function"){a=H.ml(a,null,b)
 if(typeof a==="object"&&a!==null&&a.constructor===Array)b=a
-else if(typeof a=="function")b=H.ml(a,null,b)}return b},"call$2","zL",4,0,null,81,82],
+else if(typeof a=="function")b=H.ml(a,null,b)}return b},"call$2","zL",4,0,null,81,[],82,[]],
 RB:[function(a,b,c,d){var z,y
 if(a==null)return!1
 z=H.oX(a)
 y=J.x(a)
 if(y[b]==null)return!1
-return H.hv(H.Y9(y[d],z),c)},"call$4","Ym",8,0,null,6,83,84,85],
+return H.hv(H.Y9(y[d],z),c)},"call$4","Ym",8,0,null,6,[],83,[],84,[],85,[]],
 hv:[function(a,b){var z,y
 if(a==null||b==null)return!0
 z=a.length
 for(y=0;y<z;++y)if(!H.t1(a[y],b[y]))return!1
-return!0},"call$2","QY",4,0,null,86,87],
-IG:[function(a,b,c){return H.ml(a,b,H.IM(b,c))},"call$3","k2",6,0,null,88,89,90],
+return!0},"call$2","QY",4,0,null,86,[],87,[]],
+IG:[function(a,b,c){return H.ml(a,b,H.IM(b,c))},"call$3","k2",6,0,null,88,[],89,[],90,[]],
 Gq:[function(a,b){var z,y
-if(a==null)return b==null||b.builtin$cls==="a"||b.builtin$cls==="PE"
+if(a==null)return b==null||b.builtin$cls==="a"||b.builtin$cls==="Null"
 if(b==null)return!0
 z=H.oX(a)
 a=J.x(a)
 if(z!=null){y=z.slice()
 y.splice(0,0,a)}else y=a
-return H.t1(y,b)},"call$2","TU",4,0,null,91,87],
+return H.t1(y,b)},"call$2","TU",4,0,null,91,[],87,[]],
 t1:[function(a,b){var z,y,x,w,v,u,t
 if(a===b)return!0
 if(a==null||b==null)return!0
@@ -9794,7 +10075,7 @@
 if(!y&&t==null||!w)return!0
 y=y?a.slice(1):null
 w=w?b.slice(1):null
-return H.hv(H.Y9(t,y),w)},"call$2","jm",4,0,null,86,87],
+return H.hv(H.Y9(t,y),w)},"call$2","jm",4,0,null,86,[],87,[]],
 Hc:[function(a,b,c){var z,y,x,w,v
 if(b==null&&a==null)return!0
 if(b==null)return c
@@ -9804,7 +10085,7 @@
 if(c){if(z<y)return!1}else if(z!==y)return!1
 for(x=0;x<y;++x){w=a[x]
 v=b[x]
-if(!(H.t1(w,v)||H.t1(v,w)))return!1}return!0},"call$3","C6",6,0,null,86,87,92],
+if(!(H.t1(w,v)||H.t1(v,w)))return!1}return!0},"call$3","C6",6,0,null,86,[],87,[],92,[]],
 Vt:[function(a,b){var z,y,x,w,v,u
 if(b==null)return!0
 if(a==null)return!1
@@ -9815,7 +10096,7 @@
 if(!Object.hasOwnProperty.call(a,w))return!1
 v=b[w]
 u=a[w]
-if(!(H.t1(v,u)||H.t1(u,v)))return!1}return!0},"call$2","oq",4,0,null,86,87],
+if(!(H.t1(v,u)||H.t1(u,v)))return!1}return!0},"call$2","oq",4,0,null,86,[],87,[]],
 Ly:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 if(!("func" in a))return!1
 if("void" in a){if(!("void" in b)&&"ret" in b)return!1}else if(!("void" in b)){z=a.ret
@@ -9837,12 +10118,12 @@
 n=w[m]
 if(!(H.t1(o,n)||H.t1(n,o)))return!1}for(m=0;m<q;++l,++m){o=v[l]
 n=u[m]
-if(!(H.t1(o,n)||H.t1(n,o)))return!1}}return H.Vt(a.named,b.named)},"call$2","Sj",4,0,null,86,87],
-ml:[function(a,b,c){return a.apply(b,c)},"call$3","Ey",6,0,null,15,41,82],
+if(!(H.t1(o,n)||H.t1(n,o)))return!1}}return H.Vt(a.named,b.named)},"call$2","Sj",4,0,null,86,[],87,[]],
+ml:[function(a,b,c){return a.apply(b,c)},"call$3","Ey",6,0,null,15,[],41,[],82,[]],
 uc:[function(a){var z=$.NF
-return"Instance of "+(z==null?"<Unknown>":z.call$1(a))},"call$1","zB",2,0,null,93],
-Su:[function(a){return H.eQ(a)},"call$1","cx",2,0,null,6],
-iw:[function(a,b,c){Object.defineProperty(a, b, {value: c, enumerable: false, writable: true, configurable: true})},"call$3","OU",6,0,null,93,66,23],
+return"Instance of "+(z==null?"<Unknown>":z.call$1(a))},"call$1","zB",2,0,null,93,[]],
+Su:[function(a){return H.eQ(a)},"call$1","cx",2,0,null,6,[]],
+bm:[function(a,b,c){Object.defineProperty(a, b, {value: c, enumerable: false, writable: true, configurable: true})},"call$3","C5",6,0,null,93,[],66,[],23,[]],
 w3:[function(a){var z,y,x,w,v,u
 z=$.NF.call$1(a)
 y=$.nw[z]
@@ -9868,16 +10149,16 @@
 if(v==="*")throw H.b(P.SY(z))
 if(init.leafTags[z]===true){u=H.Va(x)
 Object.defineProperty(Object.getPrototypeOf(a), init.dispatchPropertyName, {value: u, enumerable: false, writable: true, configurable: true})
-return u.i}else return H.Lc(a,x)},"call$1","eU",2,0,null,93],
+return u.i}else return H.Lc(a,x)},"call$1","eU",2,0,null,93,[]],
 Lc:[function(a,b){var z,y
 z=Object.getPrototypeOf(a)
 y=J.Qu(b,z,null,null)
 Object.defineProperty(z, init.dispatchPropertyName, {value: y, enumerable: false, writable: true, configurable: true})
-return b},"call$2","qF",4,0,null,93,7],
-Va:[function(a){return J.Qu(a,!1,null,!!a.$isXj)},"call$1","UN",2,0,null,7],
+return b},"call$2","qF",4,0,null,93,[],7,[]],
+Va:[function(a){return J.Qu(a,!1,null,!!a.$isXj)},"call$1","oe",2,0,null,7,[]],
 VF:[function(a,b,c){var z=b.prototype
 if(init.leafTags[a]===true)return J.Qu(z,!1,null,!!z.$isXj)
-else return J.Qu(z,c,null,null)},"call$3","di",6,0,null,94,95,8],
+else return J.Qu(z,c,null,null)},"call$3","vi",6,0,null,94,[],95,[],8,[]],
 XD:[function(){if(!0===$.Bv)return
 $.Bv=!0
 H.Z1()},"call$0","Ki",0,0,null],
@@ -9909,8 +10190,8 @@
 t=z.prototypeForTag
 $.NF=new H.dC(v)
 $.TX=new H.wN(u)
-$.x7=new H.VX(t)},"call$0","Qs",0,0,null],
-ud:[function(a,b){return a(b)||b},"call$2","n8",4,0,null,96,97],
+$.x7=new H.VX(t)},"call$0","Bk",0,0,null],
+ud:[function(a,b){return a(b)||b},"call$2","rM",4,0,null,96,[],97,[]],
 ZT:[function(a,b){var z,y,x,w,v,u
 z=H.VM([],[P.Od])
 y=b.length
@@ -9920,13 +10201,13 @@
 z.push(new H.tQ(v,b,a))
 u=v+x
 if(u===y)break
-else w=v===u?w+1:u}return z},"call$2","tl",4,0,null,102,103],
+else w=v===u?w+1:u}return z},"call$2","tl",4,0,null,102,[],103,[]],
 m2:[function(a,b,c){var z,y
 if(typeof b==="string")return C.xB.XU(a,b,c)!==-1
 else{z=J.rY(b)
 if(typeof b==="object"&&b!==null&&!!z.$isVR){z=C.xB.yn(a,c)
 y=b.Ej
-return y.test(z)}else return J.pO(z.dd(b,C.xB.yn(a,c)))}},"call$3","VZ",6,0,null,41,104,80],
+return y.test(z)}else return J.pO(z.dd(b,C.xB.yn(a,c)))}},"call$3","WL",6,0,null,41,[],104,[],80,[]],
 ys:[function(a,b,c){var z,y,x,w,v
 if(typeof b==="string")if(b==="")if(a==="")return c
 else{z=P.p9("")
@@ -9940,61 +10221,61 @@
 if(typeof b==="object"&&b!==null&&!!w.$isVR){v=b.gF4()
 v.lastIndex=0
 return a.replace(v,c.replace("$","$$$$"))}else{if(b==null)H.vh(new P.AT(null))
-throw H.b("String.replaceAll(Pattern) UNIMPLEMENTED")}}},"call$3","eY",6,0,null,41,105,106],
+throw H.b("String.replaceAll(Pattern) UNIMPLEMENTED")}}},"call$3","uF",6,0,null,41,[],105,[],106,[]],
 Zd:{
-"":"a;"},
+"^":"a;"},
 xQ:{
-"":"a;"},
-Q9:{
-"":"a;"},
+"^":"a;"},
+F0:{
+"^":"a;"},
 oH:{
-"":"a;",
+"^":"a;",
 gl0:function(a){return J.de(this.gB(this),0)},
 gor:function(a){return!J.de(this.gB(this),0)},
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 Ix:[function(){throw H.b(P.f("Cannot modify unmodifiable Map"))},"call$0","gPb",0,0,null],
-u:[function(a,b,c){return this.Ix()},"call$2","gj3",4,0,null,42,203],
-Rz:[function(a,b){return this.Ix()},"call$1","gRI",2,0,null,42],
+u:[function(a,b,c){return this.Ix()},"call$2","gj3",4,0,null,42,[],201,[]],
+Rz:[function(a,b){return this.Ix()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return this.Ix()},"call$0","gyP",0,0,null],
-FV:[function(a,b){return this.Ix()},"call$1","gDY",2,0,null,104],
+FV:[function(a,b){return this.Ix()},"call$1","gDY",2,0,null,104,[]],
 $isZ0:true},
 LPe:{
-"":"oH;B>,eZ,tc",
-di:[function(a){return this.gUQ(this).Vr(0,new H.bw(this,a))},"call$1","gmc",2,0,null,102],
+"^":"oH;B>,HV,tc",
+di:[function(a){return this.gUQ(this).Vr(0,new H.bw(this,a))},"call$1","gmc",2,0,null,102,[]],
 x4:[function(a){if(typeof a!=="string")return!1
 if(a==="__proto__")return!1
-return this.eZ.hasOwnProperty(a)},"call$1","gV9",2,0,null,42],
+return this.HV.hasOwnProperty(a)},"call$1","gV9",2,0,null,42,[]],
 t:[function(a,b){if(typeof b!=="string")return
 if(!this.x4(b))return
-return this.eZ[b]},"call$1","gIA",2,0,null,42],
-aN:[function(a,b){J.kH(this.tc,new H.WT(this,b))},"call$1","gjw",2,0,null,110],
+return this.HV[b]},"call$1","gIA",2,0,null,42,[]],
+aN:[function(a,b){J.kH(this.tc,new H.WT(this,b))},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){return H.VM(new H.XR(this),[H.Kp(this,0)])},
 gUQ:function(a){return H.K1(this.tc,new H.jJ(this),H.Kp(this,0),H.Kp(this,1))},
 $isyN:true},
 bw:{
-"":"Tp;a,b",
-call$1:[function(a){return J.de(a,this.b)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){return J.de(a,this.b)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"JF",args:[b]}},this.a,"LPe")}},
 WT:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.b.call$2(a,this.a.t(0,a))},"call$1",null,2,0,null,42,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.b.call$2(a,this.a.t(0,a))},"call$1",null,2,0,null,42,[],"call"],
 $isEH:true},
 jJ:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,42,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,42,[],"call"],
 $isEH:true},
 XR:{
-"":"mW;Y3",
+"^":"mW;Y3",
 gA:function(a){return J.GP(this.Y3.tc)}},
 LI:{
-"":"a;lK,uk,xI,rq,FX,Nc",
+"^":"a;lK,uk,xI,rq,FX,Nc",
 gWa:function(){var z,y,x
 z=this.lK
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$iswv)return z
 x=$.bx().t(0,z)
-if(x!=null){y=J.Gn(x,":")
+if(x!=null){y=x.split(":")
 if(0>=y.length)return H.e(y,0)
 z=y[0]}y=new H.GD(z)
 this.lK=y
@@ -10039,11 +10320,11 @@
 if(u!=null)x=!0
 else z=null}s=!0}else s=!1
 if(typeof u=="function"){if(!("$reflectable" in u))H.Hz(J.GL(this.gWa()))
-if(s)return new H.IW(H.zh(u),u,x,z)
-else return new H.Ny(u,x,z)}else return new H.F3(z)},"call$1","gLk",2,0,null,6],
-static:{"":"hAw,oY,pB"}},
-Ny:{
-"":"a;mr,eK,Ot",
+if(s)return new H.IW(H.zh(u),y,u,x,z)
+else return new H.A2(y,u,x,z)}else return new H.F3(z)},"call$1","gLk",2,0,null,6,[]],
+static:{"^":"hAw,oY,Y8"}},
+A2:{
+"^":"a;Pi<,mr,eK<,Ot",
 gpf:function(){return!1},
 Bj:[function(a,b){var z,y
 if(!this.eK){if(typeof b!=="object"||b===null||b.constructor!==Array)b=P.F(b,!0,null)
@@ -10051,44 +10332,44 @@
 C.Nm.FV(y,b)
 z=this.Ot
 z=z!=null?z:a
-b=y}return this.mr.apply(z,b)},"call$2","gUT",4,0,null,140,82]},
+b=y}return this.mr.apply(z,b)},"call$2","gUT",4,0,null,140,[],82,[]]},
 IW:{
-"":"Ny;qa,mr,eK,Ot",
+"^":"A2;qa,Pi,mr,eK,Ot",
 To:function(a){return this.qa.call$1(a)},
 Bj:[function(a,b){var z,y,x,w,v,u,t
-if(!this.eK){if(typeof b!=="object"||b===null||b.constructor!==Array)b=P.F(b,!0,null)
-z=J.q8(b)
-y=a}else{x=[a]
-C.Nm.FV(x,b)
-y=this.Ot
-y=y!=null?y:a
-z=x.length-1
-b=x}w=this.qa
-v=w.Rv
-u=v+w.hG
-if(w.Mo&&z>v)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+J.q8(b)+" arguments."))
-else if(z<v)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+z+" arguments (too few)."))
-else if(z>u)throw H.b(H.WE("Invocation of unstubbed method '"+w.gx5()+"' with "+z+" arguments (too many)."))
-for(v=J.w1(b),t=z;t<u;++t)v.h(b,init.metadata[w.BX(0,t)])
-return this.mr.apply(y,b)},"call$2","gUT",4,0,null,140,82]},
+z=this.qa
+y=z.Rv
+x=y+z.hG
+if(!this.eK){if(typeof b==="object"&&b!==null&&b.constructor===Array){w=b.length
+if(w<x)b=P.F(b,!0,null)}else{b=P.F(b,!0,null)
+w=b.length}v=a}else{u=[a]
+C.Nm.FV(u,b)
+v=this.Ot
+v=v!=null?v:a
+w=u.length-1
+b=u}if(z.Mo&&w>y)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+b.length+" arguments."))
+else if(w<y)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+w+" arguments (too few)."))
+else if(w>x)throw H.b(H.WE("Invocation of unstubbed method '"+z.gx5()+"' with "+w+" arguments (too many)."))
+for(t=w;t<x;++t)C.Nm.h(b,init.metadata[z.BX(0,t)])
+return this.mr.apply(v,b)},"call$2","gUT",4,0,null,140,[],82,[]]},
 F3:{
-"":"a;e0?",
+"^":"a;e0?",
 gpf:function(){return!0},
 Bj:[function(a,b){var z=this.e0
-return J.jf(z==null?a:z,b)},"call$2","gUT",4,0,null,140,332]},
+return J.jf(z==null?a:z,b)},"call$2","gUT",4,0,null,140,[],326,[]]},
 FD:{
-"":"a;mr,Rn>,XZ,Rv,hG,Mo,AM",
+"^":"a;mr,Rn>,XZ,Rv,hG,Mo,AM",
 BX:[function(a,b){var z=this.Rv
 if(b<z)return
-return this.Rn[3+b-z]},"call$1","gkv",2,0,null,350],
+return this.Rn[3+b-z]},"call$1","gkv",2,0,null,342,[]],
 hl:[function(a){var z,y
 z=this.AM
 if(typeof z=="number")return init.metadata[z]
 else if(typeof z=="function"){y=new a()
 H.VM(y,y["<>"])
-return z.apply({$receiver:y})}else throw H.b(H.Ef("Unexpected function type"))},"call$1","gIX",2,0,null,351],
+return z.apply({$receiver:y})}else throw H.b(H.Ef("Unexpected function type"))},"call$1","gIX",2,0,null,343,[]],
 gx5:function(){return this.mr.$reflectionName},
-static:{"":"t4,FV,C1,mr",zh:function(a){var z,y,x,w
+static:{"^":"t4,FV,C1,bt",zh:function(a){var z,y,x,w
 z=a.$reflectionInfo
 if(z==null)return
 z.fixed$length=init
@@ -10098,21 +10379,21 @@
 w=z[1]
 return new H.FD(a,z,(y&1)===1,x,w>>1,(w&1)===1,z[2])}}},
 Cj:{
-"":"Tp:352;a,b,c",
+"^":"Tp:344;a,b,c",
 call$2:[function(a,b){var z=this.a
 z.b=z.b+"$"+H.d(a)
 this.c.push(a)
 this.b.push(b)
-z.a=z.a+1},"call$2",null,4,0,null,12,46,"call"],
+z.a=z.a+1},"call$2",null,4,0,null,12,[],46,[],"call"],
 $isEH:true},
 u8:{
-"":"Tp:352;a,b",
+"^":"Tp:344;a,b",
 call$2:[function(a,b){var z=this.b
 if(z.x4(a))z.u(0,a,b)
-else this.a.a=!0},"call$2",null,4,0,null,350,23,"call"],
+else this.a.a=!0},"call$2",null,4,0,null,342,[],23,[],"call"],
 $isEH:true},
 Zr:{
-"":"a;bT,rq,Xs,Fa,Ga,EP",
+"^":"a;bT,rq,Xs,Fa,Ga,EP",
 qS:[function(a){var z,y,x
 z=new RegExp(this.bT).exec(a)
 if(z==null)return
@@ -10127,8 +10408,8 @@
 if(x!==-1)y.method=z[x+1]
 x=this.EP
 if(x!==-1)y.receiver=z[x+1]
-return y},"call$1","gul",2,0,null,20],
-static:{"":"lm,k1,Re,fN,qi,rZ,BX,tt,dt,A7",LX:[function(a){var z,y,x,w,v,u
+return y},"call$1","gul",2,0,null,20,[]],
+static:{"^":"lm,k1,Re,fN,qi,rZ,BX,tt,dt,A7",LX:[function(a){var z,y,x,w,v,u
 a=a.replace(String({}), '$receiver$').replace(new RegExp("[[\\]{}()*+?.\\\\^$|]",'g'),'\\$&')
 z=a.match(/\\\$[a-zA-Z]+\\\$/g)
 if(z==null)z=[]
@@ -10137,29 +10418,29 @@
 w=z.indexOf("\\$expr\\$")
 v=z.indexOf("\\$method\\$")
 u=z.indexOf("\\$receiver\\$")
-return new H.Zr(a.replace('\\$arguments\\$','((?:x|[^x])*)').replace('\\$argumentsExpr\\$','((?:x|[^x])*)').replace('\\$expr\\$','((?:x|[^x])*)').replace('\\$method\\$','((?:x|[^x])*)').replace('\\$receiver\\$','((?:x|[^x])*)'),y,x,w,v,u)},"call$1","dx",2,0,null,20],S7:[function(a){return function($expr$) {
+return new H.Zr(a.replace('\\$arguments\\$','((?:x|[^x])*)').replace('\\$argumentsExpr\\$','((?:x|[^x])*)').replace('\\$expr\\$','((?:x|[^x])*)').replace('\\$method\\$','((?:x|[^x])*)').replace('\\$receiver\\$','((?:x|[^x])*)'),y,x,w,v,u)},"call$1","dx",2,0,null,20,[]],S7:[function(a){return function($expr$) {
   var $argumentsExpr$ = '$arguments$'
   try {
     $expr$.$method$($argumentsExpr$);
   } catch (e) {
     return e.message;
   }
-}(a)},"call$1","XG",2,0,null,49],Mj:[function(a){return function($expr$) {
+}(a)},"call$1","XG",2,0,null,49,[]],Mj:[function(a){return function($expr$) {
   try {
     $expr$.$method$;
   } catch (e) {
     return e.message;
   }
-}(a)},"call$1","cl",2,0,null,49]}},
+}(a)},"call$1","cl",2,0,null,49,[]]}},
 W0:{
-"":"Ge;K9,Ga",
+"^":"Ge;K9,Ga",
 bu:[function(a){var z=this.Ga
 if(z==null)return"NullError: "+H.d(this.K9)
 return"NullError: Cannot call \""+H.d(z)+"\" on null"},"call$0","gXo",0,0,null],
 $ismp:true,
 $isGe:true},
 az:{
-"":"Ge;K9,Ga,EP",
+"^":"Ge;K9,Ga,EP",
 bu:[function(a){var z,y
 z=this.Ga
 if(z==null)return"NoSuchMethodError: "+H.d(this.K9)
@@ -10174,17 +10455,17 @@
 z=z?null:b.receiver
 return new H.az(a,y,z)}}},
 vV:{
-"":"Ge;K9",
+"^":"Ge;K9",
 bu:[function(a){var z=this.K9
 return C.xB.gl0(z)?"Error":"Error: "+z},"call$0","gXo",0,0,null]},
 Am:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isGe)if(a.$thrownJsError==null)a.$thrownJsError=this.a
-return a},"call$1",null,2,0,null,146,"call"],
+return a},"call$1",null,2,0,null,152,[],"call"],
 $isEH:true},
 XO:{
-"":"a;lA,ui",
+"^":"a;lA,ui",
 bu:[function(a){var z,y
 z=this.ui
 if(z!=null)return z
@@ -10194,49 +10475,49 @@
 this.ui=z
 return z},"call$0","gXo",0,0,null]},
 dr:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return this.a.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TL:{
-"":"Tp:108;b,c",
+"^":"Tp:108;b,c",
 call$0:[function(){return this.b.call$1(this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 KX:{
-"":"Tp:108;d,e,f",
+"^":"Tp:108;d,e,f",
 call$0:[function(){return this.d.call$2(this.e,this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 uZ:{
-"":"Tp:108;UI,bK,Gq,Rm",
+"^":"Tp:108;UI,bK,Gq,Rm",
 call$0:[function(){return this.UI.call$3(this.bK,this.Gq,this.Rm)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 OQ:{
-"":"Tp:108;w3,HZ,mG,xC,cj",
+"^":"Tp:108;w3,HZ,mG,xC,cj",
 call$0:[function(){return this.w3.call$4(this.HZ,this.mG,this.xC,this.cj)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Tp:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"Closure"},"call$0","gXo",0,0,null],
 $isTp:true,
 $isEH:true},
 Bp:{
-"":"Tp;"},
+"^":"Tp;"},
 v:{
-"":"Bp;nw<,jm<,EP,RA>",
+"^":"Bp;nw<,jm<,EP,RA>",
 n:[function(a,b){var z
 if(b==null)return!1
 if(this===b)return!0
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isv)return!1
-return this.nw===b.nw&&this.jm===b.jm&&this.EP===b.EP},"call$1","gUJ",2,0,null,104],
+return this.nw===b.nw&&this.jm===b.jm&&this.EP===b.EP},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z,y
 z=this.EP
 if(z==null)y=H.eQ(this.nw)
 else y=typeof z!=="object"?J.v1(z):H.eQ(z)
-return(y^H.eQ(this.jm))>>>0},
+return J.UN(y,H.eQ(this.jm))},
 $isv:true,
-static:{"":"mJ,P4",eZ:[function(a){return a.gnw()},"call$1","PR",2,0,null,52],yS:[function(a){return a.EP},"call$1","h0",2,0,null,52],oN:[function(){var z=$.mJ
+static:{"^":"bf,P4",eZ:[function(a){return a.gnw()},"call$1","PR",2,0,null,52,[]],yS:[function(a){return a.EP},"call$1","h0",2,0,null,52,[]],oN:[function(){var z=$.bf
 if(z==null){z=H.B3("self")
-$.mJ=z}return z},"call$0","uT",0,0,null],Wz:[function(){var z=$.P4
+$.bf=z}return z},"call$0","uT",0,0,null],Wz:[function(){var z=$.P4
 if(z==null){z=H.B3("receiver")
 $.P4=z}return z},"call$0","TT",0,0,null],B3:[function(a){var z,y,x,w,v
 z=new H.v("self","target","receiver","name")
@@ -10244,30 +10525,30 @@
 y.fixed$length=init
 x=y
 for(y=x.length,w=0;w<y;++w){v=x[w]
-if(z[v]===a)return v}},"call$1","ec",2,0,null,65]}},
+if(z[v]===a)return v}},"call$1","ec",2,0,null,65,[]]}},
 Ll:{
-"":"a;Jy"},
+"^":"a;Jy"},
 dN:{
-"":"a;Jy"},
+"^":"a;Jy"},
 GT:{
-"":"a;oc>"},
+"^":"a;oc>"},
 Pe:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return this.G1},"call$0","gXo",0,0,null],
 $isGe:true,
 static:{aq:function(a,b){return new H.Pe("CastError: Casting value of type "+a+" to incompatible type "+H.d(b))}}},
 Eq:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"RuntimeError: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{Ef:function(a){return new H.Eq(a)}}},
 lb:{
-"":"a;"},
+"^":"a;"},
 tD:{
-"":"lb;dw,Iq,is,p6",
+"^":"lb;dw,Iq,is,p6",
 BD:[function(a){var z=this.rP(a)
-return z==null?!1:H.Ly(z,this.za())},"call$1","gQ4",2,0,null,49],
+return z==null?!1:H.Ly(z,this.za())},"call$1","gQ4",2,0,null,49,[]],
 rP:[function(a){var z=J.x(a)
-return"$signature" in z?z.$signature():null},"call$1","gie",2,0,null,91],
+return"$signature" in z?z.$signature():null},"call$1","gie",2,0,null,91,[]],
 za:[function(){var z,y,x,w,v,u,t
 z={ "func": "dynafunc" }
 y=this.dw
@@ -10298,18 +10579,18 @@
 for(y=t.length,w=!1,v=0;v<y;++v,w=!0){s=t[v]
 if(w)x+=", "
 x+=H.d(z[s].za())+" "+s}x+="}"}}return x+(") -> "+H.d(this.dw))},"call$0","gXo",0,0,null],
-static:{"":"Ot",Dz:[function(a){var z,y,x
+static:{"^":"Ot",Dz:[function(a){var z,y,x
 a=a
 z=[]
 for(y=a.length,x=0;x<y;++x)z.push(a[x].za())
-return z},"call$1","At",2,0,null,68]}},
+return z},"call$1","eL",2,0,null,68,[]]}},
 hJ:{
-"":"lb;",
+"^":"lb;",
 bu:[function(a){return"dynamic"},"call$0","gXo",0,0,null],
 za:[function(){return},"call$0","gpA",0,0,null],
 $ishJ:true},
 tu:{
-"":"lb;oc>",
+"^":"lb;oc>",
 za:[function(){var z,y
 z=this.oc
 y=init.allClasses[z]
@@ -10317,7 +10598,7 @@
 return y},"call$0","gpA",0,0,null],
 bu:[function(a){return this.oc},"call$0","gXo",0,0,null]},
 fw:{
-"":"lb;oc>,re<,Et",
+"^":"lb;oc>,re<,Et",
 za:[function(){var z,y
 z=this.Et
 if(z!=null)return z
@@ -10330,13 +10611,13 @@
 return y},"call$0","gpA",0,0,null],
 bu:[function(a){return this.oc+"<"+J.XS(this.re,", ")+">"},"call$0","gXo",0,0,null]},
 Zz:{
-"":"Ge;K9",
+"^":"Ge;K9",
 bu:[function(a){return"Unsupported operation: "+this.K9},"call$0","gXo",0,0,null],
 $ismp:true,
 $isGe:true,
 static:{WE:function(a){return new H.Zz(a)}}},
 cu:{
-"":"a;LU<,ke",
+"^":"a;LU<,ke",
 bu:[function(a){var z,y,x
 z=this.ke
 if(z!=null)return z
@@ -10349,25 +10630,25 @@
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iscu&&J.de(this.LU,b.LU)},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$iscu&&J.de(this.LU,b.LU)},"call$1","gUJ",2,0,null,104,[]],
 $iscu:true,
 $isuq:true},
 Lm:{
-"":"a;XP<,oc>,kU>"},
+"^":"a;XP<,oc>,kU>"},
 dC:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 wN:{
-"":"Tp:353;b",
-call$2:[function(a,b){return this.b(a,b)},"call$2",null,4,0,null,91,94,"call"],
+"^":"Tp:345;b",
+call$2:[function(a,b){return this.b(a,b)},"call$2",null,4,0,null,91,[],94,[],"call"],
 $isEH:true},
 VX:{
-"":"Tp:25;c",
-call$1:[function(a){return this.c(a)},"call$1",null,2,0,null,94,"call"],
+"^":"Tp:25;c",
+call$1:[function(a){return this.c(a)},"call$1",null,2,0,null,94,[],"call"],
 $isEH:true},
 VR:{
-"":"a;Ej,Ii,Ua",
+"^":"a;Ej,Ii,Ua",
 gF4:function(){var z=this.Ii
 if(z!=null)return z
 z=this.Ej
@@ -10384,17 +10665,16 @@
 if(typeof a!=="string")H.vh(new P.AT(a))
 z=this.Ej.exec(a)
 if(z==null)return
-return H.yx(this,z)},"call$1","gvz",2,0,null,340],
+return H.yx(this,z)},"call$1","gvz",2,0,null,334,[]],
 zD:[function(a){if(typeof a!=="string")H.vh(new P.AT(a))
-return this.Ej.test(a)},"call$1","guf",2,0,null,340],
-dd:[function(a,b){if(typeof b!=="string")H.vh(new P.AT(b))
-return new H.KW(this,b)},"call$1","gYv",2,0,null,340],
+return this.Ej.test(a)},"call$1","guf",2,0,null,334,[]],
+dd:[function(a,b){return new H.KW(this,b)},"call$1","gYv",2,0,null,334,[]],
 yk:[function(a,b){var z,y
 z=this.gF4()
 z.lastIndex=b
 y=z.exec(a)
 if(y==null)return
-return H.yx(this,y)},"call$2","gow",4,0,null,26,115],
+return H.yx(this,y)},"call$2","gow",4,0,null,26,[],115,[]],
 Bh:[function(a,b){var z,y,x,w
 z=this.gAT()
 z.lastIndex=b
@@ -10405,13 +10685,13 @@
 if(w<0)return H.e(y,w)
 if(y[w]!=null)return
 J.wg(y,w)
-return H.yx(this,y)},"call$2","gq0",4,0,null,26,115],
+return H.yx(this,y)},"call$2","gm4",4,0,null,26,[],115,[]],
 wL:[function(a,b,c){var z
 if(c>=0){z=J.q8(b)
 if(typeof z!=="number")return H.s(z)
 z=c>z}else z=!0
 if(z)throw H.b(P.TE(c,0,J.q8(b)))
-return this.Bh(b,c)},function(a,b){return this.wL(a,b,0)},"R4","call$2",null,"grS",2,2,null,336,26,115],
+return this.Bh(b,c)},function(a,b){return this.wL(a,b,0)},"R4","call$2",null,"grS",2,2,null,330,26,[],115,[]],
 $isVR:true,
 $iscT:true,
 static:{v4:[function(a,b,c,d){var z,y,x,w,v
@@ -10421,24 +10701,24 @@
 w=(function() {try {return new RegExp(a, z + y + x);} catch (e) {return e;}})()
 if(w instanceof RegExp)return w
 v=String(w)
-throw H.b(P.cD("Illegal RegExp pattern: "+a+", "+v))},"call$4","ka",8,0,null,98,99,100,101]}},
+throw H.b(P.cD("Illegal RegExp pattern: "+a+", "+v))},"call$4","ka",8,0,null,98,[],99,[],100,[],101,[]]}},
 EK:{
-"":"a;zO,QK<",
+"^":"a;zO,QK<",
 t:[function(a,b){var z=this.QK
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 VO:function(a,b){},
 $isOd:true,
 static:{yx:function(a,b){var z=new H.EK(a,b)
 z.VO(a,b)
 return z}}},
 KW:{
-"":"mW;Gf,rv",
+"^":"mW;Gf,rv",
 gA:function(a){return new H.Pb(this.Gf,this.rv,null)},
 $asmW:function(){return[P.Od]},
 $ascX:function(){return[P.Od]}},
 Pb:{
-"":"a;VV,rv,Wh",
+"^":"a;VV,rv,Wh",
 gl:function(){return this.Wh},
 G:[function(){var z,y,x
 if(this.rv==null)return!1
@@ -10453,22 +10733,22 @@
 z=this.VV.yk(this.rv,x)
 this.Wh=z
 if(z==null){this.rv=null
-return!1}return!0},"call$0","guK",0,0,null]},
+return!1}return!0},"call$0","gqy",0,0,null]},
 tQ:{
-"":"a;M,J9,zO",
+"^":"a;M,J9,zO",
 t:[function(a,b){if(!J.de(b,0))H.vh(P.N(b))
-return this.zO},"call$1","gIA",2,0,null,354],
+return this.zO},"call$1","gIA",2,0,null,346,[]],
 $isOd:true}}],["app_bootstrap","index_devtools.html_bootstrap.dart",,E,{
-"":"",
-QL:[function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/breakpoint_list.dart","package:observatory/src/observatory_elements/service_ref.dart","package:observatory/src/observatory_elements/class_ref.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/field_ref.dart","package:observatory/src/observatory_elements/function_ref.dart","package:observatory/src/observatory_elements/instance_ref.dart","package:observatory/src/observatory_elements/library_ref.dart","package:observatory/src/observatory_elements/class_view.dart","package:observatory/src/observatory_elements/code_ref.dart","package:observatory/src/observatory_elements/disassembly_entry.dart","package:observatory/src/observatory_elements/code_view.dart","package:observatory/src/observatory_elements/collapsible_content.dart","package:observatory/src/observatory_elements/field_view.dart","package:observatory/src/observatory_elements/function_view.dart","package:observatory/src/observatory_elements/isolate_summary.dart","package:observatory/src/observatory_elements/isolate_list.dart","package:observatory/src/observatory_elements/instance_view.dart","package:observatory/src/observatory_elements/json_view.dart","package:observatory/src/observatory_elements/script_ref.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/heap_profile.dart","package:observatory/src/observatory_elements/script_view.dart","package:observatory/src/observatory_elements/stack_frame.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar_isolate.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/isolate_profile.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","main.dart"]
+"^":"",
+QL:[function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/breakpoint_list.dart","package:observatory/src/observatory_elements/service_ref.dart","package:observatory/src/observatory_elements/class_ref.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/field_ref.dart","package:observatory/src/observatory_elements/function_ref.dart","package:observatory/src/observatory_elements/instance_ref.dart","package:observatory/src/observatory_elements/library_ref.dart","package:observatory/src/observatory_elements/class_view.dart","package:observatory/src/observatory_elements/code_ref.dart","package:observatory/src/observatory_elements/disassembly_entry.dart","package:observatory/src/observatory_elements/code_view.dart","package:observatory/src/observatory_elements/collapsible_content.dart","package:observatory/src/observatory_elements/field_view.dart","package:observatory/src/observatory_elements/function_view.dart","package:observatory/src/observatory_elements/script_ref.dart","package:observatory/src/observatory_elements/isolate_summary.dart","package:observatory/src/observatory_elements/isolate_list.dart","package:observatory/src/observatory_elements/instance_view.dart","package:observatory/src/observatory_elements/json_view.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/heap_profile.dart","package:observatory/src/observatory_elements/script_view.dart","package:observatory/src/observatory_elements/stack_frame.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar_isolate.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/isolate_profile.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","main.dart"]
 $.uP=!1
-F.E2()},"call$0","Im",0,0,107]},1],["breakpoint_list_element","package:observatory/src/observatory_elements/breakpoint_list.dart",,B,{
-"":"",
+F.E2()},"call$0","Pc",0,0,107]},1],["breakpoint_list_element","package:observatory/src/observatory_elements/breakpoint_list.dart",,B,{
+"^":"",
 G6:{
-"":["Vf;eE%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-grs:[function(a){return a.eE},null,null,1,0,358,"msg",359,360],
-srs:[function(a,b){a.eE=this.ct(a,C.UX,a.eE,b)},null,null,3,0,361,23,"msg",359],
-"@":function(){return[C.PT]},
+"^":["Vf;BW%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+grs:[function(a){return a.BW},null,null,1,0,350,"msg",351,352],
+srs:[function(a,b){a.BW=this.ct(a,C.UX,a.BW,b)},null,null,3,0,353,23,[],"msg",351],
+"@":function(){return[C.lT]},
 static:{Dw:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -10477,20 +10757,20 @@
 w=J.O
 v=W.cv
 v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
-a.eE=z
+a.BW=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.J0.ZL(a)
-C.J0.oX(a)
-return a},null,null,0,0,108,"new BreakpointListElement$created" /* new BreakpointListElement$created:0:0 */]}},
-"+BreakpointListElement":[362],
+C.J0.G6(a)
+return a},null,null,0,0,108,"new BreakpointListElement$created"]}},
+"+BreakpointListElement":[354],
 Vf:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["class_ref_element","package:observatory/src/observatory_elements/class_ref.dart",,Q,{
-"":"",
-kf:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":"",
+Tg:{
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.OS]},
 static:{rt:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10499,18 +10779,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.YZ.ZL(a)
-C.YZ.oX(a)
-return a},null,null,0,0,108,"new ClassRefElement$created" /* new ClassRefElement$created:0:0 */]}},
-"+ClassRefElement":[364]}],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{
-"":"",
+C.YZ.G6(a)
+return a},null,null,0,0,108,"new ClassRefElement$created"]}},
+"+ClassRefElement":[357]}],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{
+"^":"",
 Ps:{
-"":["pv;F0%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gRu:[function(a){return a.F0},null,null,1,0,358,"cls",359,360],
-sRu:[function(a,b){a.F0=this.ct(a,C.XA,a.F0,b)},null,null,3,0,361,23,"cls",359],
+"^":["pv;F0%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gRu:[function(a){return a.F0},null,null,1,0,350,"cls",351,352],
+sRu:[function(a,b){a.F0=this.ct(a,C.XA,a.F0,b)},null,null,3,0,353,23,[],"cls",351],
 "@":function(){return[C.aQ]},
 static:{zg:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10520,17 +10801,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.kk.ZL(a)
-C.kk.oX(a)
-return a},null,null,0,0,108,"new ClassViewElement$created" /* new ClassViewElement$created:0:0 */]}},
-"+ClassViewElement":[365],
+C.kk.G6(a)
+return a},null,null,0,0,108,"new ClassViewElement$created"]}},
+"+ClassViewElement":[358],
 pv:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["code_ref_element","package:observatory/src/observatory_elements/code_ref.dart",,O,{
-"":"",
+"^":"",
 CN:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.U8]},
 static:{On:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10539,19 +10820,20 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.IK.ZL(a)
-C.IK.oX(a)
-return a},null,null,0,0,108,"new CodeRefElement$created" /* new CodeRefElement$created:0:0 */]}},
-"+CodeRefElement":[364]}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{
-"":"",
+C.IK.G6(a)
+return a},null,null,0,0,108,"new CodeRefElement$created"]}},
+"+CodeRefElement":[357]}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{
+"^":"",
 vc:{
-"":["Vfx;eJ%-366,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtT:[function(a){return a.eJ},null,null,1,0,367,"code",359,360],
-stT:[function(a,b){a.eJ=this.ct(a,C.b1,a.eJ,b)},null,null,3,0,368,23,"code",359],
-gtgn:[function(a){return"panel panel-success"},null,null,1,0,369,"cssPanelClass"],
+"^":["Vfx;eJ%-359,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtT:[function(a){return a.eJ},null,null,1,0,360,"code",351,352],
+stT:[function(a,b){a.eJ=this.ct(a,C.b1,a.eJ,b)},null,null,3,0,361,23,[],"code",351],
+grj:[function(a){return"panel panel-success"},null,null,1,0,362,"cssPanelClass"],
 "@":function(){return[C.xW]},
 static:{Fe:[function(a){var z,y,x,w
 z=$.Nd()
@@ -10561,29 +10843,29 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.YD.ZL(a)
-C.YD.oX(a)
-return a},null,null,0,0,108,"new CodeViewElement$created" /* new CodeViewElement$created:0:0 */]}},
-"+CodeViewElement":[370],
+C.YD.G6(a)
+return a},null,null,0,0,108,"new CodeViewElement$created"]}},
+"+CodeViewElement":[363],
 Vfx:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["collapsible_content_element","package:observatory/src/observatory_elements/collapsible_content.dart",,R,{
-"":"",
+"^":"",
 i6:{
-"":["Dsd;zh%-371,HX%-371,Uy%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gl7:[function(a){return a.zh},null,null,1,0,369,"iconClass",359,372],
-sl7:[function(a,b){a.zh=this.ct(a,C.Di,a.zh,b)},null,null,3,0,25,23,"iconClass",359],
-gai:[function(a){return a.HX},null,null,1,0,369,"displayValue",359,372],
-sai:[function(a,b){a.HX=this.ct(a,C.Jw,a.HX,b)},null,null,3,0,25,23,"displayValue",359],
-gxj:[function(a){return a.Uy},null,null,1,0,373,"collapsed"],
+"^":["Dsd;zh%-364,HX%-364,Uy%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gl7:[function(a){return a.zh},null,null,1,0,362,"iconClass",351,365],
+sl7:[function(a,b){a.zh=this.ct(a,C.Di,a.zh,b)},null,null,3,0,25,23,[],"iconClass",351],
+gai:[function(a){return a.HX},null,null,1,0,362,"displayValue",351,365],
+sai:[function(a,b){a.HX=this.ct(a,C.Jw,a.HX,b)},null,null,3,0,25,23,[],"displayValue",351],
+gxj:[function(a){return a.Uy},null,null,1,0,366,"collapsed"],
 sxj:[function(a,b){a.Uy=b
-this.SS(a)},null,null,3,0,374,375,"collapsed"],
+this.SS(a)},null,null,3,0,367,368,[],"collapsed"],
 i4:[function(a){Z.uL.prototype.i4.call(this,a)
 this.SS(a)},"call$0","gQd",0,0,107,"enteredView"],
 jp:[function(a,b,c,d){a.Uy=a.Uy!==!0
 this.SS(a)
-this.SS(a)},"call$3","gl8",6,0,376,18,307,74,"toggleDisplay"],
+this.SS(a)},"call$3","gl8",6,0,369,18,[],301,[],74,[],"toggleDisplay"],
 SS:[function(a){var z,y
 z=a.Uy
 y=a.zh
@@ -10591,7 +10873,7 @@
 a.HX=this.ct(a,C.Jw,a.HX,"none")}else{a.zh=this.ct(a,C.Di,y,"glyphicon glyphicon-chevron-up")
 a.HX=this.ct(a,C.Jw,a.HX,"block")}},"call$0","glg",0,0,107,"_refresh"],
 "@":function(){return[C.Gu]},
-static:{"":"Vl<-371,DI<-371",Hv:[function(a){var z,y,x,w
+static:{"^":"Vl<-364,DI<-364",Hv:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -10602,37 +10884,37 @@
 a.Uy=!0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.j8.ZL(a)
-C.j8.oX(a)
-return a},null,null,0,0,108,"new CollapsibleContentElement$created" /* new CollapsibleContentElement$created:0:0 */]}},
-"+CollapsibleContentElement":[377],
+C.j8.G6(a)
+return a},null,null,0,0,108,"new CollapsibleContentElement$created"]}},
+"+CollapsibleContentElement":[370],
 Dsd:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["custom_element.polyfill","package:custom_element/polyfill.dart",,B,{
-"":"",
+"^":"",
 G9:function(){var z,y
 z=$.cM()
 if(z==null)return!0
 y=J.UQ(z,"CustomElements")
-if(y==null)return"register" in document
+if(y==null)return"registerElement" in document
 return J.de(J.UQ(y,"ready"),!0)},
 wJ:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){if(B.G9()){var z=H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[null])
 z.L7(null,null)
 return z}z=H.VM(new W.RO(document,"WebComponentsReady",!1),[null])
 return z.gtH(z)},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["dart._internal","dart:_internal",,H,{
-"":"",
+"^":"",
 bQ:[function(a,b){var z
-for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.lo)},"call$2","Mn",4,0,null,109,110],
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.lo)},"call$2","Mn",4,0,null,109,[],110,[]],
 Ck:[function(a,b){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)if(b.call$1(z.lo)===!0)return!0
-return!1},"call$2","cs",4,0,null,109,110],
+return!1},"call$2","cs",4,0,null,109,[],110,[]],
 n3:[function(a,b,c){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b=c.call$2(b,z.lo)
-return b},"call$3","hp",6,0,null,109,111,112],
+return b},"call$3","hp",6,0,null,109,[],111,[],112,[]],
 mx:[function(a,b,c){var z,y,x
 for(y=0;x=$.RM(),y<x.length;++y)if(x[y]===a)return H.d(b)+"..."+H.d(c)
 z=P.p9("")
@@ -10641,19 +10923,19 @@
 z.We(a,", ")
 z.KF(c)}finally{x=$.RM()
 if(0>=x.length)return H.e(x,0)
-x.pop()}return z.gvM()},"call$3","FQ",6,0,null,109,113,114],
-S6:[function(a,b,c){var z=J.Wx(b)
+x.pop()}return z.gvM()},"call$3","FQ",6,0,null,109,[],113,[],114,[]],
+K0:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.D(b,a.length))throw H.b(P.TE(b,0,a.length))
 z=J.Wx(c)
-if(z.C(c,b)||z.D(c,a.length))throw H.b(P.TE(c,b,a.length))},"call$3","p5",6,0,null,68,115,116],
-qG:[function(a,b,c,d,e){var z,y
-H.S6(a,b,c)
+if(z.C(c,b)||z.D(c,a.length))throw H.b(P.TE(c,b,a.length))},"call$3","Ze",6,0,null,68,[],115,[],116,[]],
+Og:[function(a,b,c,d,e){var z,y
+H.K0(a,b,c)
 z=J.xH(c,b)
 if(J.de(z,0))return
 y=J.Wx(e)
 if(y.C(e,0))throw H.b(new P.AT(e))
-if(J.z8(y.g(e,z),J.q8(d)))throw H.b(P.w("Not enough elements"))
-H.Gj(d,e,a,b,z)},"call$5","it",10,0,null,68,115,116,105,117],
+if(J.z8(y.g(e,z),J.q8(d)))throw H.b(new P.lj("Not enough elements"))
+H.tb(d,e,a,b,z)},"call$5","rK",10,0,null,68,[],115,[],116,[],105,[],117,[]],
 IC:[function(a,b,c){var z,y,x,w,v,u
 z=J.Wx(b)
 if(z.C(b,0)||z.D(b,a.length))throw H.b(P.TE(b,0,a.length))
@@ -10665,34 +10947,34 @@
 z=z.g(b,x)
 w=a.length
 if(!!a.immutable$list)H.vh(P.f("set range"))
-H.qG(a,z,w,a,b)
+H.Og(a,z,w,a,b)
 for(z=y.gA(c);z.G();b=u){v=z.lo
 u=J.WB(b,1)
-C.Nm.u(a,b,v)}},"call$3","f3",6,0,null,68,47,109],
-Gj:[function(a,b,c,d,e){var z,y,x,w,v
+C.Nm.u(a,b,v)}},"call$3","f3",6,0,null,68,[],47,[],109,[]],
+tb:[function(a,b,c,d,e){var z,y,x,w,v
 z=J.Wx(b)
 if(z.C(b,d))for(y=J.xH(z.g(b,e),1),x=J.xH(J.WB(d,e),1),z=J.U6(a);w=J.Wx(y),w.F(y,b);y=w.W(y,1),x=J.xH(x,1))C.Nm.u(c,x,z.t(a,y))
-else for(w=J.U6(a),x=d,y=b;v=J.Wx(y),v.C(y,z.g(b,e));y=v.g(y,1),x=J.WB(x,1))C.Nm.u(c,x,w.t(a,y))},"call$5","E9",10,0,null,118,119,120,121,122],
-Ri:[function(a,b,c,d){var z
+else for(w=J.U6(a),x=d,y=b;v=J.Wx(y),v.C(y,z.g(b,e));y=v.g(y,1),x=J.WB(x,1))C.Nm.u(c,x,w.t(a,y))},"call$5","e8",10,0,null,118,[],119,[],120,[],121,[],122,[]],
+TK:[function(a,b,c,d){var z
 if(c>=a.length)return-1
 for(z=c;z<d;++z){if(z>=a.length)return H.e(a,z)
-if(J.de(a[z],b))return z}return-1},"call$4","Nk",8,0,null,123,124,80,125],
-lO:[function(a,b,c){var z,y
+if(J.de(a[z],b))return z}return-1},"call$4","Yh",8,0,null,123,[],124,[],80,[],125,[]],
+eX:[function(a,b,c){var z,y
 if(typeof c!=="number")return c.C()
 if(c<0)return-1
 z=a.length
 if(c>=z)c=z-1
 for(y=c;y>=0;--y){if(y>=a.length)return H.e(a,y)
-if(J.de(a[y],b))return y}return-1},"call$3","MW",6,0,null,123,124,80],
+if(J.de(a[y],b))return y}return-1},"call$3","Gf",6,0,null,123,[],124,[],80,[]],
 ZE:[function(a,b,c,d){if(J.Hb(J.xH(c,b),32))H.d1(a,b,c,d)
-else H.d4(a,b,c,d)},"call$4","UR",8,0,null,123,126,127,128],
+else H.d4(a,b,c,d)},"call$4","UR",8,0,null,123,[],126,[],127,[],128,[]],
 d1:[function(a,b,c,d){var z,y,x,w,v,u
 for(z=J.WB(b,1),y=J.U6(a);x=J.Wx(z),x.E(z,c);z=x.g(z,1)){w=y.t(a,z)
 v=z
 while(!0){u=J.Wx(v)
 if(!(u.D(v,b)&&J.z8(d.call$2(y.t(a,u.W(v,1)),w),0)))break
 y.u(a,v,y.t(a,u.W(v,1)))
-v=u.W(v,1)}y.u(a,v,w)}},"call$4","aH",8,0,null,123,126,127,128],
+v=u.W(v,1)}y.u(a,v,w)}},"call$4","aH",8,0,null,123,[],126,[],127,[],128,[]],
 d4:[function(a,b,a0,a1){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c
 z=J.Wx(a0)
 y=J.IJ(J.WB(z.W(a0,b),1),6)
@@ -10793,16 +11075,16 @@
 k=e}else{t.u(a,i,t.t(a,j))
 d=x.W(j,1)
 t.u(a,j,h)
-j=d}break}}H.ZE(a,k,j,a1)}else H.ZE(a,k,j,a1)},"call$4","Hm",8,0,null,123,126,127,128],
+j=d}break}}H.ZE(a,k,j,a1)}else H.ZE(a,k,j,a1)},"call$4","Hm",8,0,null,123,[],126,[],127,[],128,[]],
 aL:{
-"":"mW;",
+"^":"mW;",
 gA:function(a){return H.VM(new H.a7(this,this.gB(this),0,null),[H.ip(this,"aL",0)])},
 aN:[function(a,b){var z,y
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){b.call$1(this.Zv(0,y))
-if(z!==this.gB(this))throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,378],
+if(z!==this.gB(this))throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
 gl0:function(a){return J.de(this.gB(this),0)},
 grZ:function(a){if(J.de(this.gB(this),0))throw H.b(new P.lj("No elements"))
 return this.Zv(0,J.xH(this.gB(this),1))},
@@ -10811,13 +11093,13 @@
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(J.de(this.Zv(0,y),b))return!0
-if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gdj",2,0,null,124],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gdj",2,0,null,124,[]],
 Vr:[function(a,b){var z,y
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(b.call$1(this.Zv(0,y))===!0)return!0
-if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gG2",2,0,null,379],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return!1},"call$1","gG2",2,0,null,372,[]],
 zV:[function(a,b){var z,y,x,w,v,u
 z=this.gB(this)
 if(b.length!==0){y=J.x(z)
@@ -10837,17 +11119,17 @@
 for(;v<z;++v){u=this.Zv(0,v)
 u=typeof u==="string"?u:H.d(u)
 w.vM=w.vM+u
-if(z!==this.gB(this))throw H.b(P.a4(this))}return w.vM}},"call$1","gnr",0,2,null,334,335],
-ev:[function(a,b){return P.mW.prototype.ev.call(this,this,b)},"call$1","gIR",2,0,null,379],
-ez:[function(a,b){return H.VM(new H.A8(this,b),[null,null])},"call$1","gIr",2,0,null,110],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return w.vM}},"call$1","gnr",0,2,null,328,329,[]],
+ev:[function(a,b){return P.mW.prototype.ev.call(this,this,b)},"call$1","gIR",2,0,null,372,[]],
+ez:[function(a,b){return H.VM(new H.A8(this,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
 es:[function(a,b,c){var z,y,x
 z=this.gB(this)
 if(typeof z!=="number")return H.s(z)
 y=b
 x=0
 for(;x<z;++x){y=c.call$2(y,this.Zv(0,x))
-if(z!==this.gB(this))throw H.b(P.a4(this))}return y},"call$2","gTu",4,0,null,111,112],
-eR:[function(a,b){return H.j5(this,b,null,null)},"call$1","gVQ",2,0,null,122],
+if(z!==this.gB(this))throw H.b(P.a4(this))}return y},"call$2","gTu",4,0,null,111,[],112,[]],
+eR:[function(a,b){return H.j5(this,b,null,null)},"call$1","gZo",2,0,null,122,[]],
 tt:[function(a,b){var z,y,x
 if(b){z=H.VM([],[H.ip(this,"aL",0)])
 C.Nm.sB(z,this.gB(this))}else{y=this.gB(this)
@@ -10860,10 +11142,10 @@
 if(!(x<y))break
 y=this.Zv(0,x)
 if(x>=z.length)return H.e(z,x)
-z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 $isyN:true},
 nH:{
-"":"aL;l6,SH,AN",
+"^":"aL;l6,SH,AN",
 gMa:function(){var z,y
 z=J.q8(this.l6)
 y=this.AN
@@ -10883,8 +11165,8 @@
 return J.xH(x,y)},
 Zv:[function(a,b){var z=J.WB(this.gjX(),b)
 if(J.u6(b,0)||J.J5(z,this.gMa()))throw H.b(P.TE(b,0,this.gB(this)))
-return J.i4(this.l6,z)},"call$1","goY",2,0,null,47],
-eR:[function(a,b){return H.j5(this.l6,J.WB(this.SH,b),this.AN,null)},"call$1","gVQ",2,0,null,122],
+return J.i4(this.l6,z)},"call$1","goY",2,0,null,47,[]],
+eR:[function(a,b){return H.j5(this.l6,J.WB(this.SH,b),this.AN,null)},"call$1","gZo",2,0,null,122,[]],
 qZ:[function(a,b){var z,y,x
 if(J.u6(b,0))throw H.b(P.N(b))
 z=this.AN
@@ -10892,7 +11174,7 @@
 if(z==null)return H.j5(this.l6,y,J.WB(y,b),null)
 else{x=J.WB(y,b)
 if(J.u6(z,x))return this
-return H.j5(this.l6,y,x,null)}},"call$1","gcB",2,0,null,122],
+return H.j5(this.l6,y,x,null)}},"call$1","gVw",2,0,null,122,[]],
 Hd:function(a,b,c,d){var z,y,x
 z=this.SH
 y=J.Wx(z)
@@ -10904,7 +11186,7 @@
 z.Hd(a,b,c,d)
 return z}}},
 a7:{
-"":"a;l6,SW,G7,lo",
+"^":"a;l6,SW,G7,lo",
 gl:function(){return this.lo},
 G:[function(){var z,y,x,w
 z=this.l6
@@ -10916,9 +11198,9 @@
 if(w>=x){this.lo=null
 return!1}this.lo=y.Zv(z,w)
 this.G7=this.G7+1
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 i1:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 mb:function(a){return this.T6.call$1(a)},
 gA:function(a){var z=new H.MH(null,J.GP(this.l6),this.T6)
 z.$builtinTypeInfo=this.$builtinTypeInfo
@@ -10926,53 +11208,53 @@
 gB:function(a){return J.q8(this.l6)},
 gl0:function(a){return J.FN(this.l6)},
 grZ:function(a){return this.mb(J.MQ(this.l6))},
-Zv:[function(a,b){return this.mb(J.i4(this.l6,b))},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.mb(J.i4(this.l6,b))},"call$1","goY",2,0,null,47,[]],
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]},
 static:{K1:function(a,b,c,d){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isyN)return H.VM(new H.xy(a,b),[c,d])
 return H.VM(new H.i1(a,b),[c,d])}}},
 xy:{
-"":"i1;l6,T6",
+"^":"i1;l6,T6",
 $isyN:true},
 MH:{
-"":"Yl;lo,OI,T6",
+"^":"Yl;lo,OI,T6",
 mb:function(a){return this.T6.call$1(a)},
 G:[function(){var z=this.OI
 if(z.G()){this.lo=this.mb(z.gl())
 return!0}this.lo=null
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.lo},
 $asYl:function(a,b){return[b]}},
 A8:{
-"":"aL;CR,T6",
+"^":"aL;CR,T6",
 mb:function(a){return this.T6.call$1(a)},
 gB:function(a){return J.q8(this.CR)},
-Zv:[function(a,b){return this.mb(J.i4(this.CR,b))},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.mb(J.i4(this.CR,b))},"call$1","goY",2,0,null,47,[]],
 $asaL:function(a,b){return[b]},
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]},
 $isyN:true},
 U5:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 gA:function(a){var z=new H.SO(J.GP(this.l6),this.T6)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z}},
 SO:{
-"":"Yl;OI,T6",
+"^":"Yl;OI,T6",
 mb:function(a){return this.T6.call$1(a)},
 G:[function(){for(var z=this.OI;z.G();)if(this.mb(z.gl())===!0)return!0
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.OI.gl()}},
 kV:{
-"":"mW;l6,T6",
+"^":"mW;l6,T6",
 gA:function(a){var z=new H.rR(J.GP(this.l6),this.T6,C.Gw,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 $asmW:function(a,b){return[b]},
 $ascX:function(a,b){return[b]}},
 rR:{
-"":"a;OI,T6,TQ,lo",
+"^":"a;OI,T6,TQ,lo",
 mb:function(a){return this.T6.call$1(a)},
 gl:function(){return this.lo},
 G:[function(){var z,y
@@ -10982,23 +11264,23 @@
 if(y.G()){this.TQ=null
 z=J.GP(this.mb(y.gl()))
 this.TQ=z}else return!1}this.lo=this.TQ.gl()
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 H6:{
-"":"mW;l6,FT",
-eR:[function(a,b){return H.ke(this.l6,this.FT+b,H.Kp(this,0))},"call$1","gVQ",2,0,null,292],
+"^":"mW;l6,FT",
+eR:[function(a,b){return H.ke(this.l6,this.FT+b,H.Kp(this,0))},"call$1","gZo",2,0,null,287,[]],
 gA:function(a){var z=this.l6
 z=new H.U1(z.gA(z),this.FT)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 ap:function(a,b,c){},
 static:{ke:function(a,b,c){var z
-if(!!a.$isyN){z=H.VM(new H.d5(a,b),[c])
+if(!!a.$isyN){z=H.VM(new H.wB(a,b),[c])
 z.ap(a,b,c)
-return z}return H.bk(a,b,c)},bk:function(a,b,c){var z=H.VM(new H.H6(a,b),[c])
+return z}return H.mi(a,b,c)},mi:function(a,b,c){var z=H.VM(new H.H6(a,b),[c])
 z.ap(a,b,c)
 return z}}},
-d5:{
-"":"H6;l6,FT",
+wB:{
+"^":"H6;l6,FT",
 gB:function(a){var z,y
 z=this.l6
 y=J.xH(z.gB(z),this.FT)
@@ -11006,120 +11288,132 @@
 return 0},
 $isyN:true},
 U1:{
-"":"Yl;OI,FT",
+"^":"Yl;OI,FT",
 G:[function(){var z,y
 for(z=this.OI,y=0;y<this.FT;++y)z.G()
 this.FT=0
-return z.G()},"call$0","guK",0,0,null],
+return z.G()},"call$0","gqy",0,0,null],
 gl:function(){return this.OI.gl()}},
 SJ:{
-"":"a;",
-G:[function(){return!1},"call$0","guK",0,0,null],
+"^":"a;",
+G:[function(){return!1},"call$0","gqy",0,0,null],
 gl:function(){return}},
 SU7:{
-"":"a;",
+"^":"a;",
 sB:function(a,b){throw H.b(P.f("Cannot change the length of a fixed-length list"))},
-h:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","gDY",2,0,null,109],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gRI",2,0,null,124],
-V1:[function(a){throw H.b(P.f("Cannot clear a fixed-length list"))},"call$0","gyP",0,0,null]},
-JJ:{
-"":"a;",
-u:[function(a,b,c){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$2","gj3",4,0,null,47,23],
+h:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","ght",2,0,null,23,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$2","gQG",4,0,null,47,[],23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to a fixed-length list"))},"call$1","gDY",2,0,null,109,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gRI",2,0,null,124,[]],
+V1:[function(a){throw H.b(P.f("Cannot clear a fixed-length list"))},"call$0","gyP",0,0,null],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from a fixed-length list"))},"call$1","gNM",2,0,null,47,[]]},
+Qr:{
+"^":"a;",
+u:[function(a,b,c){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot change the length of an unmodifiable list"))},
-h:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","gDY",2,0,null,109],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gRI",2,0,null,124],
-So:[function(a,b){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$1","gH7",0,2,null,77,128],
+h:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","ght",2,0,null,23,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$2","gQG",4,0,null,47,[],23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to an unmodifiable list"))},"call$1","gDY",2,0,null,109,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gRI",2,0,null,124,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$1","gH7",0,2,null,77,128,[]],
 V1:[function(a){throw H.b(P.f("Cannot clear an unmodifiable list"))},"call$0","gyP",0,0,null],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$4","gam",6,2,null,336,115,116,109,117],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from an unmodifiable list"))},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot modify an unmodifiable list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
-Iy:{
-"":"ar+JJ;",
+w2Y:{
+"^":"ar+Qr;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 iK:{
-"":"aL;CR",
+"^":"aL;CR",
 gB:function(a){return J.q8(this.CR)},
 Zv:[function(a,b){var z,y
 z=this.CR
 y=J.U6(z)
-return y.Zv(z,J.xH(J.xH(y.gB(z),1),b))},"call$1","goY",2,0,null,47]},
+return y.Zv(z,J.xH(J.xH(y.gB(z),1),b))},"call$1","goY",2,0,null,47,[]]},
 GD:{
-"":"a;fN>",
+"^":"a;fN>",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isGD&&J.de(this.fN,b.fN)},"call$1","gUJ",2,0,null,104],
-giO:function(a){return 536870911&664597*J.v1(this.fN)},
+return typeof b==="object"&&b!==null&&!!z.$isGD&&J.de(this.fN,b.fN)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){var z=J.v1(this.fN)
+if(typeof z!=="number")return H.s(z)
+return 536870911&664597*z},
 bu:[function(a){return"Symbol(\""+H.d(this.fN)+"\")"},"call$0","gXo",0,0,null],
 $isGD:true,
 $iswv:true,
-static:{"":"zP",le:[function(a){var z=J.U6(a)
+static:{"^":"zP",le:[function(a){var z=J.U6(a)
 if(z.gl0(a)===!0)return a
 if(z.nC(a,"_"))throw H.b(new P.AT("\""+H.d(a)+"\" is a private identifier"))
 z=$.R0().Ej
 if(typeof a!=="string")H.vh(new P.AT(a))
 if(!z.test(a))throw H.b(new P.AT("\""+H.d(a)+"\" is not an identifier or an empty String"))
-return a},"call$1","kh",2,0,null,12]}}}],["dart._js_mirrors","dart:_js_mirrors",,H,{
-"":"",
+return a},"call$1","kh",2,0,null,12,[]]}}}],["dart._js_mirrors","dart:_js_mirrors",,H,{
+"^":"",
 YC:[function(a){if(a==null)return
-return new H.GD(a)},"call$1","Rc",2,0,null,12],
-X7:[function(a){return H.YC(H.d(a.fN)+"=")},"call$1","JP",2,0,null,129],
+return new H.GD(a)},"call$1","Rc",2,0,null,12,[]],
+X7:[function(a){return H.YC(H.d(a.fN)+"=")},"call$1","JP",2,0,null,129,[]],
 vn:[function(a){var z=J.x(a)
-if(typeof a==="object"&&a!==null&&!!z.$isTp)return new H.Sz(a)
-else return new H.iu(a)},"call$1","Yf",2,0,130,131],
-jO:[function(a){var z=$.Sl().t(0,a)
-if(J.de(a,"dynamic"))return $.Cr()
-return H.tT(H.YC(z==null?a:z),a)},"call$1","vC",2,0,null,132],
-tT:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+if(typeof a==="object"&&a!==null&&!!z.$isTp)return new H.Sz(a,4)
+else return new H.iu(a,4)},"call$1","Yf",2,0,130,131,[]],
+jO:[function(a){var z,y
+z=$.Sl().t(0,a)
+y=J.x(a)
+if(y.n(a,"dynamic"))return $.P8()
+if(y.n(a,"void"))return $.oj()
+return H.tT(H.YC(z==null?a:z),a)},"call$1","vC",2,0,null,132,[]],
+tT:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
+z=J.U6(b)
+y=z.u8(b,"/")
+if(y>-1)b=z.yn(b,y+1)
 z=$.tY
 if(z==null){z=H.Pq()
-$.tY=z}y=z[b]
-if(y!=null)return y
+$.tY=z}x=z[b]
+if(x!=null)return x
 z=J.U6(b)
-x=z.u8(b,"<")
-if(x!==-1){w=H.jO(z.Nj(b,0,x)).gJi()
-y=new H.bl(w,z.Nj(b,x+1,J.xH(z.gB(b),1)),null,null,null,null,null,null,null,null,null,null,null,null,null,w.gIf())
-$.tY[b]=y
-return y}v=H.pL(b)
-if(v==null){u=init.functionAliases[b]
-if(u!=null){y=new H.ng(b,null,a)
-y.CM=new H.Ar(init.metadata[u],null,null,null,y)
-$.tY[b]=y
-return y}throw H.b(P.f("Cannot find class for: "+H.d(a.fN)))}z=J.x(v)
-t=typeof v==="object"&&v!==null&&!!z.$isGv?v.constructor:v
-s=t["@"]
-if(s==null){r=null
-q=null}else{r=s[""]
-z=J.U6(r)
-if(typeof r==="object"&&r!==null&&(r.constructor===Array||!!z.$isList)){q=z.Mu(r,1,z.gB(r)).br(0)
-r=z.t(r,0)}else q=null
-if(typeof r!=="string")r=""}z=J.Gn(r,";")
+w=z.u8(b,"<")
+if(w!==-1){v=H.jO(z.Nj(b,0,w)).gJi()
+x=new H.bl(v,z.Nj(b,w+1,J.xH(z.gB(b),1)),null,null,null,null,null,null,null,null,null,null,null,null,null,v.gIf())
+$.tY[b]=x
+return x}u=H.pL(b)
+if(u==null){t=init.functionAliases[b]
+if(t!=null){x=new H.ng(b,null,a)
+x.CM=new H.Ar(init.metadata[t],null,null,null,x)
+$.tY[b]=x
+return x}throw H.b(P.f("Cannot find class for: "+H.d(a.fN)))}z=J.x(u)
+s=typeof u==="object"&&u!==null&&!!z.$isGv?u.constructor:u
+r=s["@"]
+if(r==null){q=null
+p=null}else{q=r["^"]
+z=J.U6(q)
+if(typeof q==="object"&&q!==null&&(q.constructor===Array||!!z.$isList)){p=z.Mu(q,1,z.gB(q)).br(0)
+q=z.t(q,0)}else p=null
+if(typeof q!=="string")q=""}z=J.uH(q,";")
 if(0>=z.length)return H.e(z,0)
-p=J.Gn(z[0],"+")
-if(p.length>1&&$.Sl().t(0,b)==null)y=H.MJ(p,b)
-else{o=new H.Wf(b,v,r,q,H.Pq(),null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,a)
-n=t.prototype["<>"]
-if(n==null||n.length===0)y=o
-else{for(z=n.length,m="dynamic",l=1;l<z;++l)m+=",dynamic"
-y=new H.bl(o,m,null,null,null,null,null,null,null,null,null,null,null,null,null,o.If)}}$.tY[b]=y
-return y},"call$2","ER",4,0,null,129,132],
+o=J.uH(z[0],"+")
+if(o.length>1&&$.Sl().t(0,b)==null)x=H.MJ(o,b)
+else{n=new H.Wf(b,u,q,p,H.Pq(),null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,a)
+m=s.prototype["<>"]
+if(m==null||m.length===0)x=n
+else{for(z=m.length,l="dynamic",k=1;k<z;++k)l+=",dynamic"
+x=new H.bl(n,l,null,null,null,null,null,null,null,null,null,null,null,null,null,n.If)}}$.tY[b]=x
+return x},"call$2","ER",4,0,null,129,[],132,[]],
 Vv:[function(a){var z,y,x
 z=P.L5(null,null,null,null,null)
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();){x=y.lo
-if(!x.gxV()&&!x.glT()&&!x.ghB())z.u(0,x.gIf(),x)}return z},"call$1","yM",2,0,null,133],
+if(!x.gxV()&&!x.glT()&&!x.ghB())z.u(0,x.gIf(),x)}return z},"call$1","yM",2,0,null,133,[]],
 Fk:[function(a){var z,y,x
 z=P.L5(null,null,null,null,null)
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();){x=y.lo
-if(x.gxV())z.u(0,x.gIf(),x)}return z},"call$1","Pj",2,0,null,133],
+if(x.gxV())z.u(0,x.gIf(),x)}return z},"call$1","Pj",2,0,null,133,[]],
 vE:[function(a,b){var z,y,x,w,v,u
 z=P.L5(null,null,null,null,null)
 z.FV(0,b)
@@ -11129,7 +11423,7 @@
 v=z.t(0,H.YC(v.Nj(w,0,J.xH(v.gB(w),1))))
 u=J.x(v)
 if(typeof v==="object"&&v!==null&&!!u.$isRY)continue}if(x.gxV())continue
-z.to(x.gIf(),new H.YX(x))}return z},"call$2","un",4,0,null,133,134],
+z.to(x.gIf(),new H.YX(x))}return z},"call$2","un",4,0,null,133,[],134,[]],
 MJ:[function(a,b){var z,y,x,w
 z=[]
 for(y=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);y.G();)z.push(H.jO(y.lo))
@@ -11137,21 +11431,21 @@
 x.G()
 w=x.lo
 for(;x.G();)w=new H.BI(w,x.lo,null,null,H.YC(b))
-return w},"call$2","R9",4,0,null,135,132],
+return w},"call$2","V8",4,0,null,135,[],132,[]],
 w2:[function(a,b){var z,y,x
 z=J.U6(a)
 y=0
 while(!0){x=z.gB(a)
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
-if(J.de(z.t(a,y).gIf(),H.YC(b)))return y;++y}throw H.b(new P.AT("Type variable not present in list."))},"call$2","QB",4,0,null,137,12],
+if(J.de(z.t(a,y).gIf(),H.YC(b)))return y;++y}throw H.b(new P.AT("Type variable not present in list."))},"call$2","QB",4,0,null,137,[],12,[]],
 Jf:[function(a,b){var z,y,x,w,v,u,t
 z={}
 z.a=null
 for(y=a;y!=null;){x=J.x(y)
 if(typeof y==="object"&&y!==null&&!!x.$isMs){z.a=y
 break}if(typeof y==="object"&&y!==null&&!!x.$isrN)break
-y=y.gXP()}if(b==null)return $.Cr()
+y=y.gXP()}if(b==null)return $.P8()
 else{x=z.a
 if(x==null)w=H.Ko(b,null)
 else if(x.gHA())if(typeof b==="number"){v=init.metadata[b]
@@ -11161,9 +11455,9 @@
 if(typeof b==="number"){t=z.call$1(b)
 x=J.x(t)
 if(typeof t==="object"&&t!==null&&!!x.$iscw)return t}w=H.Ko(b,new H.jB(z))}}if(w!=null)return H.jO(w)
-return P.re(C.yQ)},"call$2","xN",4,0,null,138,11],
+return P.re(C.yQ)},"call$2","xN",4,0,null,138,[],11,[]],
 fb:[function(a,b){if(a==null)return b
-return H.YC(H.d(a.gvd().fN)+"."+H.d(b.fN))},"call$2","WS",4,0,null,138,139],
+return H.YC(H.d(a.gUx().fN)+"."+H.d(b.fN))},"call$2","WS",4,0,null,138,[],139,[]],
 pj:[function(a){var z,y,x,w
 z=a["@"]
 if(z!=null)return z()
@@ -11173,7 +11467,7 @@
 return H.VM(new H.A8(y,new H.ye()),[null,null]).br(0)}x=Function.prototype.toString.call(a)
 w=C.xB.cn(x,new H.VR(H.v4("\"[0-9,]*\";?[ \n\r]*}",!1,!0,!1),null,null))
 if(w===-1)return C.xD;++w
-return H.VM(new H.A8(H.VM(new H.A8(C.xB.Nj(x,w,C.xB.XU(x,"\"",w)).split(","),P.ya()),[null,null]),new H.O1()),[null,null]).br(0)},"call$1","C7",2,0,null,140],
+return H.VM(new H.A8(H.VM(new H.A8(C.xB.Nj(x,w,C.xB.XU(x,"\"",w)).split(","),P.ya()),[null,null]),new H.O1()),[null,null]).br(0)},"call$1","C7",2,0,null,140,[]],
 jw:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r
 z=J.U6(b)
 if(typeof b==="object"&&b!==null&&(b.constructor===Array||!!z.$isList)){y=H.Mk(z.t(b,0),",")
@@ -11184,20 +11478,20 @@
 s=x[v]
 v=t}else s=null
 r=H.pS(u,s,a,c)
-if(r!=null)d.push(r)}},"call$4","Sv",8,0,null,138,141,61,51],
+if(r!=null)d.push(r)}},"call$4","Sv",8,0,null,138,[],141,[],61,[],51,[]],
 Mk:[function(a,b){var z=J.U6(a)
 if(z.gl0(a)===!0)return H.VM([],[J.O])
-return z.Fr(a,b)},"call$2","nK",4,0,null,26,98],
+return z.Fr(a,b)},"call$2","nK",4,0,null,26,[],98,[]],
 BF:[function(a){switch(a){case"==":case"[]":case"*":case"/":case"%":case"~/":case"+":case"<<":case">>":case">=":case">":case"<=":case"<":case"&":case"^":case"|":case"-":case"unary-":case"[]=":case"~":return!0
-default:return!1}},"call$1","IX",2,0,null,12],
+default:return!1}},"call$1","IX",2,0,null,12,[]],
 Y6:[function(a){var z,y
 z=J.x(a)
-if(z.n(a,"")||z.n(a,"$methodsWithOptionalArguments"))return!0
+if(z.n(a,"^")||z.n(a,"$methodsWithOptionalArguments"))return!0
 y=z.t(a,0)
 z=J.x(y)
-return z.n(y,"*")||z.n(y,"+")},"call$1","uG",2,0,null,42],
+return z.n(y,"*")||z.n(y,"+")},"call$1","uG",2,0,null,42,[]],
 Sn:{
-"":"a;L5,Aq>",
+"^":"a;L5,Aq>",
 gvU:function(){var z,y,x,w
 z=this.L5
 if(z!=null)return z
@@ -11206,7 +11500,7 @@
 y.u(0,w.gFP(),w)}z=H.VM(new H.Oh(y),[P.iD,P.D4])
 this.L5=z
 return z},
-static:{"":"QG,Q3,Ct",dF:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+static:{"^":"QG,Q3,Ct",dF:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z=P.L5(null,null,null,J.O,[J.Q,P.D4])
 y=init.libraries
 if(y==null)return z
@@ -11214,7 +11508,7 @@
 v=J.U6(w)
 u=v.t(w,0)
 t=v.t(w,1)
-s=P.r6($.cO().ej(t))
+s=P.r6($.qG().ej(t))
 r=v.t(w,2)
 q=v.t(w,3)
 p=v.t(w,4)
@@ -11224,48 +11518,52 @@
 l=p==null?C.xD:p()
 J.bi(z.to(u,new H.nI()),new H.Uz(s,r,q,l,o,n,m,null,null,null,null,null,null,null,null,null,null,H.YC(u)))}return z},"call$0","jc",0,0,null]}},
 nI:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return H.VM([],[P.D4])},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TY:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return this.gOO()},"call$0","gXo",0,0,null],
-Hy:[function(a,b){throw H.b(P.SY(null))},"call$2","gdk",4,0,null,41,165],
+IB:[function(a){throw H.b(P.SY(null))},"call$1","gft",2,0,null,41,[]],
+Hy:[function(a,b){throw H.b(P.SY(null))},"call$2","gdk",4,0,null,41,[],165,[]],
 $isej:true},
 Lj:{
-"":"TY;MA",
+"^":"TY;MA",
 gOO:function(){return"Isolate"},
 gcZ:function(){var z=$.Cm().gvU().nb
 return z.gUQ(z).XG(0,new H.mb())},
 $isej:true},
 mb:{
-"":"Tp:381;",
-call$1:[function(a){return a.gGD()},"call$1",null,2,0,null,380,"call"],
+"^":"Tp:374;",
+call$1:[function(a){return a.gGD()},"call$1",null,2,0,null,373,[],"call"],
 $isEH:true},
-mZ:{
-"":"TY;If<",
-gvd:function(){return H.fb(this.gXP(),this.gIf())},
+am:{
+"^":"TY;If<",
+gUx:function(){return H.fb(this.gXP(),this.gIf())},
 gq4:function(){return J.co(this.gIf().fN,"_")},
 bu:[function(a){return this.gOO()+" on '"+H.d(this.gIf().fN)+"'"},"call$0","gXo",0,0,null],
-jd:[function(a,b){throw H.b(H.Ef("Should not call _invoke"))},"call$2","gqi",4,0,null,43,44],
+jd:[function(a,b){throw H.b(H.Ef("Should not call _invoke"))},"call$2","gqi",4,0,null,43,[],44,[]],
 $isNL:true,
 $isej:true},
 cw:{
-"":"EE;XP<,xW,Nz,LQ,If",
+"^":"EE;XP<,xW,Nz,LQ,If",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iscw&&J.de(this.If,b.If)&&this.XP.n(0,b.XP)},"call$1","gUJ",2,0,null,104],
-giO:function(a){var z=this.XP
-return(1073741823&J.v1(C.Gp.LU)^17*J.v1(this.If)^19*z.giO(z))>>>0},
+return typeof b==="object"&&b!==null&&!!z.$iscw&&J.de(this.If,b.If)&&this.XP.n(0,b.XP)},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){var z,y
+z=J.v1(C.Gp.LU)
+if(typeof z!=="number")return H.s(z)
+y=this.XP
+return(1073741823&z^17*J.v1(this.If)^19*y.giO(y))>>>0},
 gOO:function(){return"TypeVariableMirror"},
 $iscw:true,
-$istg:true,
+$isac:true,
 $isX9:true,
 $isNL:true,
 $isej:true},
 EE:{
-"":"mZ;If",
+"^":"am;If",
 gOO:function(){return"TypeMirror"},
 gXP:function(){return},
 gc9:function(){return H.vh(P.SY(null))},
@@ -11278,9 +11576,9 @@
 $isNL:true,
 $isej:true},
 Uz:{
-"":"NZ;FP<,aP,wP,le,LB,GD<,ae<,SD,zE,P8,mX,T1,fX,M2,uA,Db,xO,If",
+"^":"uh;FP<,aP,wP,le,LB,GD<,ae<,SD,zE,P8,mX,T1,fX,M2,uA,Db,xO,If",
 gOO:function(){return"LibraryMirror"},
-gvd:function(){return this.If},
+gUx:function(){return this.If},
 gEO:function(){return this.gm8()},
 gqh:function(){var z,y,x,w
 z=this.P8
@@ -11302,13 +11600,16 @@
 if(w==null)w=this.gcc().nb.t(0,a)
 if(w==null)throw H.b(P.lr(this,H.X7(a),[b],null,null))
 w.Hy(this,b)
-return H.vn(b)},"call$2","gtd",4,0,null,65,165],
+return H.vn(b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z=this.gQH().nb.t(0,a)
+if(z==null)throw H.b(P.lr(this,a,[],null,null))
+return H.vn(z.IB(this))},"call$1","gPo",2,0,null,65,[]],
 F2:[function(a,b,c){var z,y
 z=this.gQH().nb.t(0,a)
 if(z==null)throw H.b(P.lr(this,a,b,c,null))
 y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isZk)if(!("$reflectable" in z.dl))H.Hz(a.gfN(a))
-return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+if(typeof z==="object"&&z!==null&&!!y.$isZk&&!("$reflectable" in z.dl))H.Hz(a.gfN(a))
+return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gm8:function(){var z,y,x,w,v,u,t,s,r,q,p
 z=this.SD
 if(z!=null)return z
@@ -11324,9 +11625,8 @@
 s=w[t]
 r=$.Sl().t(0,t)
 if(r==null)break c$0
-u=J.rY(r)
-q=u.nC(r,"new ")
-if(q){u=u.yn(r,4)
+q=J.rY(r).nC(r,"new ")
+if(q){u=C.xB.yn(r,4)
 r=H.ys(u,"$",".")}p=H.Sd(r,s,!q,q)
 y.push(p)
 p.nz=this}++v}this.SD=y
@@ -11392,78 +11692,117 @@
 this.xO=z
 return z},
 gXP:function(){return},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isD4:true,
 $isej:true,
 $isNL:true},
-NZ:{
-"":"mZ+M2;",
+uh:{
+"^":"am+M2;",
 $isej:true},
 IB:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 oP:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 YX:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return this.a},"call$0",null,0,0,null,"call"],
 $isEH:true},
 BI:{
-"":"vk;AY<,XW,BB,eL,If",
+"^":"Un;AY<,XW,BB,eL,If",
 gOO:function(){return"ClassMirror"},
 gIf:function(){var z,y
 z=this.BB
 if(z!=null)return z
-y=this.AY.gvd().fN
+y=this.AY.gUx().fN
 z=this.XW
-z=J.kE(y," with ")===!0?H.YC(H.d(y)+", "+H.d(z.gvd().fN)):H.YC(H.d(y)+" with "+H.d(z.gvd().fN))
+z=J.kE(y," with ")===!0?H.YC(H.d(y)+", "+H.d(z.gUx().fN)):H.YC(H.d(y)+" with "+H.d(z.gUx().fN))
 this.BB=z
 return z},
-gvd:function(){return this.gIf()},
+gUx:function(){return this.gIf()},
 gYK:function(){return this.XW.gYK()},
-F2:[function(a,b,c){throw H.b(P.lr(this,a,b,c,null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-PU:[function(a,b){throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,165],
+F2:[function(a,b,c){throw H.b(P.lr(this,a,b,c,null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+rN:[function(a){throw H.b(P.lr(this,a,null,null,null))},"call$1","gPo",2,0,null,65,[]],
+PU:[function(a,b){throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,[],165,[]],
 gkZ:function(){return[this.XW]},
 gHA:function(){return!0},
 gJi:function(){return this},
 gNy:function(){throw H.b(P.SY(null))},
 gw8:function(){return C.hU},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-vk:{
-"":"EE+M2;",
+Un:{
+"^":"EE+M2;",
 $isej:true},
 M2:{
-"":"a;",
+"^":"a;",
 $isej:true},
 iu:{
-"":"M2;Ax<",
+"^":"M2;Ax<,xq",
 gt5:function(a){return H.jO(J.bB(this.Ax).LU)},
 F2:[function(a,b,c){var z=J.GL(a)
-return this.tu(a,0,z+":"+b.length+":0",b)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-tu:[function(a,b,c,d){var z,y,x,w,v,u,t
+return this.tu(a,0,z+":"+b.length+":0",b)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+gK8:function(){var z,y,x
 z=$.eb
 y=this.Ax
+if(y==null)y=J.x(null)
 x=y.constructor[z]
 if(x==null){x=H.Pq()
-y.constructor[z]=x}w=x[c]
-if(w==null){v=$.I6().t(0,c)
-u=b===0?H.j5(J.Gn(c,":"),3,null,null).br(0):C.xD
-t=new H.LI(a,v,b,d,u,null)
-w=t.ZU(y)
-x[c]=w}else t=null
-if(w.gpf())return H.vn(w.Bj(y,t==null?new H.LI(a,$.I6().t(0,c),b,d,[],null):t))
-else return H.vn(w.Bj(y,d))},"call$4","gqi",8,0,null,12,11,383,82],
+y.constructor[z]=x}return x},
+tu:[function(a,b,c,d){var z,y,x,w,v
+z=this.gK8()
+y=z[c]
+if(y==null){x=$.I6().t(0,c)
+w=b===0?H.j5(J.uH(c,":"),3,null,null).br(0):C.xD
+v=new H.LI(a,x,b,d,w,null)
+y=v.ZU(this.Ax)
+z[c]=y}else v=null
+if(y.gpf()){if(v==null)v=new H.LI(a,$.I6().t(0,c),b,d,[],null)
+return H.vn(y.Bj(this.Ax,v))}else return H.vn(y.Bj(this.Ax,d))},"call$4","gqi",8,0,null,12,[],11,[],376,[],82,[]],
 PU:[function(a,b){var z=H.d(a.gfN(a))+"="
 this.tu(H.YC(z),2,z,[b])
-return H.vn(b)},"call$2","gtd",4,0,null,65,165],
-rN:[function(a){return this.tu(a,1,J.GL(a),[])},"call$1","gPo",2,0,null,65],
+return H.vn(b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z,y,x,w
+$loop$0:{z=this.xq
+if(typeof z=="number"||typeof a.$p=="undefined")break $loop$0
+y=a.$p(z)
+if(typeof y=="undefined")break $loop$0
+x=y(this.Ax)
+if(x===y.v)return y.m
+else{w=H.vn(x)
+y.v=x
+y.m=w
+return w}}return this.Dm(a)},"call$1","gPo",2,0,null,65,[]],
+Dm:[function(a){var z,y,x,w,v,u,t
+z=J.GL(a)
+y=this.tu(a,1,z,C.xD)
+x=this.gK8()[z]
+if(x.gpf())return y
+w=this.xq
+if(typeof w=="number"){w=J.xH(w,1)
+this.xq=w
+if(!J.de(w,0))return y
+w=({})
+this.xq=w}v=typeof dart_precompiled!="function"
+if(typeof a.$p=="undefined")a.$p=this.ds(z,v)
+u=x.gPi()
+t=x.geK()?this.QN(u,v):this.x0(u,v)
+w[z]=t
+t.v=t.m=w
+return y},"call$1","gFf",2,0,null,65,[]],
+ds:[function(a,b){if(b)return(function(b){return eval(b)})("(function probe$"+H.d(a)+"(c){return c."+H.d(a)+"})")
+else return(function(n){return(function(c){return c[n]})})(a)},"call$2","gfu",4,0,null,236,[],377,[]],
+x0:[function(a,b){if(!b)return(function(n){return(function(o){return o[n]()})})(a)
+return(function(b){return eval(b)})("(function "+this.Ax.constructor.name+"$"+H.d(a)+"(o){return o."+H.d(a)+"()})")},"call$2","gER",4,0,null,12,[],377,[]],
+QN:[function(a,b){var z=J.x(this.Ax)
+if(!b)return(function(n,i){return(function(o){return i[n](o)})})(a,z)
+return(function(b,i){return eval(b)})("(function "+z.constructor.name+"$"+H.d(a)+"(o){return i."+H.d(a)+"(o)})",z)},"call$2","gpa",4,0,null,12,[],377,[]],
 n:[function(a,b){var z,y
 if(b==null)return!1
 z=J.x(b)
@@ -11471,25 +11810,25 @@
 y=b.Ax
 y=z==null?y==null:z===y
 z=y}else z=!1
-return z},"call$1","gUJ",2,0,null,104],
-giO:function(a){return(H.CU(this.Ax)^909522486)>>>0},
+return z},"call$1","gUJ",2,0,null,104,[]],
+giO:function(a){return J.UN(H.CU(this.Ax),909522486)},
 bu:[function(a){return"InstanceMirror on "+H.d(P.hl(this.Ax))},"call$0","gXo",0,0,null],
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isiu:true,
 $isvr:true,
 $isej:true},
 mg:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){var z,y
 z=a.gfN(a)
 y=this.a
 if(y.x4(z))y.u(0,z,b)
-else throw H.b(H.WE("Invoking noSuchMethod with named arguments not implemented"))},"call$2",null,4,0,null,129,23,"call"],
+else throw H.b(H.WE("Invoking noSuchMethod with named arguments not implemented"))},"call$2",null,4,0,null,129,[],23,[],"call"],
 $isEH:true},
 bl:{
-"":"mZ;NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,QY,If",
+"^":"am;NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,RH,If",
 gOO:function(){return"ClassMirror"},
-gCr:function(){for(var z=this.gw8(),z=z.gA(z);z.G();)if(!J.de(z.lo,$.Cr()))return H.d(this.NK.gCr())+"<"+this.EZ+">"
+gCr:function(){for(var z=this.gw8(),z=z.gA(z);z.G();)if(!J.de(z.lo,$.P8()))return H.d(this.NK.gCr())+"<"+this.EZ+">"
 return this.NK.gCr()},
 gNy:function(){return this.NK.gNy()},
 gw8:function(){var z,y,x,w,v,u,t,s
@@ -11539,7 +11878,8 @@
 z=H.VM(new H.Oh(y),[P.wv,P.NL])
 this.Db=z
 return z},
-PU:[function(a,b){return this.NK.PU(a,b)},"call$2","gtd",4,0,null,65,165],
+PU:[function(a,b){return this.NK.PU(a,b)},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){return this.NK.rN(a)},"call$1","gPo",2,0,null,65,[]],
 gXP:function(){return this.NK.gXP()},
 gc9:function(){return this.NK.gc9()},
 gAY:function(){var z=this.qN
@@ -11547,7 +11887,7 @@
 z=H.Jf(this,init.metadata[J.UQ(init.typeInformation[this.NK.gCr()],0)])
 this.qN=z
 return z},
-F2:[function(a,b,c){return this.NK.F2(a,b,c)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+F2:[function(a,b,c){return this.NK.F2(a,b,c)},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gHA:function(){return!1},
 gJi:function(){return this.NK},
 gkZ:function(){var z=this.qm
@@ -11556,38 +11896,39 @@
 this.qm=z
 return z},
 gq4:function(){return J.co(this.NK.gIf().fN,"_")},
-gvd:function(){return this.NK.gvd()},
+gUx:function(){return this.NK.gUx()},
 gYj:function(){return new H.cu(this.gCr(),null)},
 gIf:function(){return this.NK.gIf()},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
+$isbl:true,
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
 tB:{
-"":"Tp:25;a",
+"^":"Tp:25;a",
 call$1:[function(a){var z,y,x
 z=H.BU(a,null,new H.Oo())
 y=this.a
 if(J.de(z,-1))y.push(H.jO(J.rr(a)))
 else{x=init.metadata[z]
-y.push(new H.cw(P.re(x.gXP()),x,z,null,H.YC(J.O6(x))))}},"call$1",null,2,0,null,385,"call"],
+y.push(new H.cw(P.re(x.gXP()),x,z,null,H.YC(J.O6(x))))}},"call$1",null,2,0,null,379,[],"call"],
 $isEH:true},
 Oo:{
-"":"Tp:229;",
-call$1:[function(a){return-1},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return-1},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Tc:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b.call$1(a)},"call$1",null,2,0,null,87,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b.call$1(a)},"call$1",null,2,0,null,87,[],"call"],
 $isEH:true},
 Ax:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){this.a.u(0,a.gIf(),a)
-return a},"call$1",null,2,0,null,386,"call"],
+return a},"call$1",null,2,0,null,380,[],"call"],
 $isEH:true},
 Wf:{
-"":"HZT;Cr<,Tx<,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,QY,nz,If",
+"^":"vk;Cr<,Tx<,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,RH,nz,If",
 gOO:function(){return"ClassMirror"},
 gaB:function(){var z,y
 z=this.Tx
@@ -11599,7 +11940,7 @@
 z=H.VM(new H.Oh(H.Fk(this.gEO())),[P.wv,P.RS])
 this.b0=z
 return z},
-ly:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
+ly:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=this.gaB().prototype
 y=H.kU(z)
 x=H.VM([],[H.Zk])
@@ -11607,20 +11948,22 @@
 if(H.Y6(v))continue
 u=$.bx().t(0,v)
 if(u==null)continue
-t=H.Sd(u,z[v],!1,!1)
-x.push(t)
-t.nz=a}y=H.kU(init.statics[this.Cr])
-for(w=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);w.G();){s=w.lo
-if(H.Y6(s))continue
-r=this.gXP().gae()[s]
-if("$reflectable" in r){q=r.$reflectionName
-if(q==null)continue
-p=J.rY(q).nC(q,"new ")
-if(p){o=C.xB.yn(q,4)
-q=H.ys(o,"$",".")}}else continue
-t=H.Sd(q,r,!p,p)
-x.push(t)
-t.nz=a}return x},"call$1","gN4",2,0,null,387],
+t=z[v]
+if(t.$reflectable==2)continue
+s=H.Sd(u,t,!1,!1)
+x.push(s)
+s.nz=a}y=H.kU(init.statics[this.Cr])
+for(w=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);w.G();){r=w.lo
+if(H.Y6(r))continue
+q=this.gXP().gae()[r]
+if("$reflectable" in q){p=q.$reflectionName
+if(p==null)continue
+o=J.rY(p).nC(p,"new ")
+if(o){n=C.xB.yn(p,4)
+p=H.ys(n,"$",".")}}else continue
+s=H.Sd(p,q,!o,o)
+x.push(s)
+s.nz=a}return x},"call$1","gN4",2,0,null,381,[]],
 gEO:function(){var z=this.qu
 if(z!=null)return z
 z=this.ly(this)
@@ -11635,8 +11978,8 @@
 if(y!=null){x=[x]
 C.Nm.FV(x,y)}H.jw(a,x,!1,z)
 w=init.statics[this.Cr]
-if(w!=null)H.jw(a,w[""],!0,z)
-return z},"call$1","gMp",2,0,null,388],
+if(w!=null)H.jw(a,w["^"],!0,z)
+return z},"call$1","gkW",2,0,null,382,[]],
 gTH:function(){var z=this.zE
 if(z!=null)return z
 z=this.ws(this)
@@ -11676,7 +12019,13 @@
 if(z!=null&&z.gFo()&&!z.gV5()){y=z.gao()
 if(!(y in $))throw H.b(H.Ef("Cannot find \""+y+"\" in current isolate."))
 $[y]=b
-return H.vn(b)}throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,165],
+return H.vn(b)}throw H.b(P.lr(this,H.X7(a),[b],null,null))},"call$2","gtd",4,0,null,65,[],165,[]],
+rN:[function(a){var z,y
+z=this.gcc().nb.t(0,a)
+if(z!=null&&z.gFo()){y=z.gao()
+if(!(y in $))throw H.b(H.Ef("Cannot find \""+y+"\" in current isolate."))
+if(y in init.lazies)return H.vn($[init.lazies[y]]())
+else return H.vn($[y])}throw H.b(P.lr(this,a,null,null,null))},"call$1","gPo",2,0,null,65,[]],
 gXP:function(){var z,y
 z=this.nz
 if(z==null){z=this.Tx
@@ -11713,13 +12062,13 @@
 F2:[function(a,b,c){var z=this.ghp().nb.t(0,a)
 if(z==null||!z.gFo())throw H.b(P.lr(this,a,b,c,null))
 if(!z.tB())H.Hz(a.gfN(a))
-return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
+return H.vn(z.jd(b,c))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
 gHA:function(){return!0},
 gJi:function(){return this},
 MR:[function(a){var z,y
 z=init.typeInformation[this.Cr]
 y=z!=null?H.VM(new H.A8(J.Pr(z,1),new H.t0(a)),[null,null]).br(0):C.Me
-return H.VM(new P.Yp(y),[P.Ms])},"call$1","gki",2,0,null,138],
+return H.VM(new P.Yp(y),[P.Ms])},"call$1","gki",2,0,null,138,[]],
 gkZ:function(){var z=this.qm
 if(z!=null)return z
 z=this.MR(this)
@@ -11739,30 +12088,30 @@
 gw8:function(){return C.hU},
 gYj:function(){if(!J.de(J.q8(this.gNy()),0))throw H.b(P.f("Declarations of generics have no reflected type"))
 return new H.cu(this.Cr,null)},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isWf:true,
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-HZT:{
-"":"EE+M2;",
+vk:{
+"^":"EE+M2;",
 $isej:true},
 Ei:{
-"":"Tp:382;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:375;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 U7:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){this.b.u(0,a.gIf(),a)
-return a},"call$1",null,2,0,null,386,"call"],
+return a},"call$1",null,2,0,null,380,[],"call"],
 $isEH:true},
 t0:{
-"":"Tp:389;a",
-call$1:[function(a){return H.Jf(this.a,init.metadata[a])},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:384;a",
+call$1:[function(a){return H.Jf(this.a,init.metadata[a])},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 Ld:{
-"":"mZ;ao<,V5<,Fo<,n6,nz,Ay>,le,If",
+"^":"am;ao<,V5<,Fo<,n6,nz,Ay>,le,If",
 gOO:function(){return"VariableMirror"},
 gt5:function(a){return H.Jf(this.nz,init.metadata[this.Ay])},
 gXP:function(){return this.nz},
@@ -11770,13 +12119,14 @@
 if(z==null){z=this.n6
 z=z==null?C.xD:z()
 this.le=z}return J.C0(z,H.Yf()).br(0)},
+IB:[function(a){return $[this.ao]},"call$1","gft",2,0,null,41,[]],
 Hy:[function(a,b){if(this.V5)throw H.b(P.lr(this,H.X7(this.If),[b],null,null))
-$[this.ao]=b},"call$2","gdk",4,0,null,41,165],
+$[this.ao]=b},"call$2","gdk",4,0,null,41,[],165,[]],
 $isRY:true,
 $isNL:true,
 $isej:true,
 static:{pS:function(a,b,c,d){var z,y,x,w,v,u,t,s,r,q,p,o
-z=J.Gn(a,"-")
+z=J.uH(a,"-")
 y=z.length
 if(y===1)return
 if(0>=y)return H.e(z,0)
@@ -11793,7 +12143,7 @@
 s=y.yn(x,r+1)}else q=s
 p=d?$.Sl().t(0,q):$.bx().t(0,"g"+q)
 if(p==null)p=q
-if(t){o=H.YC(H.d(p)+"=")
+if(t){o=H.YC(p+"=")
 y=c.gEO()
 v=new H.a7(y,y.length,0,null)
 v.$builtinTypeInfo=[H.Kp(y,0)]
@@ -11802,9 +12152,9 @@
 return new H.Ld(s,t,d,b,c,H.BU(z[1],null,null),null,H.YC(p))},GQ:[function(a){if(a>=60&&a<=64)return a-59
 if(a>=123&&a<=126)return a-117
 if(a>=37&&a<=43)return a-27
-return 0},"call$1","fS",2,0,null,136]}},
+return 0},"call$1","fS",2,0,null,136,[]]}},
 Sz:{
-"":"iu;Ax",
+"^":"iu;Ax,xq",
 gMj:function(a){var z,y,x,w,v,u,t,s
 z=$.te
 y=this.Ax
@@ -11821,18 +12171,18 @@
 v=H.BU(w[1],null,null)
 w=J.RE(y)
 if(typeof y==="object"&&y!==null&&!!w.$isv){u=y.gjm()
-y.gnw()
+H.eZ(y)
 t=$.bx().t(0,w.gRA(y))
 if(t==null)H.Hz(t)
 s=H.Sd(t,u,!1,!1)}else s=new H.Zk(y[x],v,!1,!1,!0,!1,!1,null,null,null,null,H.YC(x))
 y.constructor[z]=s
 return s},
 bu:[function(a){return"ClosureMirror on '"+H.d(P.hl(this.Ax))+"'"},"call$0","gXo",0,0,null],
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
 $isvr:true,
 $isej:true},
 Zk:{
-"":"mZ;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,G6,H3,If",
+"^":"am;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,wM,H3,If",
 gOO:function(){return"MethodMirror"},
 gMP:function(){var z=this.H3
 if(z!=null)return z
@@ -11841,8 +12191,8 @@
 tB:[function(){return"$reflectable" in this.dl},"call$0","gX1",0,0,null],
 gXP:function(){return this.nz},
 gdw:function(){this.gc9()
-return this.G6},
-gc9:function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
+return this.wM},
+gc9:function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 z=this.le
 if(z==null){z=this.dl
 y=H.pj(z)
@@ -11856,31 +12206,34 @@
 if(z!=null){x=J.x(z)
 x=typeof z==="object"&&z!==null&&!!x.$isD4
 z=x}else z=!1
-t=z?new H.Ar(v.hl(null),null,null,null,this.nz):new H.Ar(v.hl(this.nz.gJi().gTx()),null,null,null,this.nz)}if(this.xV)this.G6=this.nz
-else this.G6=t.gdw()
+t=z?new H.Ar(v.hl(null),null,null,null,this.nz):new H.Ar(v.hl(this.nz.gJi().gTx()),null,null,null,this.nz)}if(this.xV)this.wM=this.nz
+else this.wM=t.gdw()
 s=v.Mo
-for(z=t.gMP(),z=z.gA(z),x=w.length,r=v.hG,q=0;z.G();q=k){p=z.lo
-o=init.metadata[v.Rn[q+r+3]]
-n=J.RE(p)
-if(q<v.Rv)m=new H.fu(this,n.gAy(p),!1,!1,null,H.YC(o))
-else{l=v.BX(0,q)
-m=new H.fu(this,n.gAy(p),!0,s,l,H.YC(o))}k=q+1
-if(q>=x)return H.e(w,q)
-w[q]=m}}this.H3=H.VM(new P.Yp(w),[P.Ys])
+for(z=t.gMP(),z=z.gA(z),x=w.length,r=v.hG,q=v.Rn,p=0;z.G();p=i){o=z.lo
+n=init.metadata[q[2*p+r+3]]
+m=q[2*p+r+3+1]
+l=J.RE(o)
+if(p<v.Rv)k=new H.fu(this,l.gAy(o),!1,!1,null,m,H.YC(n))
+else{j=v.BX(0,p)
+k=new H.fu(this,l.gAy(o),!0,s,j,m,H.YC(n))}i=p+1
+if(p>=x)return H.e(w,p)
+w[p]=k}}this.H3=H.VM(new P.Yp(w),[P.Ys])
 z=H.VM(new P.Yp(J.C0(y,H.Yf())),[null])
 this.le=z}return z},
 jd:[function(a,b){if(!this.Fo&&!this.xV)throw H.b(H.Ef("Cannot invoke instance method without receiver."))
 if(!J.de(this.Yq,a.length)||this.dl==null)throw H.b(P.lr(this.gXP(),this.If,a,b,null))
-return this.dl.apply($,P.F(a,!0,null))},"call$2","gqi",4,0,null,43,44],
+return this.dl.apply($,P.F(a,!0,null))},"call$2","gqi",4,0,null,43,[],44,[]],
+IB:[function(a){if(this.lT)return this.jd([],null)
+else throw H.b(P.SY("getField on "+H.d(a)))},"call$1","gft",2,0,null,41,[]],
 Hy:[function(a,b){if(this.hB)return this.jd([b],null)
-else throw H.b(P.lr(this,H.X7(this.If),[],null,null))},"call$2","gdk",4,0,null,41,165],
+else throw H.b(P.lr(this,H.X7(this.If),[],null,null))},"call$2","gdk",4,0,null,41,[],165,[]],
 guU:function(){return!this.lT&&!this.hB&&!this.xV},
 $isZk:true,
 $isRS:true,
 $isNL:true,
 $isej:true,
 static:{Sd:function(a,b,c,d){var z,y,x,w,v,u,t
-z=J.Gn(a,":")
+z=a.split(":")
 if(0>=z.length)return H.e(z,0)
 a=z[0]
 y=H.BF(a)
@@ -11895,20 +12248,24 @@
 u=!1}w=H.YC(a)
 return new H.Zk(b,J.WB(v,t),u,x,c,d,y,null,null,null,null,w)}}},
 fu:{
-"":"mZ;XP<,Ay>,Q2<,Sh,BE,If",
+"^":"am;XP<,Ay>,Q2<,Sh,BE,QY,If",
 gOO:function(){return"ParameterMirror"},
 gt5:function(a){return H.Jf(this.XP,this.Ay)},
 gFo:function(){return!1},
 gV5:function(){return!1},
-gc9:function(){return H.vh(P.SY(null))},
+gc9:function(){return J.C0(this.QY,new H.wt()).br(0)},
 $isYs:true,
 $isRY:true,
 $isNL:true,
 $isej:true},
+wt:{
+"^":"Tp:385;",
+call$1:[function(a){return H.vn(init.metadata[a])},"call$1",null,2,0,null,383,[],"call"],
+$isEH:true},
 ng:{
-"":"mZ;Cr<,CM,If",
+"^":"am;Cr<,CM,If",
 gP:function(a){return this.CM},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 gOO:function(){return"TypedefMirror"},
 gJi:function(){return H.vh(P.SY(null))},
 gXP:function(){return H.vh(P.SY(null))},
@@ -11918,30 +12275,31 @@
 $isNL:true,
 $isej:true},
 TN:{
-"":"a;",
+"^":"a;",
 gYj:function(){return H.vh(P.SY(null))},
 gAY:function(){return H.vh(P.SY(null))},
 gkZ:function(){return H.vh(P.SY(null))},
 gYK:function(){return H.vh(P.SY(null))},
-t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12],
-F2:[function(a,b,c){return H.vh(P.SY(null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,43,44],
-PU:[function(a,b){return H.vh(P.SY(null))},"call$2","gtd",4,0,null,65,23],
+t:[function(a,b){return H.vh(P.SY(null))},"call$1","gIA",2,0,null,12,[]],
+F2:[function(a,b,c){return H.vh(P.SY(null))},function(a,b){return this.F2(a,b,null)},"CI","call$3",null,"gb2",4,2,null,77,24,[],43,[],44,[]],
+rN:[function(a){return H.vh(P.SY(null))},"call$1","gPo",2,0,null,65,[]],
+PU:[function(a,b){return H.vh(P.SY(null))},"call$2","gtd",4,0,null,65,[],23,[]],
 gNy:function(){return H.vh(P.SY(null))},
 gw8:function(){return H.vh(P.SY(null))},
 gJi:function(){return H.vh(P.SY(null))},
 gIf:function(){return H.vh(P.SY(null))},
-gvd:function(){return H.vh(P.SY(null))},
+gUx:function(){return H.vh(P.SY(null))},
 gq4:function(){return H.vh(P.SY(null))},
 gc9:function(){return H.vh(P.SY(null))}},
 Ar:{
-"":"TN;d9,o3,yA,zM,XP<",
+"^":"TN;d9,o3,yA,zM,XP<",
 gHA:function(){return!0},
 gdw:function(){var z=this.yA
 if(z!=null)return z
 z=this.d9
 if(!!z.void){z=$.oj()
 this.yA=z
-return z}if(!("ret" in z)){z=$.Cr()
+return z}if(!("ret" in z)){z=$.P8()
 this.yA=z
 return z}z=H.Jf(this.XP,z.ret)
 this.yA=z
@@ -11952,10 +12310,10 @@
 y=[]
 z=this.d9
 if("args" in z)for(x=z.args,x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]),w=0;x.G();w=v){v=w+1
-y.push(new H.fu(this,x.lo,!1,!1,null,H.YC("argument"+w)))}else w=0
+y.push(new H.fu(this,x.lo,!1,!1,null,C.iH,H.YC("argument"+w)))}else w=0
 if("opt" in z)for(x=z.opt,x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();w=v){v=w+1
-y.push(new H.fu(this,x.lo,!1,!1,null,H.YC("argument"+w)))}if("named" in z)for(x=H.kU(z.named),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){u=x.lo
-y.push(new H.fu(this,z.named[u],!1,!1,null,H.YC(u)))}z=H.VM(new P.Yp(y),[P.Ys])
+y.push(new H.fu(this,x.lo,!1,!1,null,C.iH,H.YC("argument"+w)))}if("named" in z)for(x=H.kU(z.named),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){u=x.lo
+y.push(new H.fu(this,z.named[u],!1,!1,null,C.iH,H.YC(u)))}z=H.VM(new P.Yp(y),[P.Ys])
 this.zM=z
 return z},
 bu:[function(a){var z,y,x,w,v,u
@@ -11982,50 +12340,53 @@
 $isX9:true,
 $isNL:true},
 rh:{
-"":"Tp:390;a",
+"^":"Tp:386;a",
 call$1:[function(a){var z,y,x
 z=init.metadata[a]
 y=this.a
 x=H.w2(y.a.gNy(),J.O6(z))
-return J.UQ(y.a.gw8(),x)},"call$1",null,2,0,null,47,"call"],
+return J.UQ(y.a.gw8(),x)},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 jB:{
-"":"Tp:391;b",
+"^":"Tp:387;b",
 call$1:[function(a){var z,y
 z=this.b.call$1(a)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$iscw)return H.d(z.Nz)
-return z.gCr()},"call$1",null,2,0,null,47,"call"],
+if((typeof z!=="object"||z===null||!y.$isWf)&&(typeof z!=="object"||z===null||!y.$isbl))if(y.n(z,$.P8()))return"dynamic"
+else if(y.n(z,$.oj()))return"void"
+else return"dynamic"
+return z.gCr()},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 ye:{
-"":"Tp:390;",
-call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:385;",
+call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 O1:{
-"":"Tp:390;",
-call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,341,"call"],
+"^":"Tp:385;",
+call$1:[function(a){return init.metadata[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 Oh:{
-"":"a;nb",
+"^":"a;nb",
 gB:function(a){return this.nb.X5},
 gl0:function(a){return this.nb.X5===0},
 gor:function(a){return this.nb.X5!==0},
-t:[function(a,b){return this.nb.t(0,b)},"call$1","gIA",2,0,null,42],
-x4:[function(a){return this.nb.x4(a)},"call$1","gV9",2,0,null,42],
-di:[function(a){return this.nb.di(a)},"call$1","gmc",2,0,null,23],
-aN:[function(a,b){return this.nb.aN(0,b)},"call$1","gjw",2,0,null,110],
+t:[function(a,b){return this.nb.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+x4:[function(a){return this.nb.x4(a)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return this.nb.di(a)},"call$1","gmc",2,0,null,23,[]],
+aN:[function(a,b){return this.nb.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){var z=this.nb
 return H.VM(new P.i5(z),[H.Kp(z,0)])},
 gUQ:function(a){var z=this.nb
 return z.gUQ(z)},
-u:[function(a,b,c){return H.kT()},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){return H.kT()},"call$1","gDY",2,0,null,104],
-Rz:[function(a,b){H.kT()},"call$1","gRI",2,0,null,42],
+u:[function(a,b,c){return H.kT()},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){return H.kT()},"call$1","gDY",2,0,null,104,[]],
+Rz:[function(a,b){H.kT()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return H.kT()},"call$0","gyP",0,0,null],
 $isZ0:true,
 static:{kT:[function(){throw H.b(P.f("Cannot modify an unmodifiable Map"))},"call$0","lY",0,0,null]}},
-"":"Sk<"}],["dart._js_names","dart:_js_names",,H,{
-"":"",
+"^":"Sk<"}],["dart._js_names","dart:_js_names",,H,{
+"^":"",
 hY:[function(a,b){var z,y,x,w,v,u,t
 z=H.kU(a)
 y=H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,J.O])
@@ -12033,10 +12394,10 @@
 u=a[v]
 y.u(0,v,u)
 if(w){t=J.rY(v)
-if(t.nC(v,"g"))y.u(0,"s"+t.yn(v,1),u+"=")}}return y},"call$2","BH",4,0,null,142,143],
+if(t.nC(v,"g"))y.u(0,"s"+t.yn(v,1),u+"=")}}return y},"call$2","BH",4,0,null,142,[],143,[]],
 YK:[function(a){var z=H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,J.O])
 a.aN(0,new H.Xh(z))
-return z},"call$1","OX",2,0,null,144],
+return z},"call$1","OX",2,0,null,144,[]],
 kU:[function(a){var z=H.VM((function(victim, hasOwnProperty) {
   var result = [];
   for (var key in victim) {
@@ -12045,34 +12406,37 @@
   return result;
 })(a, Object.prototype.hasOwnProperty),[null])
 z.fixed$length=init
-return z},"call$1","wp",2,0,null,140],
+return z},"call$1","wp",2,0,null,140,[]],
 Xh:{
-"":"Tp:392;a",
-call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,132,383,"call"],
+"^":"Tp:388;a",
+call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,132,[],376,[],"call"],
 $isEH:true}}],["dart.async","dart:async",,P,{
-"":"",
-K2:[function(a,b,c){var z=H.N7()
-z=H.KT(z,[z,z]).BD(a)
-if(z)return a.call$2(b,c)
-else return a.call$1(b)},"call$3","dB",6,0,null,145,146,147],
+"^":"",
 VH:[function(a,b){var z=H.N7()
 z=H.KT(z,[z,z]).BD(a)
 if(z)return b.O8(a)
-else return b.cR(a)},"call$2","p3",4,0,null,145,148],
-BG:[function(){var z,y,x,w
-for(;y=$.P8(),y.av!==y.HV;){z=y.Ux()
-try{z.call$0()}catch(x){H.Ru(x)
-w=C.jn.cU(C.RT.Fq,1000)
-H.cy(w<0?0:w,P.qZ())
-throw x}}$.TH=!1},"call$0","qZ",0,0,107],
-IA:[function(a){$.P8().NZ(0,a)
-if(!$.TH){P.jL(C.RT,P.qZ())
-$.TH=!0}},"call$1","xc",2,0,null,150],
+else return b.cR(a)},"call$2","p3",4,0,null,145,[],146,[]],
+Cx:[function(){var z=$.S6
+for(;z!=null;){z.Ki()
+z=z.gaw()
+$.S6=z}$.k8=null},"call$0","So",0,0,null],
+BG:[function(){var z
+try{P.Cx()}catch(z){H.Ru(z)
+P.jL(C.ny,P.qZ())
+$.S6=$.S6.gaw()
+throw z}},"call$0","qZ",0,0,107],
+IA:[function(a){var z,y
+z=$.k8
+if(z==null){z=new P.OM(a,null)
+$.k8=z
+$.S6=z
+P.jL(C.ny,P.qZ())}else{y=new P.OM(a,null)
+z.aw=y
+$.k8=y}},"call$1","xc",2,0,null,148,[]],
 rb:[function(a){var z
 if(J.de($.X3,C.NU)){$.X3.wr(a)
 return}z=$.X3
-z.wr(z.xi(a,!0))},"call$1","Rf",2,0,null,150],
-Ve:function(a,b,c,d,e,f){return e?H.VM(new P.ly(b,c,d,a,null,0,null),[f]):H.VM(new P.q1(b,c,d,a,null,0,null),[f])},
+z.wr(z.xi(a,!0))},"call$1","Rf",2,0,null,148,[]],
 bK:function(a,b,c,d){var z
 if(c){z=H.VM(new P.dz(b,a,0,null,null,null,null),[d])
 z.SJ=z
@@ -12088,90 +12452,85 @@
 return}catch(u){w=H.Ru(u)
 y=w
 x=new H.XO(u,null)
-$.X3.hk(y,x)}},"call$1","DC",2,0,null,151],
-YE:[function(a){},"call$1","bZ",2,0,152,23],
-SZ:[function(a,b){$.X3.hk(a,b)},function(a){return P.SZ(a,null)},null,"call$2","call$1","AY",2,2,153,77,146,147],
+$.X3.hk(y,x)}},"call$1","DC",2,0,null,149,[]],
+SN:[function(a){},"call$1","bV",2,0,150,23,[]],
+SZ:[function(a,b){$.X3.hk(a,b)},function(a){return P.SZ(a,null)},null,"call$2","call$1","AY",2,2,151,77,152,[],153,[]],
 dL:[function(){return},"call$0","v3",0,0,107],
 FE:[function(a,b,c){var z,y,x,w
 try{b.call$1(a.call$0())}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-c.call$2(z,y)}},"call$3","CV",6,0,null,154,155,156],
-NX:[function(a,b,c,d){var z,y
-z=a.ed()
-y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isb8)z.wM(new P.dR(b,c,d))
-else b.K5(c,d)},"call$4","QD",8,0,null,157,158,146,147],
-TB:[function(a,b){return new P.uR(a,b)},"call$2","cH",4,0,null,157,158],
-Bb:[function(a,b,c){var z,y
-z=a.ed()
-y=J.x(z)
-if(typeof z==="object"&&z!==null&&!!y.$isb8)z.wM(new P.QX(b,c))
-else b.rX(c)},"call$3","iB",6,0,null,157,158,23],
+c.call$2(z,y)}},"call$3","CV",6,0,null,154,[],155,[],156,[]],
+NX:[function(a,b,c,d){a.ed()
+b.K5(c,d)},"call$4","QD",8,0,null,157,[],158,[],152,[],153,[]],
+TB:[function(a,b){return new P.uR(a,b)},"call$2","cH",4,0,null,157,[],158,[]],
+Bb:[function(a,b,c){a.ed()
+b.rX(c)},"call$3","iB",6,0,null,157,[],158,[],23,[]],
 rT:function(a,b){var z
 if(J.de($.X3,C.NU))return $.X3.uN(a,b)
 z=$.X3
 return z.uN(a,z.xi(b,!0))},
 jL:[function(a,b){var z=C.jn.cU(a.Fq,1000)
-return H.cy(z<0?0:z,b)},"call$2","et",4,0,null,159,150],
-L2:[function(a,b,c,d,e){a.Gr(new P.pK(d,e))},"call$5","xP",10,0,160,161,162,148,146,147],
+return H.cy(z<0?0:z,b)},"call$2","et",4,0,null,159,[],148,[]],
+PJ:[function(a){var z=$.X3
+$.X3=a
+return z},"call$1","kb",2,0,null,146,[]],
+L2:[function(a,b,c,d,e){a.Gr(new P.pK(d,e))},"call$5","xP",10,0,160,161,[],162,[],146,[],152,[],153,[]],
 T8:[function(a,b,c,d){var z,y
 if(J.de($.X3,c))return d.call$0()
-z=$.X3
-try{$.X3=c
-y=d.call$0()
-return y}finally{$.X3=z}},"call$4","AI",8,0,163,161,162,148,110],
+z=P.PJ(c)
+try{y=d.call$0()
+return y}finally{$.X3=z}},"call$4","AI",8,0,163,161,[],162,[],146,[],110,[]],
 V7:[function(a,b,c,d,e){var z,y
 if(J.de($.X3,c))return d.call$1(e)
-z=$.X3
-try{$.X3=c
-y=d.call$1(e)
-return y}finally{$.X3=z}},"call$5","MM",10,0,164,161,162,148,110,165],
+z=P.PJ(c)
+try{y=d.call$1(e)
+return y}finally{$.X3=z}},"call$5","MM",10,0,164,161,[],162,[],146,[],110,[],165,[]],
 Qx:[function(a,b,c,d,e,f){var z,y
 if(J.de($.X3,c))return d.call$2(e,f)
-z=$.X3
-try{$.X3=c
-y=d.call$2(e,f)
-return y}finally{$.X3=z}},"call$6","l4",12,0,166,161,162,148,110,54,55],
-Ee:[function(a,b,c,d){return d},"call$4","EU",8,0,167,161,162,148,110],
-cQ:[function(a,b,c,d){return d},"call$4","zi",8,0,168,161,162,148,110],
-VI:[function(a,b,c,d){return d},"call$4","uu",8,0,169,161,162,148,110],
-Tk:[function(a,b,c,d){P.IA(C.NU!==c?c.ce(d):d)},"call$4","G2",8,0,170,161,162,148,110],
-h8:[function(a,b,c,d,e){return P.jL(d,C.NU!==c?c.ce(e):e)},"call$5","KF",10,0,171,161,162,148,159,150],
-XB:[function(a,b,c,d){H.qw(d)},"call$4","YM",8,0,172,161,162,148,173],
-CI:[function(a){J.O2($.X3,a)},"call$1","jt",2,0,174,173],
+z=P.PJ(c)
+try{y=d.call$2(e,f)
+return y}finally{$.X3=z}},"call$6","l4",12,0,166,161,[],162,[],146,[],110,[],54,[],55,[]],
+Ee:[function(a,b,c,d){return d},"call$4","EU",8,0,167,161,[],162,[],146,[],110,[]],
+cQ:[function(a,b,c,d){return d},"call$4","zi",8,0,168,161,[],162,[],146,[],110,[]],
+VI:[function(a,b,c,d){return d},"call$4","uu",8,0,169,161,[],162,[],146,[],110,[]],
+Tk:[function(a,b,c,d){P.IA(C.NU!==c?c.ce(d):d)},"call$4","G2",8,0,170,161,[],162,[],146,[],110,[]],
+h8:[function(a,b,c,d,e){return P.jL(d,C.NU!==c?c.ce(e):e)},"call$5","KF",10,0,171,161,[],162,[],146,[],159,[],148,[]],
+XB:[function(a,b,c,d){H.qw(d)},"call$4","YM",8,0,172,161,[],162,[],146,[],173,[]],
+CI:[function(a){J.O2($.X3,a)},"call$1","Fl",2,0,174,173,[]],
 UA:[function(a,b,c,d,e){var z
-$.oK=P.jt()
+$.oK=P.Fl()
 z=P.Py(null,null,null,null,null)
-return new P.cc(c,d,z)},"call$5","hn",10,0,175,161,162,148,176,177],
+return new P.uo(c,d,z)},"call$5","hn",10,0,175,161,[],162,[],146,[],176,[],177,[]],
 Ca:{
-"":"a;kc>,I4<",
+"^":"a;kc>,I4<",
 $isGe:true},
 Ik:{
-"":"O9;Y8"},
+"^":"O9;Y8"},
 JI:{
-"":"yU;Ae@,iE@,SJ@,Y8,dB,o7,Bd,Lj,Gv,lz,Ri",
+"^":"oh;Ae@,iE@,SJ@,Y8,dB,o7,Bd,Lj,Gv,lz,Ri",
 gY8:function(){return this.Y8},
 uR:[function(a){var z=this.Ae
 if(typeof z!=="number")return z.i()
-return(z&1)===a},"call$1","gLM",2,0,null,393],
+return(z&1)===a},"call$1","gLM",2,0,null,389,[]],
 Ac:[function(){var z=this.Ae
 if(typeof z!=="number")return z.w()
-this.Ae=z^1},"call$0","gUe",0,0,null],
+this.Ae=z^1},"call$0","goX",0,0,null],
 gP4:function(){var z=this.Ae
 if(typeof z!=="number")return z.i()
 return(z&2)!==0},
 dK:[function(){var z=this.Ae
 if(typeof z!=="number")return z.k()
-this.Ae=z|4},"call$0","gyL",0,0,null],
+this.Ae=z|4},"call$0","gno",0,0,null],
 gHj:function(){var z=this.Ae
 if(typeof z!=="number")return z.i()
 return(z&4)!==0},
 uO:[function(){return},"call$0","gp4",0,0,107],
 LP:[function(){return},"call$0","gZ9",0,0,107],
-static:{"":"kb,RG,cP"}},
+static:{"^":"FJ,RG,cP"}},
 Ks:{
-"":"a;nL<,QC<,iE@,SJ@",
+"^":"a;iE@,SJ@",
+gRW:function(){return!1},
 gP4:function(){return(this.Gv&2)!==0},
 SL:[function(){var z=this.Ip
 if(z!=null)return z
@@ -12184,35 +12543,17 @@
 z.siE(y)
 y.sSJ(z)
 a.sSJ(a)
-a.siE(a)},"call$1","gOo",2,0,null,157],
-ET:[function(a){var z,y,x
-if((this.Gv&4)!==0)throw H.b(new P.lj("Subscribing to closed stream"))
-z=$.X3
-y=a?1:0
-x=new P.JI(null,null,null,this,null,null,null,z,y,null,null)
-x.$builtinTypeInfo=this.$builtinTypeInfo
-x.SJ=x
-x.iE=x
-y=this.SJ
-x.SJ=y
-x.iE=this
-y.siE(x)
-this.SJ=x
-x.Ae=this.Gv&1
-if(this.iE===x)P.ot(this.nL)
-return x},"call$1","gwk",2,0,null,346],
+a.siE(a)},"call$1","gOo",2,0,null,157,[]],
 j0:[function(a){if(a.giE()===a)return
 if(a.gP4())a.dK()
 else{this.p1(a)
-if((this.Gv&2)===0&&this.iE===this)this.Of()}},"call$1","gOr",2,0,null,157],
-mO:[function(a){},"call$1","gnx",2,0,null,157],
-m4:[function(a){},"call$1","gyb",2,0,null,157],
+if((this.Gv&2)===0&&this.iE===this)this.Of()}},"call$1","gOr",2,0,null,157,[]],
 q7:[function(){if((this.Gv&4)!==0)return new P.lj("Cannot add new events after calling close")
 return new P.lj("Cannot add new events while doing an addStream")},"call$0","gVo",0,0,null],
 h:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
-this.Iv(b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU",void:true,args:[a]}},this.$receiver,"Ks")},237],
-zw:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
-this.pb(a,b)},function(a){return this.zw(a,null)},"JT","call$2","call$1","gXB",2,2,394,77,146,147],
+this.Iv(b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU",void:true,args:[a]}},this.$receiver,"Ks")},231,[]],
+fDe:[function(a,b){if(this.Gv>=4)throw H.b(this.q7())
+this.pb(a,b)},function(a){return this.fDe(a,null)},"JT","call$2","call$1","gXB",2,2,390,77,152,[],153,[]],
 cO:[function(a){var z,y
 z=this.Gv
 if((z&4)!==0)return this.Ip
@@ -12221,8 +12562,8 @@
 y=this.SL()
 this.SY()
 return y},"call$0","gJK",0,0,null],
-Rg:[function(a,b){this.Iv(b)},"call$1","gHR",2,0,null,237],
-V8:[function(a,b){this.pb(a,b)},"call$2","grd",4,0,null,146,147],
+Rg:[function(a,b){this.Iv(b)},"call$1","gHR",2,0,null,231,[]],
+V8:[function(a,b){this.pb(a,b)},"call$2","grd",4,0,null,152,[],153,[]],
 Qj:[function(){var z=this.WX
 this.WX=null
 this.Gv=this.Gv&4294967287
@@ -12246,101 +12587,93 @@
 y.sAe(z&4294967293)
 y=w}else y=y.giE()
 this.Gv=this.Gv&4294967293
-if(this.iE===this)this.Of()},"call$1","gxd",2,0,null,378],
+if(this.iE===this)this.Of()},"call$1","gxd",2,0,null,371,[]],
 Of:[function(){if((this.Gv&4)!==0&&this.Ip.Gv===0)this.Ip.OH(null)
 P.ot(this.QC)},"call$0","gVg",0,0,null]},
 dz:{
-"":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
+"^":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
 Iv:[function(a){var z=this.iE
 if(z===this)return
 if(z.giE()===this){this.Gv=this.Gv|2
 this.iE.Rg(0,a)
 this.Gv=this.Gv&4294967293
 if(this.iE===this)this.Of()
-return}this.nE(new P.tK(this,a))},"call$1","gm9",2,0,null,237],
+return}this.nE(new P.tK(this,a))},"call$1","gm9",2,0,null,231,[]],
 pb:[function(a,b){if(this.iE===this)return
-this.nE(new P.OR(this,a,b))},"call$2","gTb",4,0,null,146,147],
+this.nE(new P.OR(this,a,b))},"call$2","gTb",4,0,null,152,[],153,[]],
 SY:[function(){if(this.iE!==this)this.nE(new P.Bg(this))
 else this.Ip.OH(null)},"call$0","gXm",0,0,null]},
 tK:{
-"":"Tp;a,b",
-call$1:[function(a){a.Rg(0,this.b)},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){a.Rg(0,this.b)},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"DU",args:[[P.KA,a]]}},this.a,"dz")}},
 OR:{
-"":"Tp;a,b,c",
-call$1:[function(a){a.V8(this.b,this.c)},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a,b,c",
+call$1:[function(a){a.V8(this.b,this.c)},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"DU",args:[[P.KA,a]]}},this.a,"dz")}},
 Bg:{
-"":"Tp;a",
-call$1:[function(a){a.Qj()},"call$1",null,2,0,null,157,"call"],
+"^":"Tp;a",
+call$1:[function(a){a.Qj()},"call$1",null,2,0,null,157,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Zj",args:[[P.JI,a]]}},this.a,"dz")}},
 DL:{
-"":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
+"^":"Ks;nL,QC,Gv,iE,SJ,WX,Ip",
 Iv:[function(a){var z,y
 for(z=this.iE;z!==this;z=z.giE()){y=new P.LV(a,null)
 y.$builtinTypeInfo=[null]
-z.w6(y)}},"call$1","gm9",2,0,null,237],
+z.w6(y)}},"call$1","gm9",2,0,null,231,[]],
 pb:[function(a,b){var z
-for(z=this.iE;z!==this;z=z.giE())z.w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,146,147],
+for(z=this.iE;z!==this;z=z.giE())z.w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,152,[],153,[]],
 SY:[function(){var z=this.iE
 if(z!==this)for(;z!==this;z=z.giE())z.w6(C.Wj)
 else this.Ip.OH(null)},"call$0","gXm",0,0,null]},
 b8:{
-"":"a;",
+"^":"a;",
 $isb8:true},
 Ia:{
-"":"a;"},
+"^":"a;"},
 Zf:{
-"":"Ia;MM",
+"^":"Ia;MM",
 oo:[function(a,b){var z=this.MM
 if(z.Gv!==0)throw H.b(P.w("Future already completed"))
-z.OH(b)},function(a){return this.oo(a,null)},"tZ","call$1","call$0","gv6",0,2,395,77,23],
+z.OH(b)},function(a){return this.oo(a,null)},"tZ","call$1","call$0","gv6",0,2,391,77,23,[]],
 w0:[function(a,b){var z
 if(a==null)throw H.b(new P.AT("Error must not be null"))
 z=this.MM
 if(z.Gv!==0)throw H.b(new P.lj("Future already completed"))
-z.CG(a,b)},function(a){return this.w0(a,null)},"pm","call$2","call$1","gYJ",2,2,394,77,146,147]},
+z.CG(a,b)},function(a){return this.w0(a,null)},"pm","call$2","call$1","gYJ",2,2,390,77,152,[],153,[]]},
 vs:{
-"":"a;Gv,Lj<,jk,BQ@,OY,As,qV,o4",
+"^":"a;Gv,Lj<,jk,BQ@,OY,As,qV,o4",
 gcg:function(){return this.Gv>=4},
 gNm:function(){return this.Gv===8},
 swG:function(a){if(a)this.Gv=2
 else this.Gv=0},
 gO1:function(){return this.Gv===2?null:this.OY},
-GP:function(a){return this.gO1().call$1(a)},
 gyK:function(){return this.Gv===2?null:this.As},
 go7:function(){return this.Gv===2?null:this.qV},
 gIa:function(){return this.Gv===2?null:this.o4},
-xY:function(){return this.gIa().call$0()},
 Rx:[function(a,b){var z,y
 z=$.X3
 y=H.VM(new P.vs(0,z,null,null,z.cR(a),null,P.VH(b,$.X3),null),[null])
 this.au(y)
-return y},function(a){return this.Rx(a,null)},"ml","call$2$onError",null,"grf",2,3,null,77,110,156],
+return y},function(a){return this.Rx(a,null)},"ml","call$2$onError",null,"grf",2,3,null,77,110,[],156,[]],
 yd:[function(a,b){var z,y,x
 z=$.X3
 y=P.VH(a,z)
 x=H.VM(new P.vs(0,z,null,null,null,$.X3.cR(b),y,null),[null])
 this.au(x)
-return x},function(a){return this.yd(a,null)},"OA","call$2$test",null,"gue",2,3,null,77,156,379],
-wM:[function(a){var z,y
-z=$.X3
-y=new P.vs(0,z,null,null,null,null,null,z.Al(a))
-y.$builtinTypeInfo=this.$builtinTypeInfo
-this.au(y)
-return y},"call$1","gE1",2,0,null,378],
+return x},function(a){return this.yd(a,null)},"OA","call$2$test",null,"gue",2,3,null,77,156,[],372,[]],
 gDL:function(){return this.jk},
 gcG:function(){return this.jk},
 Am:[function(a){this.Gv=4
-this.jk=a},"call$1","gAu",2,0,null,23],
+this.jk=a},"call$1","gAu",2,0,null,23,[]],
 E6:[function(a,b){this.Gv=8
-this.jk=new P.Ca(a,b)},"call$2","gM6",4,0,null,146,147],
+this.jk=new P.Ca(a,b)},"call$2","gM6",4,0,null,152,[],153,[]],
 au:[function(a){if(this.Gv>=4)this.Lj.wr(new P.da(this,a))
 else{a.sBQ(this.jk)
-this.jk=a}},"call$1","gXA",2,0,null,298],
+this.jk=a}},"call$1","gXA",2,0,null,292,[]],
 L3:[function(){var z,y,x
 z=this.jk
 this.jk=null
@@ -12351,10 +12684,10 @@
 if(typeof a==="object"&&a!==null&&!!z.$isb8){P.GZ(a,this)
 return}y=this.L3()
 this.Am(a)
-P.HZ(this,y)},"call$1","gJJ",2,0,null,23],
+P.HZ(this,y)},"call$1","gJJ",2,0,null,23,[]],
 K5:[function(a,b){var z=this.L3()
 this.E6(a,b)
-P.HZ(this,z)},function(a){return this.K5(a,null)},"Lp","call$2","call$1","gbY",2,2,153,77,146,147],
+P.HZ(this,z)},function(a){return this.K5(a,null)},"Lp","call$2","call$1","gbY",2,2,151,77,152,[],153,[]],
 OH:[function(a){var z,y
 z=J.x(a)
 y=typeof a==="object"&&a!==null&&!!z.$isb8
@@ -12363,24 +12696,24 @@
 if(z){this.rX(a)
 return}if(this.Gv!==0)H.vh(P.w("Future already completed"))
 this.Gv=1
-this.Lj.wr(new P.rH(this,a))},"call$1","gZV",2,0,null,23],
+this.Lj.wr(new P.rH(this,a))},"call$1","gZV",2,0,null,23,[]],
 CG:[function(a,b){if(this.Gv!==0)H.vh(new P.lj("Future already completed"))
 this.Gv=1
-this.Lj.wr(new P.ZL(this,a,b))},"call$2","glC",4,0,null,146,147],
+this.Lj.wr(new P.ZL(this,a,b))},"call$2","glC",4,0,null,152,[],153,[]],
 L7:function(a,b){this.OH(a)},
 $isvs:true,
 $isb8:true,
-static:{"":"ewM,JE,C3n,Cd,dh",Dt:function(a){return H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[a])},GZ:[function(a,b){var z
+static:{"^":"ewM,JE,C3n,oN1,NK",Dt:function(a){return H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[a])},GZ:[function(a,b){var z
 b.swG(!0)
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isvs)if(a.Gv>=4)P.HZ(a,b)
 else a.au(b)
-else a.Rx(new P.xw(b),new P.dm(b))},"call$2","mX",4,0,null,27,74],yE:[function(a,b){var z
+else a.Rx(new P.xw(b),new P.dm(b))},"call$2","mX",4,0,null,27,[],74,[]],yE:[function(a,b){var z
 do{z=b.gBQ()
 b.sBQ(null)
 P.HZ(a,b)
 if(z!=null){b=z
-continue}else break}while(!0)},"call$2","cN",4,0,null,27,149],HZ:[function(a,b){var z,y,x,w,v,u,t,s,r
+continue}else break}while(!0)},"call$2","cN",4,0,null,27,[],147,[]],HZ:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 z.e=a
 for(y=a;!0;){x={}
@@ -12390,133 +12723,167 @@
 z.e.gLj().hk(J.w8(v),v.gI4())
 return}if(b==null)return
 if(b.gBQ()!=null){P.yE(z.e,b)
-return}if(w&&!z.e.gLj().fC(b.gLj())){v=z.e.gcG()
+return}u=b.gLj()
+if(w&&!z.e.gLj().fC(u)){v=z.e.gcG()
 z.e.gLj().hk(J.w8(v),v.gI4())
-return}y=$.X3
-u=b.gLj()
-if(y==null?u!=null:y!==u){b.gLj().Gr(new P.mi(z,b))
-return}x.b=null
+return}t=$.X3
+if(t==null?u!=null:t!==u)$.X3=u
+else t=null
+x.b=null
 x.c=null
 x.d=!1
-b.gLj().Gr(new P.jb(z,x,w,b))
+if(!w)if(b.gO1()!=null)x.b=new P.rq(x,z,b,u).call$0()
+else{x.c=z.e.gDL()
+x.b=!0}else new P.RW(z,x,b,u).call$0()
+if(b.gIa()!=null)new P.RT(z,x,w,b,u).call$0()
+if(t!=null)$.X3=t
 if(x.d)return
 y=x.b===!0
-if(y){u=x.c
-t=J.x(u)
-t=typeof u==="object"&&u!==null&&!!t.$isb8
-u=t}else u=!1
-if(u){s=x.c
-y=J.x(s)
-if(typeof s==="object"&&s!==null&&!!y.$isvs&&s.Gv>=4){b.swG(!0)
-z.e=s
-y=s
-continue}P.GZ(s,b)
-return}if(y){r=b.L3()
-b.Am(x.c)}else{r=b.L3()
+if(y){s=x.c
+r=J.x(s)
+r=typeof s==="object"&&s!==null&&!!r.$isb8
+s=r}else s=!1
+if(s){q=x.c
+y=J.x(q)
+if(typeof q==="object"&&q!==null&&!!y.$isvs&&q.Gv>=4){b.swG(!0)
+z.e=q
+y=q
+continue}P.GZ(q,b)
+return}if(y){p=b.L3()
+b.Am(x.c)}else{p=b.L3()
 v=x.c
 b.E6(J.w8(v),v.gI4())}z.e=b
 y=b
-b=r}},"call$2","WY",4,0,null,27,149]}},
+b=p}},"call$2","WY",4,0,null,27,[],147,[]]}},
 da:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){P.HZ(this.a,this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 xw:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.rX(a)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.rX(a)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 dm:{
-"":"Tp:396;b",
-call$2:[function(a,b){this.b.K5(a,b)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,146,147,"call"],
+"^":"Tp:392;b",
+call$2:[function(a,b){this.b.K5(a,b)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,152,[],153,[],"call"],
 $isEH:true},
 rH:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){this.a.rX(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ZL:{
-"":"Tp:108;a,b,c",
+"^":"Tp:108;a,b,c",
 call$0:[function(){this.a.K5(this.b,this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-mi:{
-"":"Tp:108;c,d",
-call$0:[function(){P.HZ(this.c.e,this.d)},"call$0",null,0,0,null,"call"],
+rq:{
+"^":"Tp:366;b,c,d,e",
+call$0:[function(){var z,y,x,w
+try{this.b.c=this.e.FI(this.d.gO1(),this.c.e.gDL())
+return!0}catch(x){w=H.Ru(x)
+z=w
+y=new H.XO(x,null)
+this.b.c=new P.Ca(z,y)
+return!1}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-jb:{
-"":"Tp:108;c,b,e,f",
+RW:{
+"^":"Tp:107;c,b,f,UI",
 call$0:[function(){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
-z={}
-try{r=this.c
-if(!this.e){y=r.e.gDL()
-q=this.f
-p=this.b
-if(q.gO1()!=null){p.c=q.GP(y)
-p.b=!0}else{p.c=y
-p.b=!0}}else{x=r.e.gcG()
-q=this.f
-w=q.gyK()
-v=!0
-if(w!=null)v=w.call$1(J.w8(x))
-p=v===!0&&q.go7()!=null
-o=this.b
-if(p){u=q.go7()
-o.c=P.K2(u,J.w8(x),x.gI4())
-o.b=!0}else{o.c=x
-o.b=!1}p=o}if(q.gIa()!=null){n=q.xY()
-z.a=n
-o=J.x(n)
-if(typeof n==="object"&&n!==null&&!!o.$isb8){q.swG(!0)
-z.a.Rx(new P.wB(r,q),new P.Pu(z,q))
-p.d=!0}}}catch(m){z=H.Ru(m)
-t=z
-s=new H.XO(m,null)
-if(this.e){z=J.w8(this.c.e.gcG())
-r=t
-r=z==null?r==null:z===r
-z=r}else z=!1
+z=this.c.e.gcG()
+r=this.f
+y=r.gyK()
+x=!0
+if(y!=null)try{x=this.UI.FI(y,J.w8(z))}catch(q){r=H.Ru(q)
+w=r
+v=new H.XO(q,null)
+r=J.w8(z)
+p=w
+o=(r==null?p==null:r===p)?z:new P.Ca(w,v)
 r=this.b
-if(z)r.c=this.c.e.gcG()
-else r.c=new P.Ca(t,s)
+r.c=o
+r.b=!1
+return}u=r.go7()
+if(x===!0&&u!=null){try{r=u
+p=H.N7()
+p=H.KT(p,[p,p]).BD(r)
+n=this.UI
+m=this.b
+if(p)m.c=n.mg(u,J.w8(z),z.gI4())
+else m.c=n.FI(u,J.w8(z))}catch(q){r=H.Ru(q)
+t=r
+s=new H.XO(q,null)
+r=J.w8(z)
+p=t
+o=(r==null?p==null:r===p)?z:new P.Ca(t,s)
+r=this.b
+r.c=o
+r.b=!1
+return}this.b.b=!0}else{r=this.b
+r.c=z
 r.b=!1}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-wB:{
-"":"Tp:229;c,UI",
-call$1:[function(a){P.HZ(this.c.e,this.UI)},"call$1",null,2,0,null,397,"call"],
+RT:{
+"^":"Tp:107;c,b,bK,Gq,Rm",
+call$0:[function(){var z,y,x,w,v,u
+z={}
+z.a=null
+try{z.a=this.Rm.Gr(this.Gq.gIa())}catch(w){v=H.Ru(w)
+y=v
+x=new H.XO(w,null)
+if(this.bK){v=J.w8(this.c.e.gcG())
+u=y
+u=v==null?u==null:v===u
+v=u}else v=!1
+u=this.b
+if(v)u.c=this.c.e.gcG()
+else u.c=new P.Ca(y,x)
+u.b=!1}v=z.a
+u=J.x(v)
+if(typeof v==="object"&&v!==null&&!!u.$isb8){v=this.Gq
+v.swG(!0)
+this.b.d=!0
+z.a.Rx(new P.jZ(this.c,v),new P.FZ(z,v))}},"call$0",null,0,0,null,"call"],
 $isEH:true},
-Pu:{
-"":"Tp:396;a,bK",
+jZ:{
+"^":"Tp:223;c,w3",
+call$1:[function(a){P.HZ(this.c.e,this.w3)},"call$1",null,2,0,null,393,[],"call"],
+$isEH:true},
+FZ:{
+"^":"Tp:392;a,HZ",
 call$2:[function(a,b){var z,y,x,w
 z=this.a
 y=z.a
 x=J.x(y)
 if(typeof y!=="object"||y===null||!x.$isvs){w=P.Dt(null)
 z.a=w
-w.E6(a,b)}P.HZ(z.a,this.bK)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,146,147,"call"],
+w.E6(a,b)}P.HZ(z.a,this.HZ)},function(a){return this.call$2(a,null)},"call$1","call$2",null,null,2,2,null,77,152,[],153,[],"call"],
 $isEH:true},
+OM:{
+"^":"a;FR,aw@",
+Ki:function(){return this.FR.call$0()}},
 qh:{
-"":"a;",
-ez:[function(a,b){return H.VM(new P.t3(b,this),[H.ip(this,"qh",0),null])},"call$1","gIr",2,0,null,398],
+"^":"a;",
+ez:[function(a,b){return H.VM(new P.t3(b,this),[H.ip(this,"qh",0),null])},"call$1","gIr",2,0,null,394,[]],
 tg:[function(a,b){var z,y
 z={}
 y=P.Dt(J.kn)
 z.a=null
-z.a=this.KR(new P.YJ(z,this,b,y),!0,new P.DO(y),y.gbY())
-return y},"call$1","gdj",2,0,null,102],
+z.a=this.KR(new P.tG(z,this,b,y),!0,new P.zn(y),y.gbY())
+return y},"call$1","gdj",2,0,null,102,[]],
 aN:[function(a,b){var z,y
 z={}
 y=P.Dt(null)
 z.a=null
 z.a=this.KR(new P.lz(z,this,b,y),!0,new P.M4(y),y.gbY())
-return y},"call$1","gjw",2,0,null,378],
+return y},"call$1","gjw",2,0,null,371,[]],
 Vr:[function(a,b){var z,y
 z={}
 y=P.Dt(J.kn)
 z.a=null
 z.a=this.KR(new P.Jp(z,this,b,y),!0,new P.eN(y),y.gbY())
-return y},"call$1","gG2",2,0,null,379],
+return y},"call$1","gG2",2,0,null,372,[]],
 gB:function(a){var z,y
 z={}
-y=new P.vs(0,$.X3,null,null,null,null,null,null)
-y.$builtinTypeInfo=[J.im]
+y=P.Dt(J.im)
 z.a=0
 this.KR(new P.PI(z),!0,new P.uO(z,y),y.gbY())
 return y},
@@ -12533,7 +12900,7 @@
 return y},"call$0","gRV",0,0,null],
 eR:[function(a,b){var z=H.VM(new P.dq(b,this),[null])
 z.U6(this,b,null)
-return z},"call$1","gVQ",2,0,null,122],
+return z},"call$1","gZo",2,0,null,122,[]],
 gtH:function(a){var z,y
 z={}
 y=P.Dt(H.ip(this,"qh",0))
@@ -12554,281 +12921,202 @@
 y=P.Dt(H.ip(this,"qh",0))
 z.b=null
 z.b=this.KR(new P.ii(z,this,y),!0,new P.ib(z,y),y.gbY())
-return y},"call$1","goY",2,0,null,47],
+return y},"call$1","goY",2,0,null,47,[]],
 $isqh:true},
-YJ:{
-"":"Tp;a,b,c,d",
+tG:{
+"^":"Tp;a,b,c,d",
 call$1:[function(a){var z,y
 z=this.a
 y=this.d
-P.FE(new P.jv(this.c,a),new P.LB(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,"call"],
+P.FE(new P.jv(this.c,a),new P.LB(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 jv:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return J.de(this.f,this.e)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 LB:{
-"":"Tp:374;a,UI",
-call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,399,"call"],
+"^":"Tp:367;a,UI",
+call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,395,[],"call"],
 $isEH:true},
-DO:{
-"":"Tp:108;bK",
+zn:{
+"^":"Tp:108;bK",
 call$0:[function(){this.bK.rX(!1)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 lz:{
-"":"Tp;a,b,c,d",
-call$1:[function(a){P.FE(new P.Rl(this.c,a),new P.Jb(),P.TB(this.a.a,this.d))},"call$1",null,2,0,null,124,"call"],
+"^":"Tp;a,b,c,d",
+call$1:[function(a){P.FE(new P.Rl(this.c,a),new P.Jb(),P.TB(this.a.a,this.d))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 Rl:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return this.e.call$1(this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Jb:{
-"":"Tp:229;",
-call$1:[function(a){},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 M4:{
-"":"Tp:108;UI",
+"^":"Tp:108;UI",
 call$0:[function(){this.UI.rX(null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Jp:{
-"":"Tp;a,b,c,d",
+"^":"Tp;a,b,c,d",
 call$1:[function(a){var z,y
 z=this.a
 y=this.d
-P.FE(new P.h7(this.c,a),new P.pr(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,"call"],
+P.FE(new P.h7(this.c,a),new P.pr(z,y),P.TB(z.a,y))},"call$1",null,2,0,null,124,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 h7:{
-"":"Tp:108;e,f",
+"^":"Tp:108;e,f",
 call$0:[function(){return this.e.call$1(this.f)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 pr:{
-"":"Tp:374;a,UI",
-call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,399,"call"],
+"^":"Tp:367;a,UI",
+call$1:[function(a){if(a===!0)P.Bb(this.a.a,this.UI,!0)},"call$1",null,2,0,null,395,[],"call"],
 $isEH:true},
 eN:{
-"":"Tp:108;bK",
+"^":"Tp:108;bK",
 call$0:[function(){this.bK.rX(!1)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 PI:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
-z.a=z.a+1},"call$1",null,2,0,null,240,"call"],
+z.a=z.a+1},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 uO:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){this.b.rX(this.a.a)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 j4:{
-"":"Tp:229;a,b",
-call$1:[function(a){P.Bb(this.a.a,this.b,!1)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){P.Bb(this.a.a,this.b,!1)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 i9:{
-"":"Tp:108;c",
+"^":"Tp:108;c",
 call$0:[function(){this.c.rX(!0)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 VV:{
-"":"Tp;a,b",
-call$1:[function(a){this.b.push(a)},"call$1",null,2,0,null,237,"call"],
+"^":"Tp;a,b",
+call$1:[function(a){this.b.push(a)},"call$1",null,2,0,null,231,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.a,"qh")}},
 Dy:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){this.d.rX(this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 lU:{
-"":"Tp;a,b,c",
-call$1:[function(a){P.Bb(this.a.a,this.c,a)},"call$1",null,2,0,null,23,"call"],
+"^":"Tp;a,b,c",
+call$1:[function(a){P.Bb(this.a.a,this.c,a)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 OC:{
-"":"Tp:108;d",
+"^":"Tp:108;d",
 call$0:[function(){this.d.Lp(new P.lj("No elements"))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 UH:{
-"":"Tp;a,b",
+"^":"Tp;a,b",
 call$1:[function(a){var z=this.a
 z.b=!0
-z.a=a},"call$1",null,2,0,null,23,"call"],
+z.a=a},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 Z5:{
-"":"Tp:108;a,c",
+"^":"Tp:108;a,c",
 call$0:[function(){var z=this.a
 if(z.b){this.c.rX(z.a)
 return}this.c.Lp(new P.lj("No elements"))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ii:{
-"":"Tp;a,b,c",
+"^":"Tp;a,b,c",
 call$1:[function(a){var z=this.a
 if(J.de(z.a,0)){P.Bb(z.b,this.c,a)
-return}z.a=J.xH(z.a,1)},"call$1",null,2,0,null,23,"call"],
+return}z.a=J.xH(z.a,1)},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"Lf",args:[a]}},this.b,"qh")}},
 ib:{
-"":"Tp:108;a,d",
+"^":"Tp:108;a,d",
 call$0:[function(){this.d.Lp(new P.bJ("value "+H.d(this.a.a)))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 MO:{
-"":"a;",
+"^":"a;",
 $isMO:true},
-ms:{
-"":"a;",
-gh6:function(){if((this.Gv&8)===0)return this.iP
-return this.iP.gmT()},
-kW:[function(){var z,y
-if((this.Gv&8)===0){z=this.iP
-if(z==null){z=new P.Qk(null,null,0)
-this.iP=z}return z}y=this.iP
-y.gmT()
-return y.gmT()},"call$0","gUo",0,0,null],
-gEe:function(){if((this.Gv&8)!==0)return this.iP.gmT()
-return this.iP},
-BW:[function(){if((this.Gv&4)!==0)return new P.lj("Cannot add event after closing")
-return new P.lj("Cannot add event while adding a stream")},"call$0","gCi",0,0,null],
-h:[function(a,b){if(this.Gv>=4)throw H.b(this.BW())
-this.Rg(0,b)},"call$1","ght",2,0,function(){return H.IG(function(a){return{func:"lU6",void:true,args:[a]}},this.$receiver,"ms")},23],
-cO:[function(a){var z,y
-z=this.Gv
-if((z&4)!==0)return this.Ip
-if(z>=4)throw H.b(this.BW())
-z|=4
-this.Gv=z
-if(this.Ip==null){y=P.Dt(null)
-this.Ip=y
-if((z&2)!==0)y.rX(null)}z=this.Gv
-if((z&1)!==0)this.SY()
-else if((z&3)===0)this.kW().h(0,C.Wj)
-return this.Ip},"call$0","gJK",0,0,null],
-Rg:[function(a,b){var z=this.Gv
-if((z&1)!==0)this.Iv(b)
-else if((z&3)===0)this.kW().h(0,H.VM(new P.LV(b,null),[H.ip(this,"ms",0)]))},"call$1","gHR",2,0,null,23],
-V8:[function(a,b){var z=this.Gv
-if((z&1)!==0)this.pb(a,b)
-else if((z&3)===0)this.kW().h(0,new P.DS(a,b,null))},"call$2","grd",4,0,null,146,147],
-Qj:[function(){var z=this.iP
-this.iP=z.gmT()
-this.Gv=this.Gv&4294967287
-z.tZ(0)},"call$0","gS2",0,0,null],
-ET:[function(a){var z,y,x,w,v
-if((this.Gv&3)!==0)throw H.b(new P.lj("Stream has already been listened to."))
-z=$.X3
-y=a?1:0
-x=H.VM(new P.yU(this,null,null,null,z,y,null,null),[null])
-w=this.gh6()
-y=this.Gv|1
-this.Gv=y
-if((y&8)!==0){v=this.iP
-v.smT(x)
-v.QE()}else this.iP=x
-x.WN(w)
-x.J7(new P.UO(this))
-return x},"call$1","gwk",2,0,null,346],
-j0:[function(a){var z,y
-if((this.Gv&8)!==0)this.iP.ed()
-this.iP=null
-this.Gv=this.Gv&4294967286|2
-z=new P.Bc(this)
-y=P.ot(this.gQC())
-if(y!=null)y=y.wM(z)
-else z.call$0()
-return y},"call$1","gOr",2,0,null,157],
-mO:[function(a){if((this.Gv&8)!==0)this.iP.yy(0)
-P.ot(this.gp4())},"call$1","gnx",2,0,null,157],
-m4:[function(a){if((this.Gv&8)!==0)this.iP.QE()
-P.ot(this.gZ9())},"call$1","gyb",2,0,null,157]},
-UO:{
-"":"Tp:108;a",
-call$0:[function(){P.ot(this.a.gnL())},"call$0",null,0,0,null,"call"],
-$isEH:true},
-Bc:{
-"":"Tp:107;a",
-call$0:[function(){var z=this.a.Ip
-if(z!=null&&z.Gv===0)z.OH(null)},"call$0",null,0,0,null,"call"],
-$isEH:true},
-vp:{
-"":"a;",
-Iv:[function(a){this.gEe().Rg(0,a)},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){this.gEe().V8(a,b)},"call$2","gTb",4,0,null,146,147],
-SY:[function(){this.gEe().Qj()},"call$0","gXm",0,0,null]},
-lk:{
-"":"a;",
-Iv:[function(a){this.gEe().w6(H.VM(new P.LV(a,null),[null]))},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){this.gEe().w6(new P.DS(a,b,null))},"call$2","gTb",4,0,null,146,147],
-SY:[function(){this.gEe().w6(C.Wj)},"call$0","gXm",0,0,null]},
-q1:{
-"":"ZzD;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},
-ZzD:{
-"":"ms+lk;"},
-ly:{
-"":"fE;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},
-fE:{
-"":"ms+vp;"},
 O9:{
-"":"ez;Y8",
-w4:[function(a){return this.Y8.ET(a)},"call$1","gvC",2,0,null,346],
+"^":"ez;",
+w4:[function(a){var z,y,x,w
+z=this.Y8
+if((z.Gv&4)!==0)H.vh(new P.lj("Subscribing to closed stream"))
+y=$.X3
+x=a?1:0
+w=H.VM(new P.JI(null,null,null,z,null,null,null,y,x,null,null),[H.Kp(z,0)])
+w.SJ=w
+w.iE=w
+x=z.SJ
+w.SJ=x
+w.iE=z
+x.siE(w)
+z.SJ=w
+w.Ae=z.Gv&1
+if(z.iE===w)P.ot(z.nL)
+return w},"call$1","gvC",2,0,null,396,[]],
 giO:function(a){return(H.eQ(this.Y8)^892482866)>>>0},
 n:[function(a,b){var z
 if(b==null)return!1
 if(this===b)return!0
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isO9)return!1
-return b.Y8===this.Y8},"call$1","gUJ",2,0,null,104],
+return b.Y8===this.Y8},"call$1","gUJ",2,0,null,104,[]],
 $isO9:true},
-yU:{
-"":"KA;Y8<,dB,o7,Bd,Lj,Gv,lz,Ri",
-tA:[function(){return this.gY8().j0(this)},"call$0","gQC",0,0,400],
-uO:[function(){this.gY8().mO(this)},"call$0","gp4",0,0,107],
-LP:[function(){this.gY8().m4(this)},"call$0","gZ9",0,0,107]},
+oh:{
+"^":"KA;Y8<",
+tA:[function(){return this.gY8().j0(this)},"call$0","gQC",0,0,null],
+uO:[function(){this.gY8()},"call$0","gp4",0,0,107],
+LP:[function(){this.gY8()},"call$0","gZ9",0,0,107]},
 nP:{
-"":"a;"},
+"^":"a;"},
 KA:{
-"":"a;dB,o7<,Bd,Lj<,Gv,lz,Ri",
-WN:[function(a){if(a==null)return
-this.Ri=a
-if(!a.gl0(a)){this.Gv=(this.Gv|64)>>>0
-this.Ri.t2(this)}},"call$1","gNl",2,0,null,401],
-fe:[function(a){this.dB=this.Lj.cR(a)},"call$1","gqd",2,0,null,402],
+"^":"a;dB,o7<,Bd,Lj<,Gv,lz,Ri",
+fe:[function(a){this.dB=this.Lj.cR(a)},"call$1","gqd",2,0,null,397,[]],
 fm:[function(a,b){if(b==null)b=P.AY()
-this.o7=P.VH(b,this.Lj)},"call$1","geO",2,0,null,29],
+this.o7=P.VH(b,this.Lj)},"call$1","geO",2,0,null,29,[]],
 y5:[function(a){if(a==null)a=P.v3()
-this.Bd=this.Lj.Al(a)},"call$1","gNS",2,0,null,403],
-nB:[function(a,b){var z=this.Gv
+this.Bd=this.Lj.Al(a)},"call$1","gNS",2,0,null,398,[]],
+nB:[function(a,b){var z,y,x
+z=this.Gv
 if((z&8)!==0)return
-this.Gv=(z+128|4)>>>0
-if(z<128&&this.Ri!=null)this.Ri.FK()
-if((z&4)===0&&(this.Gv&32)===0)this.J7(this.gp4())},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,404],
+y=(z+128|4)>>>0
+this.Gv=y
+if(z<128&&this.Ri!=null){x=this.Ri
+if(x.Gv===1)x.Gv=3}if((z&4)===0&&(y&32)===0)this.J7(this.gp4())},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,399,[]],
 QE:[function(){var z=this.Gv
 if((z&8)!==0)return
 if(z>=128){z-=128
 this.Gv=z
-if(z<128){if((z&64)!==0){z=this.Ri
-z=!z.gl0(z)}else z=!1
-if(z)this.Ri.t2(this)
-else{z=(this.Gv&4294967291)>>>0
+if(z<128)if((z&64)!==0&&this.Ri.N6!=null)this.Ri.t2(this)
+else{z=(z&4294967291)>>>0
 this.Gv=z
-if((z&32)===0)this.J7(this.gZ9())}}}},"call$0","gDQ",0,0,null],
+if((z&32)===0)this.J7(this.gZ9())}}},"call$0","gDQ",0,0,null],
 ed:[function(){var z=(this.Gv&4294967279)>>>0
 this.Gv=z
 if((z&8)!==0)return this.lz
 this.Ek()
 return this.lz},"call$0","gZS",0,0,null],
-Ek:[function(){var z=(this.Gv|8)>>>0
+gRW:function(){return this.Gv>=128},
+Ek:[function(){var z,y
+z=(this.Gv|8)>>>0
 this.Gv=z
-if((z&64)!==0)this.Ri.FK()
-if((this.Gv&32)===0)this.Ri=null
+if((z&64)!==0){y=this.Ri
+if(y.Gv===1)y.Gv=3}if((z&32)===0)this.Ri=null
 this.lz=this.tA()},"call$0","gbz",0,0,null],
 Rg:[function(a,b){var z=this.Gv
 if((z&8)!==0)return
 if(z<32)this.Iv(b)
-else this.w6(H.VM(new P.LV(b,null),[null]))},"call$1","gHR",2,0,null,237],
+else this.w6(H.VM(new P.LV(b,null),[null]))},"call$1","gHR",2,0,null,231,[]],
 V8:[function(a,b){var z=this.Gv
 if((z&8)!==0)return
 if(z<32)this.pb(a,b)
-else this.w6(new P.DS(a,b,null))},"call$2","grd",4,0,null,146,147],
+else this.w6(new P.DS(a,b,null))},"call$2","grd",4,0,null,152,[],153,[]],
 Qj:[function(){var z=this.Gv
 if((z&8)!==0)return
 z=(z|2)>>>0
@@ -12837,7 +13125,7 @@
 else this.w6(C.Wj)},"call$0","gS2",0,0,null],
 uO:[function(){},"call$0","gp4",0,0,107],
 LP:[function(){},"call$0","gZ9",0,0,107],
-tA:[function(){},"call$0","gQC",0,0,400],
+tA:[function(){},"call$0","gQC",0,0,null],
 w6:[function(a){var z,y
 z=this.Ri
 if(z==null){z=new P.Qk(null,null,0)
@@ -12845,56 +13133,47 @@
 y=this.Gv
 if((y&64)===0){y=(y|64)>>>0
 this.Gv=y
-if(y<128)this.Ri.t2(this)}},"call$1","gnX",2,0,null,405],
+if(y<128)this.Ri.t2(this)}},"call$1","gnX",2,0,null,400,[]],
 Iv:[function(a){var z=this.Gv
 this.Gv=(z|32)>>>0
 this.Lj.m1(this.dB,a)
 this.Gv=(this.Gv&4294967263)>>>0
-this.Kl((z&4)!==0)},"call$1","gm9",2,0,null,237],
-pb:[function(a,b){var z,y,x
+this.Kl((z&4)!==0)},"call$1","gm9",2,0,null,231,[]],
+pb:[function(a,b){var z,y
 z=this.Gv
 y=new P.Vo(this,a,b)
 if((z&1)!==0){this.Gv=(z|16)>>>0
 this.Ek()
-z=this.lz
-x=J.x(z)
-if(typeof z==="object"&&z!==null&&!!x.$isb8)z.wM(y)
-else y.call$0()}else{y.call$0()
-this.Kl((z&4)!==0)}},"call$2","gTb",4,0,null,146,147],
-SY:[function(){var z,y,x
-z=new P.qB(this)
-this.Ek()
+y.call$0()}else{y.call$0()
+this.Kl((z&4)!==0)}},"call$2","gTb",4,0,null,152,[],153,[]],
+SY:[function(){this.Ek()
 this.Gv=(this.Gv|16)>>>0
-y=this.lz
-x=J.x(y)
-if(typeof y==="object"&&y!==null&&!!x.$isb8)y.wM(z)
-else z.call$0()},"call$0","gXm",0,0,null],
+new P.qB(this).call$0()},"call$0","gXm",0,0,null],
 J7:[function(a){var z=this.Gv
 this.Gv=(z|32)>>>0
 a.call$0()
 this.Gv=(this.Gv&4294967263)>>>0
-this.Kl((z&4)!==0)},"call$1","gc2",2,0,null,150],
-Kl:[function(a){var z,y
-if((this.Gv&64)!==0){z=this.Ri
-z=z.gl0(z)}else z=!1
-if(z){z=(this.Gv&4294967231)>>>0
+this.Kl((z&4)!==0)},"call$1","gc2",2,0,null,148,[]],
+Kl:[function(a){var z,y,x
+z=this.Gv
+if((z&64)!==0&&this.Ri.N6==null){z=(z&4294967231)>>>0
 this.Gv=z
-if((z&4)!==0)if(z<128){z=this.Ri
-z=z==null||z.gl0(z)}else z=!1
-else z=!1
-if(z)this.Gv=(this.Gv&4294967291)>>>0}for(;!0;a=y){z=this.Gv
-if((z&8)!==0){this.Ri=null
-return}y=(z&4)!==0
-if(a===y)break
+if((z&4)!==0)if(z<128){y=this.Ri
+y=y==null||y.N6==null}else y=!1
+else y=!1
+if(y){z=(z&4294967291)>>>0
+this.Gv=z}}for(;!0;a=x){if((z&8)!==0){this.Ri=null
+return}x=(z&4)!==0
+if(a===x)break
 this.Gv=(z^32)>>>0
-if(y)this.uO()
+if(x)this.uO()
 else this.LP()
-this.Gv=(this.Gv&4294967263)>>>0}z=this.Gv
-if((z&64)!==0&&z<128)this.Ri.t2(this)},"call$1","ghE",2,0,null,406],
+z=(this.Gv&4294967263)>>>0
+this.Gv=z}if((z&64)!==0&&z<128)this.Ri.t2(this)},"call$1","ghE",2,0,null,401,[]],
 $isMO:true,
-static:{"":"ry,bG,nS,R7,yJ,X8,HX,GC,L3"}},
+static:{"^":"ry,bG,Q9,Ir,Il,X8,HX,GC,f9"}},
 Vo:{
-"":"Tp:107;a,b,c",
+"^":"Tp:107;a,b,c",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 y=z.Gv
@@ -12910,7 +13189,7 @@
 else y.m1(x,v)}z.Gv=(z.Gv&4294967263)>>>0},"call$0",null,0,0,null,"call"],
 $isEH:true},
 qB:{
-"":"Tp:107;a",
+"^":"Tp:107;a",
 call$0:[function(){var z,y
 z=this.a
 y=z.Gv
@@ -12920,43 +13199,41 @@
 z.Gv=(z.Gv&4294967263)>>>0},"call$0",null,0,0,null,"call"],
 $isEH:true},
 ez:{
-"":"qh;",
+"^":"qh;",
 KR:[function(a,b,c,d){var z=this.w4(!0===b)
 z.fe(a)
 z.fm(0,d)
 z.y5(c)
-return z},function(a){return this.KR(a,null,null,null)},"yI",function(a,b,c){return this.KR(a,null,b,c)},"zC","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
+return z},function(a){return this.KR(a,null,null,null)},"yI",function(a,b,c){return this.KR(a,null,b,c)},"zC","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
 w4:[function(a){var z,y
 z=$.X3
 y=a?1:0
 y=new P.KA(null,null,null,z,y,null,null)
 y.$builtinTypeInfo=this.$builtinTypeInfo
-return y},"call$1","gvC",2,0,null,346],
-na:[function(a){},"call$1","gnL",2,0,407,157]},
+return y},"call$1","gvC",2,0,null,396,[]]},
 lx:{
-"":"a;LD@"},
+"^":"a;aw@"},
 LV:{
-"":"lx;P>,LD",
+"^":"lx;P>,aw",
 r6:function(a,b){return this.P.call$1(b)},
-pP:[function(a){a.Iv(this.P)},"call$1","gqp",2,0,null,408]},
+dP:[function(a){a.Iv(this.P)},"call$1","gqp",2,0,null,404,[]]},
 DS:{
-"":"lx;kc>,I4<,LD",
-pP:[function(a){a.pb(this.kc,this.I4)},"call$1","gqp",2,0,null,408]},
+"^":"lx;kc>,I4<,aw",
+dP:[function(a){a.pb(this.kc,this.I4)},"call$1","gqp",2,0,null,404,[]]},
 JF:{
-"":"a;",
-pP:[function(a){a.SY()},"call$1","gqp",2,0,null,408],
-gLD:function(){return},
-sLD:function(a){throw H.b(new P.lj("No events after a done."))}},
-ht:{
-"":"a;",
+"^":"a;",
+dP:[function(a){a.SY()},"call$1","gqp",2,0,null,404,[]],
+gaw:function(){return},
+saw:function(a){throw H.b(new P.lj("No events after a done."))}},
+Je:{
+"^":"a;",
 t2:[function(a){var z=this.Gv
 if(z===1)return
 if(z>=1){this.Gv=1
 return}P.rb(new P.CR(this,a))
-this.Gv=1},"call$1","gQu",2,0,null,408],
-FK:[function(){if(this.Gv===1)this.Gv=3},"call$0","gTg",0,0,null]},
+this.Gv=1},"call$1","gQu",2,0,null,404,[]]},
 CR:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){var z,y
 z=this.a
 y=z.Gv
@@ -12965,35 +13242,35 @@
 z.TO(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Qk:{
-"":"ht;zR,N6,Gv",
+"^":"Je;zR,N6,Gv",
 gl0:function(a){return this.N6==null},
 h:[function(a,b){var z=this.N6
 if(z==null){this.N6=b
-this.zR=b}else{z.sLD(b)
-this.N6=b}},"call$1","ght",2,0,null,405],
+this.zR=b}else{z.saw(b)
+this.N6=b}},"call$1","ght",2,0,null,400,[]],
 TO:[function(a){var z,y
 z=this.zR
-y=z.gLD()
+y=z.gaw()
 this.zR=y
 if(y==null)this.N6=null
-z.pP(a)},"call$1","gTn",2,0,null,408],
+z.dP(a)},"call$1","gTn",2,0,null,404,[]],
 V1:[function(a){if(this.Gv===1)this.Gv=3
 this.N6=null
 this.zR=null},"call$0","gyP",0,0,null]},
-dR:{
-"":"Tp:108;a,b,c",
+v1y:{
+"^":"Tp:108;a,b,c",
 call$0:[function(){return this.a.K5(this.b,this.c)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 uR:{
-"":"Tp:409;a,b",
-call$2:[function(a,b){return P.NX(this.a,this.b,a,b)},"call$2",null,4,0,null,146,147,"call"],
+"^":"Tp:405;a,b",
+call$2:[function(a,b){return P.NX(this.a,this.b,a,b)},"call$2",null,4,0,null,152,[],153,[],"call"],
 $isEH:true},
-QX:{
-"":"Tp:108;a,b",
+Q0:{
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.rX(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 YR:{
-"":"qh;",
+"^":"qh;",
 KR:[function(a,b,c,d){var z,y,x,w,v
 b=!0===b
 z=H.ip(this,"YR",0)
@@ -13005,15 +13282,15 @@
 v.fe(a)
 v.fm(0,d)
 v.y5(c)
-return v},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
-Ml:[function(a,b){b.Rg(0,a)},"call$2","gOa",4,0,null,237,410],
+return v},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
+Ml:[function(a,b){b.Rg(0,a)},"call$2","gOa",4,0,null,231,[],406,[]],
 $asqh:function(a,b){return[b]}},
 fB:{
-"":"KA;UY,Ee,dB,o7,Bd,Lj,Gv,lz,Ri",
+"^":"KA;UY,Ee,dB,o7,Bd,Lj,Gv,lz,Ri",
 Rg:[function(a,b){if((this.Gv&2)!==0)return
-P.KA.prototype.Rg.call(this,this,b)},"call$1","gHR",2,0,null,237],
+P.KA.prototype.Rg.call(this,this,b)},"call$1","gHR",2,0,null,231,[]],
 V8:[function(a,b){if((this.Gv&2)!==0)return
-P.KA.prototype.V8.call(this,a,b)},"call$2","grd",4,0,null,146,147],
+P.KA.prototype.V8.call(this,a,b)},"call$2","grd",4,0,null,152,[],153,[]],
 uO:[function(){var z=this.Ee
 if(z==null)return
 z.yy(0)},"call$0","gp4",0,0,107],
@@ -13022,9 +13299,9 @@
 z.QE()},"call$0","gZ9",0,0,107],
 tA:[function(){var z=this.Ee
 if(z!=null){this.Ee=null
-z.ed()}return},"call$0","gQC",0,0,400],
-vx:[function(a){this.UY.Ml(a,this)},"call$1","gOa",2,0,function(){return H.IG(function(a,b){return{func:"kA",void:true,args:[a]}},this.$receiver,"fB")},237],
-xL:[function(a,b){this.V8(a,b)},"call$2","gRE",4,0,411,146,147],
+z.ed()}return},"call$0","gQC",0,0,null],
+vx:[function(a){this.UY.Ml(a,this)},"call$1","gOa",2,0,function(){return H.IG(function(a,b){return{func:"kA",void:true,args:[a]}},this.$receiver,"fB")},231,[]],
+xL:[function(a,b){this.V8(a,b)},"call$2","gRE",4,0,407,152,[],153,[]],
 nn:[function(){this.Qj()},"call$0","gH1",0,0,107],
 S8:function(a,b,c,d){var z,y
 z=this.gOa()
@@ -13033,7 +13310,7 @@
 $asKA:function(a,b){return[b]},
 $asMO:function(a,b){return[b]}},
 nO:{
-"":"YR;qs,Sb",
+"^":"YR;qs,Sb",
 Dr:function(a){return this.qs.call$1(a)},
 Ml:[function(a,b){var z,y,x,w,v
 z=null
@@ -13041,11 +13318,11 @@
 y=v
 x=new H.XO(w,null)
 b.V8(y,x)
-return}if(z===!0)J.QM(b,a)},"call$2","gOa",4,0,null,412,410],
+return}if(z===!0)J.QM(b,a)},"call$2","gOa",4,0,null,408,[],406,[]],
 $asYR:function(a){return[a,a]},
 $asqh:null},
 t3:{
-"":"YR;TN,Sb",
+"^":"YR;TN,Sb",
 kn:function(a){return this.TN.call$1(a)},
 Ml:[function(a,b){var z,y,x,w,v
 z=null
@@ -13053,23 +13330,25 @@
 y=v
 x=new H.XO(w,null)
 b.V8(y,x)
-return}J.QM(b,z)},"call$2","gOa",4,0,null,412,410]},
+return}J.QM(b,z)},"call$2","gOa",4,0,null,408,[],406,[]]},
 dq:{
-"":"YR;Em,Sb",
+"^":"YR;Em,Sb",
 Ml:[function(a,b){var z=this.Em
 if(z>0){this.Em=z-1
-return}b.Rg(0,a)},"call$2","gOa",4,0,null,412,410],
+return}b.Rg(0,a)},"call$2","gOa",4,0,null,408,[],406,[]],
 U6:function(a,b,c){},
 $asYR:function(a){return[a,a]},
 $asqh:null},
-tU:{
-"":"a;"},
+lO:{
+"^":"a;"},
 aY:{
-"":"a;"},
+"^":"a;"},
 zG:{
-"":"a;E2<,cP<,Jl<,pU<,Fh<,Xp<,aj<,rb<,Zq<,rF,JS>,iq<",
+"^":"a;E2<,cP<,Jl<,pU<,Fh<,Xp<,aj<,rb<,Zq<,rF,JS>,iq<",
 hk:function(a,b){return this.E2.call$2(a,b)},
 Gr:function(a){return this.cP.call$1(a)},
+FI:function(a,b){return this.Jl.call$2(a,b)},
+mg:function(a,b,c){return this.pU.call$3(a,b,c)},
 Al:function(a){return this.Fh.call$1(a)},
 cR:function(a){return this.Xp.call$1(a)},
 O8:function(a){return this.aj.call$1(a)},
@@ -13079,137 +13358,137 @@
 Ch:function(a,b){return this.JS.call$1(b)},
 iT:function(a){return this.iq.call$1$specification(a)}},
 e4:{
-"":"a;"},
+"^":"a;"},
 JB:{
-"":"a;"},
+"^":"a;"},
 Id:{
-"":"a;nU",
-gLj:function(){return this.nU},
+"^":"a;oh",
+gLj:function(){return this.oh},
 c1:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gE2()==null;)z=z.geT(z)
-return y.gE2().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gE2",6,0,null,148,146,147],
+return y.gE2().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gE2",6,0,null,146,[],152,[],153,[]],
 Vn:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gcP()==null;)z=z.geT(z)
-return y.gcP().call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gcP",4,0,null,148,110],
+return y.gcP().call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gcP",4,0,null,146,[],110,[]],
 qG:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gJl()==null;)z=z.geT(z)
-return y.gJl().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gJl",6,0,null,148,110,165],
+return y.gJl().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gJl",6,0,null,146,[],110,[],165,[]],
 nA:[function(a,b,c,d){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gpU()==null;)z=z.geT(z)
-return y.gpU().call$6(z,new P.Id(z.geT(z)),a,b,c,d)},"call$4","gpU",8,0,null,148,110,54,55],
+return y.gpU().call$6(z,new P.Id(z.geT(z)),a,b,c,d)},"call$4","gpU",8,0,null,146,[],110,[],54,[],55,[]],
 TE:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gFh(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gFh",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gFh",4,0,null,146,[],110,[]],
 V6:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gXp(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gXp",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gXp",4,0,null,146,[],110,[]],
 mz:[function(a,b){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU().gaj(),y==null;)z=z.geT(z)
-return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gaj",4,0,null,148,110],
+return y.call$4(z,new P.Id(z.geT(z)),a,b)},"call$2","gaj",4,0,null,146,[],110,[]],
 RK:[function(a,b){var z,y,x
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.grb()==null;)z=z.geT(z)
 x=z.geT(z)
-y.grb().call$4(z,new P.Id(x),a,b)},"call$2","grb",4,0,null,148,110],
-dJ:[function(a,b,c){var z,y
-z=this.nU
+y.grb().call$4(z,new P.Id(x),a,b)},"call$2","grb",4,0,null,146,[],110,[]],
+pX:[function(a,b,c){var z,y
+z=this.oh
 for(;y=z.gzU(),y.gZq()==null;)z=z.geT(z)
-return y.gZq().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gZq",6,0,null,148,159,110],
+return y.gZq().call$5(z,new P.Id(z.geT(z)),a,b,c)},"call$3","gZq",6,0,null,146,[],159,[],110,[]],
 RB:[function(a,b,c){var z,y
-z=this.nU
+z=this.oh
 for(;y=z.gzU(),y.gJS(y)==null;)z=z.geT(z)
-y.gJS(y).call$4(z,new P.Id(z.geT(z)),b,c)},"call$2","gJS",4,0,null,148,173],
-GT:[function(a,b,c){var z,y,x
-z=this.nU
+y.gJS(y).call$4(z,new P.Id(z.geT(z)),b,c)},"call$2","gJS",4,0,null,146,[],173,[]],
+ld:[function(a,b,c){var z,y,x
+z=this.oh
 for(;y=z.gzU(),y.giq()==null;)z=z.geT(z)
 x=z.geT(z)
-return y.giq().call$5(z,new P.Id(x),a,b,c)},"call$3","giq",6,0,null,148,176,177]},
+return y.giq().call$5(z,new P.Id(x),a,b,c)},"call$3","giq",6,0,null,146,[],176,[],177,[]]},
 WH:{
-"":"a;",
-fC:[function(a){return this.gC5()===a.gC5()},"call$1","gRX",2,0,null,413],
+"^":"a;",
+fC:[function(a){return this.gC5()===a.gC5()},"call$1","gRX",2,0,null,409,[]],
 bH:[function(a){var z,y,x,w
 try{x=this.Gr(a)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$1","gCF",2,0,null,110],
+return this.hk(z,y)}},"call$1","gCF",2,0,null,110,[]],
 m1:[function(a,b){var z,y,x,w
 try{x=this.FI(a,b)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$2","gNY",4,0,null,110,165],
+return this.hk(z,y)}},"call$2","gNY",4,0,null,110,[],165,[]],
 z8:[function(a,b,c){var z,y,x,w
 try{x=this.mg(a,b,c)
 return x}catch(w){x=H.Ru(w)
 z=x
 y=new H.XO(w,null)
-return this.hk(z,y)}},"call$3","gLG",6,0,null,110,54,55],
+return this.hk(z,y)}},"call$3","gLG",6,0,null,110,[],54,[],55,[]],
 xi:[function(a,b){var z=this.Al(a)
 if(b)return new P.TF(this,z)
-else return new P.K5(this,z)},function(a){return this.xi(a,!0)},"ce","call$2$runGuarded",null,"gAX",2,3,null,337,110,414],
+else return new P.K5(this,z)},function(a){return this.xi(a,!0)},"ce","call$2$runGuarded",null,"gAX",2,3,null,331,110,[],410,[]],
 oj:[function(a,b){var z=this.cR(a)
 if(b)return new P.Cg(this,z)
-else return new P.Hs(this,z)},"call$2$runGuarded","gVF",2,3,null,337,110,414],
+else return new P.Hs(this,z)},"call$2$runGuarded","gVF",2,3,null,331,110,[],410,[]],
 PT:[function(a,b){var z=this.O8(a)
 if(b)return new P.dv(this,z)
-else return new P.pV(this,z)},"call$2$runGuarded","gzg",2,3,null,337,110,414]},
+else return new P.pV(this,z)},"call$2$runGuarded","gzg",2,3,null,331,110,[],410,[]]},
 TF:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.bH(this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 K5:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){return this.c.Gr(this.d)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Cg:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.m1(this.b,a)},"call$1",null,2,0,null,165,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.m1(this.b,a)},"call$1",null,2,0,null,165,[],"call"],
 $isEH:true},
 Hs:{
-"":"Tp:229;c,d",
-call$1:[function(a){return this.c.FI(this.d,a)},"call$1",null,2,0,null,165,"call"],
+"^":"Tp:223;c,d",
+call$1:[function(a){return this.c.FI(this.d,a)},"call$1",null,2,0,null,165,[],"call"],
 $isEH:true},
 dv:{
-"":"Tp:349;a,b",
-call$2:[function(a,b){return this.a.z8(this.b,a,b)},"call$2",null,4,0,null,54,55,"call"],
+"^":"Tp:341;a,b",
+call$2:[function(a,b){return this.a.z8(this.b,a,b)},"call$2",null,4,0,null,54,[],55,[],"call"],
 $isEH:true},
 pV:{
-"":"Tp:349;c,d",
-call$2:[function(a,b){return this.c.mg(this.d,a,b)},"call$2",null,4,0,null,54,55,"call"],
+"^":"Tp:341;c,d",
+call$2:[function(a,b){return this.c.mg(this.d,a,b)},"call$2",null,4,0,null,54,[],55,[],"call"],
 $isEH:true},
-cc:{
-"":"WH;eT>,zU<,R1",
+uo:{
+"^":"WH;eT>,zU<,R1",
 gC5:function(){return this.eT.gC5()},
 t:[function(a,b){var z,y
 z=this.R1
 y=z.t(0,b)
 if(y!=null||z.x4(b))return y
-return this.eT.t(0,b)},"call$1","gIA",2,0,null,42],
-hk:[function(a,b){return new P.Id(this).c1(this,a,b)},"call$2","gE2",4,0,null,146,147],
-c6:[function(a,b){return new P.Id(this).GT(this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,177],
-Gr:[function(a){return new P.Id(this).Vn(this,a)},"call$1","gcP",2,0,null,110],
-FI:[function(a,b){return new P.Id(this).qG(this,a,b)},"call$2","gJl",4,0,null,110,165],
-mg:[function(a,b,c){return new P.Id(this).nA(this,a,b,c)},"call$3","gpU",6,0,null,110,54,55],
-Al:[function(a){return new P.Id(this).TE(this,a)},"call$1","gFh",2,0,null,110],
-cR:[function(a){return new P.Id(this).V6(this,a)},"call$1","gXp",2,0,null,110],
-O8:[function(a){return new P.Id(this).mz(this,a)},"call$1","gaj",2,0,null,110],
-wr:[function(a){new P.Id(this).RK(this,a)},"call$1","grb",2,0,null,110],
-uN:[function(a,b){return new P.Id(this).dJ(this,a,b)},"call$2","gZq",4,0,null,159,110],
-Ch:[function(a,b){new P.Id(this).RB(0,this,b)},"call$1","gJS",2,0,null,173]},
+return this.eT.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+hk:[function(a,b){return new P.Id(this).c1(this,a,b)},"call$2","gE2",4,0,null,152,[],153,[]],
+c6:[function(a,b){return new P.Id(this).ld(this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,[],177,[]],
+Gr:[function(a){return new P.Id(this).Vn(this,a)},"call$1","gcP",2,0,null,110,[]],
+FI:[function(a,b){return new P.Id(this).qG(this,a,b)},"call$2","gJl",4,0,null,110,[],165,[]],
+mg:[function(a,b,c){return new P.Id(this).nA(this,a,b,c)},"call$3","gpU",6,0,null,110,[],54,[],55,[]],
+Al:[function(a){return new P.Id(this).TE(this,a)},"call$1","gFh",2,0,null,110,[]],
+cR:[function(a){return new P.Id(this).V6(this,a)},"call$1","gXp",2,0,null,110,[]],
+O8:[function(a){return new P.Id(this).mz(this,a)},"call$1","gaj",2,0,null,110,[]],
+wr:[function(a){new P.Id(this).RK(this,a)},"call$1","grb",2,0,null,110,[]],
+uN:[function(a,b){return new P.Id(this).pX(this,a,b)},"call$2","gZq",4,0,null,159,[],110,[]],
+Ch:[function(a,b){new P.Id(this).RB(0,this,b)},"call$1","gJS",2,0,null,173,[]]},
 pK:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){P.IA(new P.eM(this.a,this.b))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 eM:{
-"":"Tp:108;c,d",
+"^":"Tp:108;c,d",
 call$0:[function(){var z,y,x
 z=this.c
 P.JS("Uncaught Error: "+H.d(z))
@@ -13221,18 +13500,20 @@
 throw H.b(z)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Uez:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){if(a==null)throw H.b(new P.AT("ZoneValue key must not be null"))
-this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
-W5:{
-"":"a;",
+nU:{
+"^":"a;",
 gE2:function(){return P.xP()},
 hk:function(a,b){return this.gE2().call$2(a,b)},
 gcP:function(){return P.AI()},
 Gr:function(a){return this.gcP().call$1(a)},
 gJl:function(){return P.MM()},
+FI:function(a,b){return this.gJl().call$2(a,b)},
 gpU:function(){return P.l4()},
+mg:function(a,b,c){return this.gpU().call$3(a,b,c)},
 gFh:function(){return P.EU()},
 Al:function(a){return this.gFh().call$1(a)},
 gXp:function(){return P.zi()},
@@ -13245,31 +13526,31 @@
 gZq:function(){return P.KF()},
 uN:function(a,b){return this.gZq().call$2(a,b)},
 gJS:function(a){return P.YM()},
-Ch:function(a,b){return this.gJS(a).call$1(b)},
+Ch:function(a,b){return this.gJS(this).call$1(b)},
 giq:function(){return P.hn()},
 iT:function(a){return this.giq().call$1$specification(a)}},
 R8:{
-"":"WH;",
+"^":"WH;",
 geT:function(a){return},
 gzU:function(){return C.v8},
 gC5:function(){return this},
-fC:[function(a){return a.gC5()===this},"call$1","gRX",2,0,null,413],
-t:[function(a,b){return},"call$1","gIA",2,0,null,42],
-hk:[function(a,b){return P.L2(this,null,this,a,b)},"call$2","gE2",4,0,null,146,147],
-c6:[function(a,b){return P.UA(this,null,this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,177],
-Gr:[function(a){return P.T8(this,null,this,a)},"call$1","gcP",2,0,null,110],
-FI:[function(a,b){return P.V7(this,null,this,a,b)},"call$2","gJl",4,0,null,110,165],
-mg:[function(a,b,c){return P.Qx(this,null,this,a,b,c)},"call$3","gpU",6,0,null,110,54,55],
-Al:[function(a){return a},"call$1","gFh",2,0,null,110],
-cR:[function(a){return a},"call$1","gXp",2,0,null,110],
-O8:[function(a){return a},"call$1","gaj",2,0,null,110],
-wr:[function(a){P.Tk(this,null,this,a)},"call$1","grb",2,0,null,110],
-uN:[function(a,b){return P.h8(this,null,this,a,b)},"call$2","gZq",4,0,null,159,110],
+fC:[function(a){return a.gC5()===this},"call$1","gRX",2,0,null,409,[]],
+t:[function(a,b){return},"call$1","gIA",2,0,null,42,[]],
+hk:[function(a,b){return P.L2(this,null,this,a,b)},"call$2","gE2",4,0,null,152,[],153,[]],
+c6:[function(a,b){return P.UA(this,null,this,a,b)},function(a){return this.c6(a,null)},"iT","call$2$specification$zoneValues",null,"giq",0,5,null,77,77,176,[],177,[]],
+Gr:[function(a){return P.T8(this,null,this,a)},"call$1","gcP",2,0,null,110,[]],
+FI:[function(a,b){return P.V7(this,null,this,a,b)},"call$2","gJl",4,0,null,110,[],165,[]],
+mg:[function(a,b,c){return P.Qx(this,null,this,a,b,c)},"call$3","gpU",6,0,null,110,[],54,[],55,[]],
+Al:[function(a){return a},"call$1","gFh",2,0,null,110,[]],
+cR:[function(a){return a},"call$1","gXp",2,0,null,110,[]],
+O8:[function(a){return a},"call$1","gaj",2,0,null,110,[]],
+wr:[function(a){P.Tk(this,null,this,a)},"call$1","grb",2,0,null,110,[]],
+uN:[function(a,b){return P.h8(this,null,this,a,b)},"call$2","gZq",4,0,null,159,[],110,[]],
 Ch:[function(a,b){H.qw(b)
-return},"call$1","gJS",2,0,null,173]}}],["dart.collection","dart:collection",,P,{
-"":"",
-Ou:[function(a,b){return J.de(a,b)},"call$2","iv",4,0,179,123,180],
-T9:[function(a){return J.v1(a)},"call$1","py",2,0,181,123],
+return},"call$1","gJS",2,0,null,173,[]]}}],["dart.collection","dart:collection",,P,{
+"^":"",
+Ou:[function(a,b){return J.de(a,b)},"call$2","iv",4,0,179,123,[],180,[]],
+T9:[function(a){return J.v1(a)},"call$1","py",2,0,181,123,[]],
 Py:function(a,b,c,d,e){var z
 if(a==null){z=new P.k6(0,null,null,null,null)
 z.$builtinTypeInfo=[d,e]
@@ -13284,7 +13565,7 @@
 try{P.Vr(a,z)}finally{$.xb().Rz(0,a)}y=P.p9("(")
 y.We(z,", ")
 y.KF(")")
-return y.vM},"call$1","Zw",2,0,null,109],
+return y.vM},"call$1","Zw",2,0,null,109,[]],
 Vr:[function(a,b){var z,y,x,w,v,u,t,s,r,q
 z=a.gA(a)
 y=0
@@ -13317,7 +13598,7 @@
 if(q==null){y+=5
 q="..."}}if(q!=null)b.push(q)
 b.push(u)
-b.push(v)},"call$2","zE",4,0,null,109,182],
+b.push(v)},"call$2","zE",4,0,null,109,[],182,[]],
 L5:function(a,b,c,d,e){if(b==null){if(a==null)return H.VM(new P.YB(0,null,null,null,null,null,0),[d,e])
 b=P.py()}else{if(P.J2()===b&&P.N3()===a)return H.VM(new P.ey(0,null,null,null,null,null,0),[d,e])
 if(a==null)a=P.iv()}return P.Ex(a,b,c,d,e)},
@@ -13332,9 +13613,9 @@
 J.kH(a,new P.ZQ(z,y))
 y.KF("}")}finally{z=$.tw()
 if(0>=z.length)return H.e(z,0)
-z.pop()}return y.gvM()},"call$1","DH",2,0,null,183],
+z.pop()}return y.gvM()},"call$1","DH",2,0,null,183,[]],
 k6:{
-"":"a;X5,vv,OX,OB,aw",
+"^":"a;X5,vv,OX,OB,wV",
 gB:function(a){return this.X5},
 gl0:function(a){return this.X5===0},
 gor:function(a){return this.X5!==0},
@@ -13345,11 +13626,11 @@
 return z==null?!1:z[a]!=null}else if(typeof a==="number"&&(a&0x3ffffff)===a){y=this.OX
 return y==null?!1:y[a]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42],
+return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42,[]],
 di:[function(a){var z=this.Ig()
 z.toString
-return H.Ck(z,new P.ce(this,a))},"call$1","gmc",2,0,null,23],
-FV:[function(a,b){J.kH(b,new P.DJ(this))},"call$1","gDY",2,0,null,104],
+return H.Ck(z,new P.ce(this,a))},"call$1","gmc",2,0,null,23,[]],
+FV:[function(a,b){J.kH(b,new P.DJ(this))},"call$1","gDY",2,0,null,104,[]],
 t:[function(a,b){var z,y,x,w,v,u,t
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null)y=null
@@ -13361,41 +13642,23 @@
 if(v==null)return
 u=v[this.nm(b)]
 t=this.aH(u,b)
-return t<0?null:u[t+1]}},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){var z,y,x,w,v,u,t,s
+return t<0?null:u[t+1]}},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
-if(z==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.vv=y
-z=y}if(z[b]==null){this.X5=this.X5+1
-this.aw=null}if(c==null)z[b]=z
-else z[b]=c}else if(typeof b==="number"&&(b&0x3ffffff)===b){x=this.OX
-if(x==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OX=y
-x=y}if(x[b]==null){this.X5=this.X5+1
-this.aw=null}if(c==null)x[b]=x
-else x[b]=c}else{w=this.OB
-if(w==null){y=Object.create(null)
-if(y==null)y["<non-identifier-key>"]=y
-else y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OB=y
-w=y}v=this.nm(b)
-u=w[v]
-if(u==null){t=[b,c]
-if(t==null)w[v]=w
-else w[v]=t
+if(z==null){z=P.a0()
+this.vv=z}this.dg(z,b,c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
+if(y==null){y=P.a0()
+this.OX=y}this.dg(y,b,c)}else{x=this.OB
+if(x==null){x=P.a0()
+this.OB=x}w=this.nm(b)
+v=x[w]
+if(v==null){P.cW(x,w,[b,c])
 this.X5=this.X5+1
-this.aw=null}else{s=this.aH(u,b)
-if(s>=0)u[s+1]=c
-else{u.push(b,c)
+this.wV=null}else{u=this.aH(v,b)
+if(u>=0)v[u+1]=c
+else{v.push(b,c)
 this.X5=this.X5+1
-this.aw=null}}}},"call$2","gj3",4,0,null,42,23],
+this.wV=null}}}},"call$2","gj3",4,0,null,42,[],23,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13405,9 +13668,9 @@
 x=this.aH(y,b)
 if(x<0)return
 this.X5=this.X5-1
-this.aw=null
-return y.splice(x,2)[1]}},"call$1","gRI",2,0,null,42],
-V1:[function(a){if(this.X5>0){this.aw=null
+this.wV=null
+return y.splice(x,2)[1]}},"call$1","gRI",2,0,null,42,[]],
+V1:[function(a){if(this.X5>0){this.wV=null
 this.OB=null
 this.OX=null
 this.vv=null
@@ -13416,9 +13679,9 @@
 z=this.Ig()
 for(y=z.length,x=0;x<y;++x){w=z[x]
 b.call$2(w,this.t(0,w))
-if(z!==this.aw)throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,378],
+if(z!==this.wV)throw H.b(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
 Ig:[function(){var z,y,x,w,v,u,t,s,r,q,p,o
-z=this.aw
+z=this.wV
 if(z!=null)return z
 y=Array(this.X5)
 y.fixed$length=init
@@ -13434,98 +13697,104 @@
 v=w.length
 for(t=0;t<v;++t){q=r[w[t]]
 p=q.length
-for(o=0;o<p;o+=2){y[u]=q[o];++u}}}this.aw=y
+for(o=0;o<p;o+=2){y[u]=q[o];++u}}}this.wV=y
 return y},"call$0","gtL",0,0,null],
+dg:[function(a,b,c){if(a[b]==null){this.X5=this.X5+1
+this.wV=null}P.cW(a,b,c)},"call$3","gLa",6,0,null,178,[],42,[],23,[]],
 Nv:[function(a,b){var z
 if(a!=null&&a[b]!=null){z=P.vL(a,b)
 delete a[b]
 this.X5=this.X5-1
-this.aw=null
-return z}else return},"call$2","got",4,0,null,178,42],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+this.wV=null
+return z}else return},"call$2","got",4,0,null,178,[],42,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2)if(J.de(a[y],b))return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 $isZ0:true,
 static:{vL:[function(a,b){var z=a[b]
-return z===a?null:z},"call$2","ME",4,0,null,178,42]}},
+return z===a?null:z},"call$2","ME",4,0,null,178,[],42,[]],cW:[function(a,b,c){if(c==null)a[b]=a
+else a[b]=c},"call$3","Nk",6,0,null,178,[],42,[],23,[]],a0:[function(){var z=Object.create(null)
+P.cW(z,"<non-identifier-key>",z)
+delete z["<non-identifier-key>"]
+return z},"call$0","Vd",0,0,null]}},
 oi:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 ce:{
-"":"Tp:229;a,b",
-call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 DJ:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"vP",args:[a,b]}},this.a,"k6")}},
 PL:{
-"":"k6;X5,vv,OX,OB,aw",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"k6;X5,vv,OX,OB,wV",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2){x=a[y]
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,42]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],42,[]]},
 Fq:{
-"":"k6;m6,Q6,ac,X5,vv,OX,OB,aw",
+"^":"k6;m6,Q6,ac,X5,vv,OX,OB,wV",
 C2:function(a,b){return this.m6.call$2(a,b)},
 H5:function(a){return this.Q6.call$1(a)},
 Ef:function(a){return this.ac.call$1(a)},
 t:[function(a,b){if(this.Ef(b)!==!0)return
-return P.k6.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42],
+return P.k6.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42,[]],
 x4:[function(a){if(this.Ef(a)!==!0)return!1
-return P.k6.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42],
+return P.k6.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42,[]],
 Rz:[function(a,b){if(this.Ef(b)!==!0)return
-return P.k6.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42],
-nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+return P.k6.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42,[]],
+nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;y+=2)if(this.C2(a[y],b)===!0)return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 static:{MP:function(a,b,c,d,e){var z=new P.jG(d)
 return H.VM(new P.Fq(a,b,z,0,null,null,null,null),[d,e])}}},
 jG:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 fG:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.X5},
 gl0:function(a){return this.Fb.X5===0},
 gA:function(a){var z=this.Fb
 z=new P.EQ(z,z.Ig(),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
-tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124],
+tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z,y,x,w
 z=this.Fb
 y=z.Ig()
 for(x=y.length,w=0;w<x;++w){b.call$1(y[w])
-if(y!==z.aw)throw H.b(P.a4(z))}},"call$1","gjw",2,0,null,110],
+if(y!==z.wV)throw H.b(P.a4(z))}},"call$1","gjw",2,0,null,110,[]],
 $isyN:true},
 EQ:{
-"":"a;Fb,aw,zi,fD",
+"^":"a;Fb,wV,zi,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
-z=this.aw
+z=this.wV
 y=this.zi
 x=this.Fb
-if(z!==x.aw)throw H.b(P.a4(x))
+if(z!==x.wV)throw H.b(P.a4(x))
 else if(y>=z.length){this.fD=null
 return!1}else{this.fD=z[y]
 this.zi=y+1
-return!0}},"call$0","guK",0,0,null]},
+return!0}},"call$0","gqy",0,0,null]},
 YB:{
-"":"a;X5,vv,OX,OB,H9,lX,zN",
+"^":"a;X5,vv,OX,OB,H9,lX,zN",
 gB:function(a){return this.X5},
 gl0:function(a){return this.X5===0},
 gor:function(a){return this.X5!==0},
@@ -13538,9 +13807,9 @@
 if(y==null)return!1
 return y[a]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42],
-di:[function(a){return H.VM(new P.i5(this),[H.Kp(this,0)]).Vr(0,new P.ou(this,a))},"call$1","gmc",2,0,null,23],
-FV:[function(a,b){J.kH(b,new P.S9(this))},"call$1","gDY",2,0,null,104],
+return this.aH(x[this.nm(a)],a)>=0}},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return H.VM(new P.i5(this),[H.Kp(this,0)]).Vr(0,new P.ou(this,a))},"call$1","gmc",2,0,null,23,[]],
+FV:[function(a,b){J.kH(b,new P.S9(this))},"call$1","gDY",2,0,null,104,[]],
 t:[function(a,b){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null)return
@@ -13553,38 +13822,25 @@
 v=w[this.nm(b)]
 u=this.aH(v,b)
 if(u<0)return
-return v[u].gS4()}},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){var z,y,x,w,v,u,t,s
+return v[u].gS4()}},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
-if(z==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.vv=y
-z=y}x=z[b]
-if(x==null)z[b]=this.pE(b,c)
-else x.sS4(c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){w=this.OX
-if(w==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OX=y
-w=y}x=w[b]
-if(x==null)w[b]=this.pE(b,c)
-else x.sS4(c)}else{v=this.OB
-if(v==null){y=Object.create(null)
-y["<non-identifier-key>"]=y
-delete y["<non-identifier-key>"]
-this.OB=y
-v=y}u=this.nm(b)
-t=v[u]
-if(t==null)v[u]=[this.pE(b,c)]
-else{s=this.aH(t,b)
-if(s>=0)t[s].sS4(c)
-else t.push(this.pE(b,c))}}},"call$2","gj3",4,0,null,42,23],
+if(z==null){z=P.Qs()
+this.vv=z}this.dg(z,b,c)}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
+if(y==null){y=P.Qs()
+this.OX=y}this.dg(y,b,c)}else{x=this.OB
+if(x==null){x=P.Qs()
+this.OB=x}w=this.nm(b)
+v=x[w]
+if(v==null)x[w]=[this.pE(b,c)]
+else{u=this.aH(v,b)
+if(u>=0)v[u].sS4(c)
+else v.push(this.pE(b,c))}}},"call$2","gj3",4,0,null,42,[],23,[]],
 to:[function(a,b){var z
 if(this.x4(a))return this.t(0,a)
 z=b.call$0()
 this.u(0,a,z)
-return z},"call$2","gMs",4,0,null,42,417],
+return z},"call$2","gMs",4,0,null,42,[],413,[]],
 Rz:[function(a,b){var z,y,x,w
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13595,7 +13851,7 @@
 if(x<0)return
 w=y.splice(x,1)[0]
 this.Vb(w)
-return w.gS4()}},"call$1","gRI",2,0,null,42],
+return w.gS4()}},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){if(this.X5>0){this.lX=null
 this.H9=null
 this.OB=null
@@ -13608,14 +13864,17 @@
 y=this.zN
 for(;z!=null;){b.call$2(z.gkh(),z.gS4())
 if(y!==this.zN)throw H.b(P.a4(this))
-z=z.gDG()}},"call$1","gjw",2,0,null,378],
+z=z.gDG()}},"call$1","gjw",2,0,null,371,[]],
+dg:[function(a,b,c){var z=a[b]
+if(z==null)a[b]=this.pE(b,c)
+else z.sS4(c)},"call$3","gLa",6,0,null,178,[],42,[],23,[]],
 Nv:[function(a,b){var z
 if(a==null)return
 z=a[b]
 if(z==null)return
 this.Vb(z)
 delete a[b]
-return z.gS4()},"call$2","got",4,0,null,178,42],
+return z.gS4()},"call$2","got",4,0,null,178,[],42,[]],
 pE:[function(a,b){var z,y
 z=new P.db(a,b,null,null)
 if(this.H9==null){this.lX=z
@@ -13624,7 +13883,7 @@
 y.sDG(z)
 this.lX=z}this.X5=this.X5+1
 this.zN=this.zN+1&67108863
-return z},"call$2","gTM",4,0,null,42,23],
+return z},"call$2","gTM",4,0,null,42,[],23,[]],
 Vb:[function(a){var z,y
 z=a.gzQ()
 y=a.gDG()
@@ -13633,65 +13892,69 @@
 if(y==null)this.lX=z
 else y.szQ(z)
 this.X5=this.X5-1
-this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,418],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,414,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y].gkh(),b))return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 $isFo:true,
-$isZ0:true},
+$isZ0:true,
+static:{Qs:[function(){var z=Object.create(null)
+z["<non-identifier-key>"]=z
+delete z["<non-identifier-key>"]
+return z},"call$0","Bs",0,0,null]}},
 a1:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.t(0,a)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 ou:{
-"":"Tp:229;a,b",
-call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,416,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return J.de(this.a.t(0,a),this.b)},"call$1",null,2,0,null,412,[],"call"],
 $isEH:true},
 S9:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"oK",args:[a,b]}},this.a,"YB")}},
 ey:{
-"":"YB;X5,vv,OX,OB,H9,lX,zN",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"YB;X5,vv,OX,OB,H9,lX,zN",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y){x=a[y].gkh()
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,42]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],42,[]]},
 xd:{
-"":"YB;m6,Q6,ac,X5,vv,OX,OB,H9,lX,zN",
+"^":"YB;m6,Q6,ac,X5,vv,OX,OB,H9,lX,zN",
 C2:function(a,b){return this.m6.call$2(a,b)},
 H5:function(a){return this.Q6.call$1(a)},
 Ef:function(a){return this.ac.call$1(a)},
 t:[function(a,b){if(this.Ef(b)!==!0)return
-return P.YB.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42],
+return P.YB.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,42,[]],
 x4:[function(a){if(this.Ef(a)!==!0)return!1
-return P.YB.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42],
+return P.YB.prototype.x4.call(this,a)},"call$1","gV9",2,0,null,42,[]],
 Rz:[function(a,b){if(this.Ef(b)!==!0)return
-return P.YB.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42],
-nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+return P.YB.prototype.Rz.call(this,this,b)},"call$1","gRI",2,0,null,42,[]],
+nm:[function(a){return this.H5(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(this.C2(a[y].gkh(),b)===!0)return y
-return-1},"call$2","gSP",4,0,null,415,42],
+return-1},"call$2","gSP",4,0,null,411,[],42,[]],
 static:{Ex:function(a,b,c,d,e){var z=new P.v6(d)
 return H.VM(new P.xd(a,b,z,0,null,null,null,null,null,0),[d,e])}}},
 v6:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 db:{
-"":"a;kh<,S4@,DG@,zQ@"},
+"^":"a;kh<,S4@,DG@,zQ@"},
 i5:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.X5},
 gl0:function(a){return this.Fb.X5===0},
 gA:function(a){var z,y
@@ -13700,17 +13963,17 @@
 y.$builtinTypeInfo=this.$builtinTypeInfo
 y.zq=z.H9
 return y},
-tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124],
+tg:[function(a,b){return this.Fb.x4(b)},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z,y,x
 z=this.Fb
 y=z.H9
 x=z.zN
 for(;y!=null;){b.call$1(y.gkh())
 if(x!==z.zN)throw H.b(P.a4(z))
-y=y.gDG()}},"call$1","gjw",2,0,null,110],
+y=y.gDG()}},"call$1","gjw",2,0,null,110,[]],
 $isyN:true},
 N6:{
-"":"a;Fb,zN,zq,fD",
+"^":"a;Fb,zN,zq,fD",
 gl:function(){return this.fD},
 G:[function(){var z=this.Fb
 if(this.zN!==z.zN)throw H.b(P.a4(z))
@@ -13718,9 +13981,9 @@
 if(z==null){this.fD=null
 return!1}else{this.fD=z.gkh()
 this.zq=this.zq.gDG()
-return!0}}},"call$0","guK",0,0,null]},
+return!0}}},"call$0","gqy",0,0,null]},
 Rr:{
-"":"lN;",
+"^":"lN;",
 gA:function(a){var z=new P.oz(this,this.Zl(),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
@@ -13732,7 +13995,7 @@
 return z==null?!1:z[b]!=null}else if(typeof b==="number"&&(b&0x3ffffff)===b){y=this.OX
 return y==null?!1:y[b]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6],
+return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6,[]],
 Zt:[function(a){var z,y,x,w
 if(!(typeof a==="string"&&a!=="__proto__"))z=typeof a==="number"&&(a&0x3ffffff)===a
 else z=!0
@@ -13742,7 +14005,7 @@
 x=y[this.nm(a)]
 w=this.aH(x,a)
 if(w<0)return
-return J.UQ(x,w)},"call$1","gQB",2,0,null,6],
+return J.UQ(x,w)},"call$1","gQB",2,0,null,6,[]],
 h:[function(a,b){var z,y,x,w,v,u
 if(typeof b==="string"&&b!=="__proto__"){z=this.vv
 if(z==null){y=Object.create(null)
@@ -13765,9 +14028,9 @@
 else{if(this.aH(u,b)>=0)return!1
 u.push(b)}this.X5=this.X5+1
 this.DM=null
-return!0}},"call$1","ght",2,0,null,124],
+return!0}},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,419],
+for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,415,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13779,7 +14042,7 @@
 this.X5=this.X5-1
 this.DM=null
 y.splice(x,1)
-return!0}},"call$1","gRI",2,0,null,6],
+return!0}},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){if(this.X5>0){this.DM=null
 this.OB=null
 this.OX=null
@@ -13808,30 +14071,30 @@
 a[b]=0
 this.X5=this.X5+1
 this.DM=null
-return!0},"call$2","gLa",4,0,null,178,124],
+return!0},"call$2","gLa",4,0,null,178,[],124,[]],
 Nv:[function(a,b){if(a!=null&&a[b]!=null){delete a[b]
 this.X5=this.X5-1
 this.DM=null
-return!0}else return!1},"call$2","got",4,0,null,178,124],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124],
+return!0}else return!1},"call$2","got",4,0,null,178,[],124,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y],b))return y
-return-1},"call$2","gSP",4,0,null,415,124],
+return-1},"call$2","gSP",4,0,null,411,[],124,[]],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 YO:{
-"":"Rr;X5,vv,OX,OB,DM",
-nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42],
+"^":"Rr;X5,vv,OX,OB,DM",
+nm:[function(a){return H.CU(a)&0x3ffffff},"call$1","gtU",2,0,null,42,[]],
 aH:[function(a,b){var z,y,x
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y){x=a[y]
-if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,415,124]},
+if(x==null?b==null:x===b)return y}return-1},"call$2","gSP",4,0,null,411,[],124,[]]},
 oz:{
-"":"a;O2,DM,zi,fD",
+"^":"a;O2,DM,zi,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
 z=this.DM
@@ -13841,9 +14104,9 @@
 else if(y>=z.length){this.fD=null
 return!1}else{this.fD=z[y]
 this.zi=y+1
-return!0}},"call$0","guK",0,0,null]},
+return!0}},"call$0","gqy",0,0,null]},
 b6:{
-"":"lN;X5,vv,OX,OB,H9,lX,zN",
+"^":"lN;X5,vv,OX,OB,H9,lX,zN",
 gA:function(a){var z=H.VM(new P.zQ(this,this.zN,null,null),[null])
 z.zq=z.O2.H9
 return z},
@@ -13857,7 +14120,7 @@
 if(y==null)return!1
 return y[b]!=null}else{x=this.OB
 if(x==null)return!1
-return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6],
+return this.aH(x[this.nm(b)],b)>=0}},"call$1","gdj",2,0,null,6,[]],
 Zt:[function(a){var z,y,x,w
 if(!(typeof a==="string"&&a!=="__proto__"))z=typeof a==="number"&&(a&0x3ffffff)===a
 else z=!0
@@ -13867,13 +14130,13 @@
 x=y[this.nm(a)]
 w=this.aH(x,a)
 if(w<0)return
-return J.UQ(x,w).gGc()}},"call$1","gQB",2,0,null,6],
+return J.UQ(x,w).gGc()}},"call$1","gQB",2,0,null,6,[]],
 aN:[function(a,b){var z,y
 z=this.H9
 y=this.zN
 for(;z!=null;){b.call$1(z.gGc())
 if(y!==this.zN)throw H.b(P.a4(this))
-z=z.gDG()}},"call$1","gjw",2,0,null,378],
+z=z.gDG()}},"call$1","gjw",2,0,null,371,[]],
 grZ:function(a){var z=this.lX
 if(z==null)throw H.b(new P.lj("No elements"))
 return z.gGc()},
@@ -13897,9 +14160,9 @@
 u=w[v]
 if(u==null)w[v]=[this.xf(b)]
 else{if(this.aH(u,b)>=0)return!1
-u.push(this.xf(b))}return!0}},"call$1","ght",2,0,null,124],
+u.push(this.xf(b))}return!0}},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z
-for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,419],
+for(z=J.GP(b);z.G();)this.h(0,z.gl())},"call$1","gDY",2,0,null,415,[]],
 Rz:[function(a,b){var z,y,x
 if(typeof b==="string"&&b!=="__proto__")return this.Nv(this.vv,b)
 else if(typeof b==="number"&&(b&0x3ffffff)===b)return this.Nv(this.OX,b)
@@ -13909,7 +14172,7 @@
 x=this.aH(y,b)
 if(x<0)return!1
 this.Vb(y.splice(x,1)[0])
-return!0}},"call$1","gRI",2,0,null,6],
+return!0}},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){if(this.X5>0){this.lX=null
 this.H9=null
 this.OB=null
@@ -13919,14 +14182,14 @@
 this.zN=this.zN+1&67108863}},"call$0","gyP",0,0,null],
 cA:[function(a,b){if(a[b]!=null)return!1
 a[b]=this.xf(b)
-return!0},"call$2","gLa",4,0,null,178,124],
+return!0},"call$2","gLa",4,0,null,178,[],124,[]],
 Nv:[function(a,b){var z
 if(a==null)return!1
 z=a[b]
 if(z==null)return!1
 this.Vb(z)
 delete a[b]
-return!0},"call$2","got",4,0,null,178,124],
+return!0},"call$2","got",4,0,null,178,[],124,[]],
 xf:[function(a){var z,y
 z=new P.ef(a,null,null)
 if(this.H9==null){this.lX=z
@@ -13935,7 +14198,7 @@
 y.sDG(z)
 this.lX=z}this.X5=this.X5+1
 this.zN=this.zN+1&67108863
-return z},"call$1","gTM",2,0,null,124],
+return z},"call$1","gTM",2,0,null,124,[]],
 Vb:[function(a){var z,y
 z=a.gzQ()
 y=a.gDG()
@@ -13944,20 +14207,20 @@
 if(y==null)this.lX=z
 else y.szQ(z)
 this.X5=this.X5-1
-this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,418],
-nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124],
+this.zN=this.zN+1&67108863},"call$1","glZ",2,0,null,414,[]],
+nm:[function(a){return J.v1(a)&0x3ffffff},"call$1","gtU",2,0,null,124,[]],
 aH:[function(a,b){var z,y
 if(a==null)return-1
 z=a.length
 for(y=0;y<z;++y)if(J.de(a[y].gGc(),b))return y
-return-1},"call$2","gSP",4,0,null,415,124],
+return-1},"call$2","gSP",4,0,null,411,[],124,[]],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 ef:{
-"":"a;Gc<,DG@,zQ@"},
+"^":"a;Gc<,DG@,zQ@"},
 zQ:{
-"":"a;O2,zN,zq,fD",
+"^":"a;O2,zN,zq,fD",
 gl:function(){return this.fD},
 G:[function(){var z=this.O2
 if(this.zN!==z.zN)throw H.b(P.a4(z))
@@ -13965,13 +14228,13 @@
 if(z==null){this.fD=null
 return!1}else{this.fD=z.gGc()
 this.zq=this.zq.gDG()
-return!0}}},"call$0","guK",0,0,null]},
+return!0}}},"call$0","gqy",0,0,null]},
 Yp:{
-"":"Iy;G4",
+"^":"w2Y;G4",
 gB:function(a){return J.q8(this.G4)},
-t:[function(a,b){return J.i4(this.G4,b)},"call$1","gIA",2,0,null,47]},
+t:[function(a,b){return J.i4(this.G4,b)},"call$1","gIA",2,0,null,47,[]]},
 lN:{
-"":"mW;",
+"^":"mW;",
 tt:[function(a,b){var z,y,x,w,v
 if(b){z=H.VM([],[H.Kp(this,0)])
 C.Nm.sB(z,this.gB(this))}else{y=Array(this.gB(this))
@@ -13979,20 +14242,20 @@
 z=H.VM(y,[H.Kp(this,0)])}for(y=this.gA(this),x=0;y.G();x=v){w=y.gl()
 v=x+1
 if(x>=z.length)return H.e(z,x)
-z[x]=w}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=w}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 bu:[function(a){return H.mx(this,"{","}")},"call$0","gXo",0,0,null],
 $isyN:true,
 $iscX:true,
 $ascX:null},
 mW:{
-"":"a;",
-ez:[function(a,b){return H.K1(this,b,H.ip(this,"mW",0),null)},"call$1","gIr",2,0,null,110],
-ev:[function(a,b){return H.VM(new H.U5(this,b),[H.ip(this,"mW",0)])},"call$1","gIR",2,0,null,110],
+"^":"a;",
+ez:[function(a,b){return H.K1(this,b,H.ip(this,"mW",0),null)},"call$1","gIr",2,0,null,110,[]],
+ev:[function(a,b){return H.VM(new H.U5(this,b),[H.ip(this,"mW",0)])},"call$1","gIR",2,0,null,110,[]],
 tg:[function(a,b){var z
 for(z=this.gA(this);z.G();)if(J.de(z.gl(),b))return!0
-return!1},"call$1","gdj",2,0,null,124],
+return!1},"call$1","gdj",2,0,null,124,[]],
 aN:[function(a,b){var z
-for(z=this.gA(this);z.G();)b.call$1(z.gl())},"call$1","gjw",2,0,null,110],
+for(z=this.gA(this);z.G();)b.call$1(z.gl())},"call$1","gjw",2,0,null,110,[]],
 zV:[function(a,b){var z,y,x
 z=this.gA(this)
 if(!z.G())return""
@@ -14002,21 +14265,18 @@
 else{y.KF(H.d(z.gl()))
 for(;z.G();){y.vM=y.vM+b
 x=H.d(z.gl())
-y.vM=y.vM+x}}return y.vM},"call$1","gnr",0,2,null,334,335],
+y.vM=y.vM+x}}return y.vM},"call$1","gnr",0,2,null,328,329,[]],
 Vr:[function(a,b){var z
 for(z=this.gA(this);z.G();)if(b.call$1(z.gl())===!0)return!0
-return!1},"call$1","gG2",2,0,null,110],
-tt:[function(a,b){return P.F(this,b,H.ip(this,"mW",0))},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+return!1},"call$1","gG2",2,0,null,110,[]],
+tt:[function(a,b){return P.F(this,b,H.ip(this,"mW",0))},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 gB:function(a){var z,y
 z=this.gA(this)
 for(y=0;z.G();)++y
 return y},
 gl0:function(a){return!this.gA(this).G()},
 gor:function(a){return this.gl0(this)!==!0},
-eR:[function(a,b){return H.ke(this,b,H.ip(this,"mW",0))},"call$1","gVQ",2,0,null,292],
-gtH:function(a){var z=this.gA(this)
-if(!z.G())throw H.b(new P.lj("No elements"))
-return z.gl()},
+eR:[function(a,b){return H.ke(this,b,H.ip(this,"mW",0))},"call$1","gZo",2,0,null,287,[]],
 grZ:function(a){var z,y
 z=this.gA(this)
 if(!z.G())throw H.b(new P.lj("No elements"))
@@ -14025,72 +14285,60 @@
 return y},
 qA:[function(a,b,c){var z,y
 for(z=this.gA(this);z.G();){y=z.gl()
-if(b.call$1(y)===!0)return y}throw H.b(new P.lj("No matching element"))},function(a,b){return this.qA(a,b,null)},"XG","call$2$orElse",null,"gyo",2,3,null,77,379,420],
+if(b.call$1(y)===!0)return y}throw H.b(new P.lj("No matching element"))},function(a,b){return this.qA(a,b,null)},"XG","call$2$orElse",null,"gyo",2,3,null,77,372,[],416,[]],
 Zv:[function(a,b){var z,y,x,w
 if(typeof b!=="number"||Math.floor(b)!==b||b<0)throw H.b(P.N(b))
 for(z=this.gA(this),y=b;z.G();){x=z.gl()
 w=J.x(y)
 if(w.n(y,0))return x
-y=w.W(y,1)}throw H.b(P.N(b))},"call$1","goY",2,0,null,47],
+y=w.W(y,1)}throw H.b(P.N(b))},"call$1","goY",2,0,null,47,[]],
 bu:[function(a){return P.FO(this)},"call$0","gXo",0,0,null],
 $iscX:true,
 $ascX:null},
 ar:{
-"":"a+lD;",
+"^":"a+lD;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 lD:{
-"":"a;",
+"^":"a;",
 gA:function(a){return H.VM(new H.a7(a,this.gB(a),0,null),[H.ip(a,"lD",0)])},
-Zv:[function(a,b){return this.t(a,b)},"call$1","goY",2,0,null,47],
+Zv:[function(a,b){return this.t(a,b)},"call$1","goY",2,0,null,47,[]],
 aN:[function(a,b){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){b.call$1(this.t(a,y))
-if(z!==this.gB(a))throw H.b(P.a4(a))}},"call$1","gjw",2,0,null,378],
+if(z!==this.gB(a))throw H.b(P.a4(a))}},"call$1","gjw",2,0,null,371,[]],
 gl0:function(a){return J.de(this.gB(a),0)},
 gor:function(a){return!this.gl0(a)},
 grZ:function(a){if(J.de(this.gB(a),0))throw H.b(new P.lj("No elements"))
 return this.t(a,J.xH(this.gB(a),1))},
-tg:[function(a,b){var z,y
+tg:[function(a,b){var z,y,x,w
 z=this.gB(a)
-if(typeof z!=="number")return H.s(z)
-y=0
-for(;y<z;++y){if(J.de(this.t(a,y),b))return!0
-if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gdj",2,0,null,124],
+y=J.x(z)
+x=0
+while(!0){w=this.gB(a)
+if(typeof w!=="number")return H.s(w)
+if(!(x<w))break
+if(J.de(this.t(a,x),b))return!0
+if(!y.n(z,this.gB(a)))throw H.b(P.a4(a));++x}return!1},"call$1","gdj",2,0,null,124,[]],
 Vr:[function(a,b){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 y=0
 for(;y<z;++y){if(b.call$1(this.t(a,y))===!0)return!0
-if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gG2",2,0,null,379],
-zV:[function(a,b){var z,y,x,w,v,u
-z=this.gB(a)
-if(b.length!==0){y=J.x(z)
-if(y.n(z,0))return""
-x=H.d(this.t(a,0))
-if(!y.n(z,this.gB(a)))throw H.b(P.a4(a))
-w=P.p9(x)
-if(typeof z!=="number")return H.s(z)
-v=1
-for(;v<z;++v){w.vM=w.vM+b
-u=this.t(a,v)
-u=typeof u==="string"?u:H.d(u)
-w.vM=w.vM+u
-if(z!==this.gB(a))throw H.b(P.a4(a))}return w.vM}else{w=P.p9("")
-if(typeof z!=="number")return H.s(z)
-v=0
-for(;v<z;++v){u=this.t(a,v)
-u=typeof u==="string"?u:H.d(u)
-w.vM=w.vM+u
-if(z!==this.gB(a))throw H.b(P.a4(a))}return w.vM}},"call$1","gnr",0,2,null,334,335],
-ev:[function(a,b){return H.VM(new H.U5(a,b),[H.ip(a,"lD",0)])},"call$1","gIR",2,0,null,379],
-ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110],
-eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gVQ",2,0,null,122],
+if(z!==this.gB(a))throw H.b(P.a4(a))}return!1},"call$1","gG2",2,0,null,372,[]],
+zV:[function(a,b){var z
+if(J.de(this.gB(a),0))return""
+z=P.p9("")
+z.We(a,b)
+return z.vM},"call$1","gnr",0,2,null,328,329,[]],
+ev:[function(a,b){return H.VM(new H.U5(a,b),[H.ip(a,"lD",0)])},"call$1","gIR",2,0,null,372,[]],
+ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"call$1","gIr",2,0,null,110,[]],
+eR:[function(a,b){return H.j5(a,b,null,null)},"call$1","gZo",2,0,null,122,[]],
 tt:[function(a,b){var z,y,x
 if(b){z=H.VM([],[H.ip(a,"lD",0)])
 C.Nm.sB(z,this.gB(a))}else{y=this.gB(a)
@@ -14103,15 +14351,15 @@
 if(!(x<y))break
 y=this.t(a,x)
 if(x>=z.length)return H.e(z,x)
-z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+z[x]=y;++x}return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 h:[function(a,b){var z=this.gB(a)
 this.sB(a,J.WB(z,1))
-this.u(a,z,b)},"call$1","ght",2,0,null,124],
+this.u(a,z,b)},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z,y,x
 for(z=J.GP(b);z.G();){y=z.gl()
 x=this.gB(a)
 this.sB(a,J.WB(x,1))
-this.u(a,x,y)}},"call$1","gDY",2,0,null,109],
+this.u(a,x,y)}},"call$1","gDY",2,0,null,109,[]],
 Rz:[function(a,b){var z,y
 z=0
 while(!0){y=this.gB(a)
@@ -14119,13 +14367,13 @@
 if(!(z<y))break
 if(J.de(this.t(a,z),b)){this.YW(a,z,J.xH(this.gB(a),1),a,z+1)
 this.sB(a,J.xH(this.gB(a),1))
-return!0}++z}return!1},"call$1","gRI",2,0,null,124],
+return!0}++z}return!1},"call$1","gRI",2,0,null,124,[]],
 V1:[function(a){this.sB(a,0)},"call$0","gyP",0,0,null],
-So:[function(a,b){H.ZE(a,0,J.xH(this.gB(a),1),b)},"call$1","gH7",0,2,null,77,128],
+GT:[function(a,b){H.ZE(a,0,J.xH(this.gB(a),1),b)},"call$1","gH7",0,2,null,77,128,[]],
 pZ:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.D(b,this.gB(a)))throw H.b(P.TE(b,0,this.gB(a)))
 z=J.Wx(c)
-if(z.C(c,b)||z.D(c,this.gB(a)))throw H.b(P.TE(c,b,this.gB(a)))},"call$2","gbI",4,0,null,115,116],
+if(z.C(c,b)||z.D(c,this.gB(a)))throw H.b(P.TE(c,b,this.gB(a)))},"call$2","gbI",4,0,null,115,[],116,[]],
 D6:[function(a,b,c){var z,y,x,w
 if(c==null)c=this.gB(a)
 this.pZ(a,b,c)
@@ -14136,25 +14384,26 @@
 x=0
 for(;x<z;++x){w=this.t(a,b+x)
 if(x>=y.length)return H.e(y,x)
-y[x]=w}return y},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+y[x]=w}return y},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
 Mu:[function(a,b,c){this.pZ(a,b,c)
-return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,116],
+return H.j5(a,b,c,null)},"call$2","gYf",4,0,null,115,[],116,[]],
 YW:[function(a,b,c,d,e){var z,y,x,w
-z=this.gB(a)
+if(b>=0){z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
-z=b>z
+z=b>z}else z=!0
 if(z)H.vh(P.TE(b,0,this.gB(a)))
 z=J.Wx(c)
 if(z.C(c,b)||z.D(c,this.gB(a)))H.vh(P.TE(c,b,this.gB(a)))
 y=z.W(c,b)
 if(J.de(y,0))return
+if(e<0)throw H.b(new P.AT(e))
 if(typeof y!=="number")return H.s(y)
 z=J.U6(d)
 x=z.gB(d)
 if(typeof x!=="number")return H.s(x)
 if(e+y>x)throw H.b(new P.lj("Not enough elements"))
 if(e<b)for(w=y-1;w>=0;--w)this.u(a,b+w,z.t(d,e+w))
-else for(w=0;w<y;++w)this.u(a,b+w,z.t(d,e+w))},"call$4","gam",6,2,null,336,115,116,109,117],
+else for(w=0;w<y;++w)this.u(a,b+w,z.t(d,e+w))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 XU:[function(a,b,c){var z,y
 z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
@@ -14163,11 +14412,24 @@
 while(!0){z=this.gB(a)
 if(typeof z!=="number")return H.s(z)
 if(!(y<z))break
-if(J.de(this.t(a,y),b))return y;++y}return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,336,124,80],
+if(J.de(this.t(a,y),b))return y;++y}return-1},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],80,[]],
 Pk:[function(a,b,c){var z,y
 c=J.xH(this.gB(a),1)
 for(z=c;y=J.Wx(z),y.F(z,0);z=y.W(z,1))if(J.de(this.t(a,z),b))return z
-return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gkl",2,2,null,77,124,80],
+return-1},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],80,[]],
+xe:[function(a,b,c){var z
+if(b>=0){z=this.gB(a)
+if(typeof z!=="number")return H.s(z)
+z=b>z}else z=!0
+if(z)throw H.b(P.TE(b,0,this.gB(a)))
+if(b===this.gB(a)){this.h(a,c)
+return}this.sB(a,J.WB(this.gB(a),1))
+this.YW(a,b+1,this.gB(a),a,b)
+this.u(a,b,c)},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){var z=this.t(a,b)
+this.YW(a,b,J.xH(this.gB(a),1),a,b+1)
+this.sB(a,J.xH(this.gB(a),1))
+return z},"call$1","gNM",2,0,null,47,[]],
 bu:[function(a){var z
 if($.xb().tg(0,a))return"[...]"
 z=P.p9("")
@@ -14181,34 +14443,34 @@
 $iscX:true,
 $ascX:null},
 ZQ:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.a
 if(!z.a)this.b.KF(", ")
 z.a=!1
 z=this.b
 z.KF(a)
 z.KF(": ")
-z.KF(b)},"call$2",null,4,0,null,421,277,"call"],
+z.KF(b)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 Sw:{
-"":"mW;v5,av,HV,qT",
-gA:function(a){var z=new P.o0(this,this.HV,this.qT,this.av,null)
+"^":"mW;v5,av,eZ,qT",
+gA:function(a){var z=new P.o0(this,this.eZ,this.qT,this.av,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
 aN:[function(a,b){var z,y,x
 z=this.qT
-for(y=this.av;y!==this.HV;y=(y+1&this.v5.length-1)>>>0){x=this.v5
+for(y=this.av;y!==this.eZ;y=(y+1&this.v5.length-1)>>>0){x=this.v5
 if(y<0||y>=x.length)return H.e(x,y)
 b.call$1(x[y])
-if(z!==this.qT)H.vh(P.a4(this))}},"call$1","gjw",2,0,null,378],
-gl0:function(a){return this.av===this.HV},
-gB:function(a){return J.KV(J.xH(this.HV,this.av),this.v5.length-1)},
+if(z!==this.qT)H.vh(P.a4(this))}},"call$1","gjw",2,0,null,371,[]],
+gl0:function(a){return this.av===this.eZ},
+gB:function(a){return J.mQ(J.xH(this.eZ,this.av),this.v5.length-1)},
 grZ:function(a){var z,y
 z=this.av
-y=this.HV
+y=this.eZ
 if(z===y)throw H.b(new P.lj("No elements"))
 z=this.v5
-y=J.KV(J.xH(y,1),this.v5.length-1)
+y=J.mQ(J.xH(y,1),this.v5.length-1)
 if(y>=z.length)return H.e(z,y)
 return z[y]},
 Zv:[function(a,b){var z,y,x
@@ -14220,14 +14482,14 @@
 x=z.length
 y=(y+b&x-1)>>>0
 if(y<0||y>=x)return H.e(z,y)
-return z[y]},"call$1","goY",2,0,null,47],
+return z[y]},"call$1","goY",2,0,null,47,[]],
 tt:[function(a,b){var z,y
 if(b){z=H.VM([],[H.Kp(this,0)])
 C.Nm.sB(z,this.gB(this))}else{y=Array(this.gB(this))
 y.fixed$length=init
 z=H.VM(y,[H.Kp(this,0)])}this.e4(z)
-return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
-h:[function(a,b){this.NZ(0,b)},"call$1","ght",2,0,null,124],
+return z},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
+h:[function(a,b){this.NZ(0,b)},"call$1","ght",2,0,null,124,[]],
 FV:[function(a,b){var z,y,x,w,v,u,t,s,r
 z=J.x(b)
 if(typeof b==="object"&&b!==null&&(b.constructor===Array||!!z.$isList)){y=z.gB(b)
@@ -14241,131 +14503,128 @@
 w=Array(u)
 w.fixed$length=init
 t=H.VM(w,[H.Kp(this,0)])
-this.HV=this.e4(t)
+this.eZ=this.e4(t)
 this.v5=t
 this.av=0
-H.qG(t,x,z,b,0)
-this.HV=J.WB(this.HV,y)}else{z=this.HV
+H.Og(t,x,z,b,0)
+this.eZ=J.WB(this.eZ,y)}else{z=this.eZ
 if(typeof z!=="number")return H.s(z)
 s=v-z
-if(y<s){H.qG(w,z,z+y,b,0)
-this.HV=J.WB(this.HV,y)}else{r=y-s
-H.qG(w,z,z+s,b,0)
+if(y<s){H.Og(w,z,z+y,b,0)
+this.eZ=J.WB(this.eZ,y)}else{r=y-s
+H.Og(w,z,z+s,b,0)
 z=this.v5
-H.qG(z,0,r,b,s)
-this.HV=r}}this.qT=this.qT+1}else for(z=z.gA(b);z.G();)this.NZ(0,z.gl())},"call$1","gDY",2,0,null,422],
+H.Og(z,0,r,b,s)
+this.eZ=r}}this.qT=this.qT+1}else for(z=z.gA(b);z.G();)this.NZ(0,z.gl())},"call$1","gDY",2,0,null,418,[]],
 Rz:[function(a,b){var z,y
-for(z=this.av;z!==this.HV;z=(z+1&this.v5.length-1)>>>0){y=this.v5
+for(z=this.av;z!==this.eZ;z=(z+1&this.v5.length-1)>>>0){y=this.v5
 if(z<0||z>=y.length)return H.e(y,z)
 if(J.de(y[z],b)){this.bB(z)
 this.qT=this.qT+1
-return!0}}return!1},"call$1","gRI",2,0,null,6],
+return!0}}return!1},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){var z,y,x,w,v
 z=this.av
-y=this.HV
+y=this.eZ
 if(z!==y){for(x=this.v5,w=x.length,v=w-1;z!==y;z=(z+1&v)>>>0){if(z<0||z>=w)return H.e(x,z)
-x[z]=null}this.HV=0
+x[z]=null}this.eZ=0
 this.av=0
 this.qT=this.qT+1}},"call$0","gyP",0,0,null],
 bu:[function(a){return H.mx(this,"{","}")},"call$0","gXo",0,0,null],
-Ux:[function(){var z,y,x,w
-z=this.av
-if(z===this.HV)throw H.b(P.w("No elements"))
-this.qT=this.qT+1
-y=this.v5
-x=y.length
-if(z>=x)return H.e(y,z)
-w=y[z]
-this.av=(z+1&x-1)>>>0
-return w},"call$0","gdm",0,0,null],
-NZ:[function(a,b){var z,y,x,w
+NZ:[function(a,b){var z,y
 z=this.v5
-y=this.HV
+y=this.eZ
 if(y>>>0!==y||y>=z.length)return H.e(z,y)
 z[y]=b
 y=(y+1&this.v5.length-1)>>>0
-this.HV=y
-if(this.av===y){x=Array(this.v5.length*2)
-x.fixed$length=init
-x.$builtinTypeInfo=[H.Kp(this,0)]
-z=this.v5
-y=this.av
-w=z.length-y
-H.qG(x,0,w,z,y)
-z=this.av
-y=this.v5
-H.qG(x,w,w+z,y,0)
-this.av=0
-this.HV=this.v5.length
-this.v5=x}this.qT=this.qT+1},"call$1","gXk",2,0,null,124],
+this.eZ=y
+if(this.av===y)this.VW()
+this.qT=this.qT+1},"call$1","gXk",2,0,null,124,[]],
 bB:[function(a){var z,y,x,w,v,u,t,s
 z=this.v5.length-1
-if((a-this.av&z)>>>0<J.KV(J.xH(this.HV,a),z)){for(y=this.av,x=this.v5,w=x.length,v=a;v!==y;v=u){u=(v-1&z)>>>0
+if((a-this.av&z)>>>0<J.mQ(J.xH(this.eZ,a),z)){for(y=this.av,x=this.v5,w=x.length,v=a;v!==y;v=u){u=(v-1&z)>>>0
 if(u<0||u>=w)return H.e(x,u)
 t=x[u]
 if(v<0||v>=w)return H.e(x,v)
 x[v]=t}if(y>=w)return H.e(x,y)
 x[y]=null
 this.av=(y+1&z)>>>0
-return(a+1&z)>>>0}else{y=J.KV(J.xH(this.HV,1),z)
-this.HV=y
+return(a+1&z)>>>0}else{y=J.mQ(J.xH(this.eZ,1),z)
+this.eZ=y
 for(x=this.v5,w=x.length,v=a;v!==y;v=s){s=(v+1&z)>>>0
 if(s<0||s>=w)return H.e(x,s)
 t=x[s]
 if(v<0||v>=w)return H.e(x,v)
 x[v]=t}if(y>=w)return H.e(x,y)
 x[y]=null
-return a}},"call$1","gzv",2,0,null,423],
+return a}},"call$1","gzv",2,0,null,419,[]],
+VW:[function(){var z,y,x,w
+z=Array(this.v5.length*2)
+z.fixed$length=init
+y=H.VM(z,[H.Kp(this,0)])
+z=this.v5
+x=this.av
+w=z.length-x
+H.Og(y,0,w,z,x)
+z=this.av
+x=this.v5
+H.Og(y,w,w+z,x,0)
+this.av=0
+this.eZ=this.v5.length
+this.v5=y},"call$0","gJm",0,0,null],
 e4:[function(a){var z,y,x,w
 z=this.av
-y=this.HV
+y=this.eZ
 if(typeof y!=="number")return H.s(y)
 if(z<=y){x=y-z
 z=this.v5
 y=this.av
-H.qG(a,0,x,z,y)
+H.Og(a,0,x,z,y)
 return x}else{y=this.v5
 w=y.length-z
-H.qG(a,0,w,y,z)
-z=this.HV
+H.Og(a,0,w,y,z)
+z=this.eZ
 if(typeof z!=="number")return H.s(z)
 y=this.v5
-H.qG(a,w,w+z,y,0)
-return J.WB(this.HV,w)}},"call$1","gLR",2,0,null,74],
-Eo:function(a,b){var z=Array(8)
+H.Og(a,w,w+z,y,0)
+return J.WB(this.eZ,w)}},"call$1","gLR",2,0,null,74,[]],
+Eo:function(a,b){var z
+if(typeof 8!=="number")return H.s(8)
+z=Array(8)
 z.fixed$length=init
 this.v5=H.VM(z,[b])},
 $isyN:true,
 $iscX:true,
 $ascX:null,
-static:{"":"Mo",ua:[function(a){var z
+static:{"^":"Mo",NZ:function(a,b){var z=H.VM(new P.Sw(null,0,0,0),[b])
+z.Eo(a,b)
+return z},ua:[function(a){var z
 if(typeof a!=="number")return a.O()
 a=(a<<2>>>0)-1
 for(;!0;a=z){z=(a&a-1)>>>0
-if(z===0)return a}},"call$1","bD",2,0,null,184]}},
+if(z===0)return a}},"call$1","W5",2,0,null,184,[]]}},
 o0:{
-"":"a;Lz,dP,qT,Dc,fD",
+"^":"a;Lz,pP,qT,Dc,fD",
 gl:function(){return this.fD},
 G:[function(){var z,y,x
 z=this.Lz
 if(this.qT!==z.qT)H.vh(P.a4(z))
 y=this.Dc
-if(y===this.dP){this.fD=null
+if(y===this.pP){this.fD=null
 return!1}z=z.v5
 x=z.length
 if(y>=x)return H.e(z,y)
 this.fD=z[y]
 this.Dc=(y+1&x-1)>>>0
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 qv:{
-"":"a;G3>,Bb>,T8>",
+"^":"a;G3>,Bb<,T8<",
 $isqv:true},
 jp:{
-"":"qv;P*,G3,Bb,T8",
+"^":"qv;P*,G3,Bb,T8",
 r6:function(a,b){return this.P.call$1(b)},
 $asqv:function(a,b){return[a]}},
 vX:{
-"":"a;",
+"^":"a;",
 vh:[function(a){var z,y,x,w,v,u,t,s
 z=this.aY
 if(z==null)return-1
@@ -14400,10 +14659,10 @@
 y.T8=null
 y.Bb=null
 this.bb=this.bb+1
-return v},"call$1","gST",2,0,null,42],
+return v},"call$1","gST",2,0,null,42,[]],
 Xu:[function(a){var z,y
 for(z=a;y=z.T8,y!=null;z=y){z.T8=y.Bb
-y.Bb=z}return z},"call$1","gOv",2,0,null,265],
+y.Bb=z}return z},"call$1","gOv",2,0,null,259,[]],
 bB:[function(a){var z,y,x
 if(this.aY==null)return
 if(!J.de(this.vh(a),0))return
@@ -14415,8 +14674,8 @@
 else{y=this.Xu(y)
 this.aY=y
 y.T8=x}this.qT=this.qT+1
-return z},"call$1","gzv",2,0,null,42],
-K8:[function(a,b){var z,y
+return z},"call$1","gzv",2,0,null,42,[]],
+fS:[function(a,b){var z,y
 this.P6=this.P6+1
 this.qT=this.qT+1
 if(this.aY==null){this.aY=a
@@ -14426,29 +14685,27 @@
 a.T8=y.T8
 y.T8=null}else{a.T8=y
 a.Bb=y.Bb
-y.Bb=null}this.aY=a},"call$2","gSx",4,0,null,265,424]},
+y.Bb=null}this.aY=a},"call$2","gSx",4,0,null,259,[],420,[]]},
 Ba:{
-"":"vX;Cw,ac,aY,iW,P6,qT,bb",
+"^":"vX;Cw,ac,aY,iW,P6,qT,bb",
 wS:function(a,b){return this.Cw.call$2(a,b)},
 Ef:function(a){return this.ac.call$1(a)},
-yV:[function(a,b){return this.wS(a,b)},"call$2","gNA",4,0,null,425,426],
+yV:[function(a,b){return this.wS(a,b)},"call$2","gNA",4,0,null,421,[],422,[]],
 t:[function(a,b){if(b==null)throw H.b(new P.AT(b))
 if(this.Ef(b)!==!0)return
 if(this.aY!=null)if(J.de(this.vh(b),0))return this.aY.P
-return},"call$1","gIA",2,0,null,42],
+return},"call$1","gIA",2,0,null,42,[]],
 Rz:[function(a,b){var z
 if(this.Ef(b)!==!0)return
 z=this.bB(b)
 if(z!=null)return z.P
-return},"call$1","gRI",2,0,null,42],
-u:[function(a,b,c){var z,y
+return},"call$1","gRI",2,0,null,42,[]],
+u:[function(a,b,c){var z
 if(b==null)throw H.b(new P.AT(b))
 z=this.vh(b)
 if(J.de(z,0)){this.aY.P=c
-return}y=new P.jp(c,b,null,null)
-y.$builtinTypeInfo=[null,null]
-this.K8(y,z)},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){J.kH(b,new P.bF(this))},"call$1","gDY",2,0,null,104],
+return}this.fS(H.VM(new P.jp(c,b,null,null),[null,null]),z)},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){J.kH(b,new P.bF(this))},"call$1","gDY",2,0,null,104,[]],
 gl0:function(a){return this.aY==null},
 gor:function(a){return this.aY!=null},
 aN:[function(a,b){var z,y,x
@@ -14457,13 +14714,13 @@
 y.Qf(this,[P.qv,z])
 for(;y.G();){x=y.gl()
 z=J.RE(x)
-b.call$2(z.gG3(x),z.gP(x))}},"call$1","gjw",2,0,null,110],
+b.call$2(z.gG3(x),z.gP(x))}},"call$1","gjw",2,0,null,110,[]],
 gB:function(a){return this.P6},
 V1:[function(a){this.aY=null
 this.P6=0
 this.qT=this.qT+1},"call$0","gyP",0,0,null],
-x4:[function(a){return this.Ef(a)===!0&&J.de(this.vh(a),0)},"call$1","gV9",2,0,null,42],
-di:[function(a){return new P.LD(this,a,this.bb).call$1(this.aY)},"call$1","gmc",2,0,null,23],
+x4:[function(a){return this.Ef(a)===!0&&J.de(this.vh(a),0)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return new P.LD(this,a,this.bb).call$1(this.aY)},"call$1","gmc",2,0,null,23,[]],
 gvc:function(a){return H.VM(new P.OG(this),[H.Kp(this,0)])},
 gUQ:function(a){var z=new P.uM(this)
 z.$builtinTypeInfo=this.$builtinTypeInfo
@@ -14478,32 +14735,32 @@
 y=new P.An(c)
 return H.VM(new P.Ba(z,y,null,H.VM(new P.qv(null,null,null),[c]),0,0,0),[c,d])}}},
 An:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=H.Gq(a,this.a)
-return z},"call$1",null,2,0,null,277,"call"],
+return z},"call$1",null,2,0,null,272,[],"call"],
 $isEH:true},
 bF:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"ri",args:[a,b]}},this.a,"Ba")}},
 LD:{
-"":"Tp:427;a,b,c",
+"^":"Tp:423;a,b,c",
 call$1:[function(a){var z,y,x,w
 for(z=this.c,y=this.a,x=this.b;a!=null;){if(J.de(a.P,x))return!0
 if(z!==y.bb)throw H.b(P.a4(y))
 w=a.T8
 if(w!=null&&this.call$1(w)===!0)return!0
-a=a.Bb}return!1},"call$1",null,2,0,null,265,"call"],
+a=a.Bb}return!1},"call$1",null,2,0,null,259,[],"call"],
 $isEH:true},
 S6B:{
-"":"a;",
+"^":"a;",
 gl:function(){var z=this.ya
 if(z==null)return
 return this.Wb(z)},
 WV:[function(a){var z
 for(z=this.Ln;a!=null;){z.push(a)
-a=a.Bb}},"call$1","gBl",2,0,null,265],
+a=a.Bb}},"call$1","gBl",2,0,null,259,[]],
 G:[function(){var z,y,x
 z=this.Dn
 if(this.qT!==z.qT)throw H.b(P.a4(z))
@@ -14517,10 +14774,10 @@
 z=y.pop()
 this.ya=z
 this.WV(z.T8)
-return!0},"call$0","guK",0,0,null],
+return!0},"call$0","gqy",0,0,null],
 Qf:function(a,b){this.WV(a.aY)}},
 OG:{
-"":"mW;Dn",
+"^":"mW;Dn",
 gB:function(a){return this.Dn.P6},
 gl0:function(a){return this.Dn.P6===0},
 gA:function(a){var z,y
@@ -14531,7 +14788,7 @@
 return y},
 $isyN:true},
 uM:{
-"":"mW;Fb",
+"^":"mW;Fb",
 gB:function(a){return this.Fb.P6},
 gl0:function(a){return this.Fb.P6===0},
 gA:function(a){var z,y
@@ -14544,33 +14801,33 @@
 $ascX:function(a,b){return[b]},
 $isyN:true},
 DN:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a.G3},"call$1","gBL",2,0,null,265]},
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a.G3},"call$1","gBL",2,0,null,259,[]]},
 ZM:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a.P},"call$1","gBL",2,0,null,265],
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a.P},"call$1","gBL",2,0,null,259,[]],
 $asS6B:function(a,b){return[b]}},
 HW:{
-"":"S6B;Dn,Ln,qT,bb,ya",
-Wb:[function(a){return a},"call$1","gBL",2,0,null,265],
+"^":"S6B;Dn,Ln,qT,bb,ya",
+Wb:[function(a){return a},"call$1","gBL",2,0,null,259,[]],
 $asS6B:function(a){return[[P.qv,a]]}}}],["dart.convert","dart:convert",,P,{
-"":"",
+"^":"",
 VQ:[function(a,b){var z=new P.JC()
-return z.call$2(null,new P.f1(z).call$1(a))},"call$2","os",4,0,null,185,186],
+return z.call$2(null,new P.f1(z).call$1(a))},"call$2","os",4,0,null,185,[],186,[]],
 BS:[function(a,b){var z,y,x,w
 x=a
 if(typeof x!=="string")throw H.b(new P.AT(a))
 z=null
 try{z=JSON.parse(a)}catch(w){x=H.Ru(w)
 y=x
-throw H.b(P.cD(String(y)))}return P.VQ(z,b)},"call$2","pi",4,0,null,27,186],
-tp:[function(a){return a.Lt()},"call$1","BC",2,0,187,6],
+throw H.b(P.cD(String(y)))}return P.VQ(z,b)},"call$2","H44",4,0,null,27,[],186,[]],
+tp:[function(a){return a.Lt()},"call$1","BC",2,0,187,6,[]],
 JC:{
-"":"Tp:349;",
-call$2:[function(a,b){return b},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return b},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 f1:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w,v,u,t
 if(a==null||typeof a!="object")return a
 if(Object.getPrototypeOf(a)===Array.prototype){z=a
@@ -14580,41 +14837,43 @@
 for(y=this.a,x=0;x<w.length;++x){u=w[x]
 v.u(0,u,y.call$2(u,this.call$1(a[u])))}t=a.__proto__
 if(typeof t!=="undefined"&&t!==Object.prototype)v.u(0,"__proto__",y.call$2("__proto__",this.call$1(t)))
-return v},"call$1",null,2,0,null,18,"call"],
+return v},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Uk:{
-"":"a;"},
+"^":"a;"},
 wI:{
-"":"a;"},
+"^":"a;"},
 Zi:{
-"":"Uk;",
+"^":"Uk;",
 $asUk:function(){return[J.O,[J.Q,J.im]]}},
 Ud:{
-"":"Ge;Ct,FN",
+"^":"Ge;Ct,FN",
 bu:[function(a){if(this.FN!=null)return"Converting object to an encodable object failed."
 else return"Converting object did not return an encodable object."},"call$0","gXo",0,0,null],
 static:{ox:function(a,b){return new P.Ud(a,b)}}},
 K8:{
-"":"Ud;Ct,FN",
+"^":"Ud;Ct,FN",
 bu:[function(a){return"Cyclic error in JSON stringify"},"call$0","gXo",0,0,null],
 static:{TP:function(a){return new P.K8(a,null)}}},
 by:{
-"":"Uk;",
-pW:[function(a,b){return P.BS(a,C.A3.N5)},function(a){return this.pW(a,null)},"kV","call$2$reviver",null,"gzL",2,3,null,77,27,186],
-PN:[function(a,b){return P.Vg(a,C.Ap.Xi)},function(a){return this.PN(a,null)},"KP","call$2$toEncodable",null,"gr8",2,3,null,77,23,188],
+"^":"Uk;N5,iY",
+pW:[function(a,b){return P.BS(a,this.gHe().N5)},function(a){return this.pW(a,null)},"kV","call$2$reviver",null,"gzL",2,3,null,77,27,[],186,[]],
+PN:[function(a,b){return P.Vg(a,this.gZE().Xi)},function(a){return this.PN(a,null)},"KP","call$2$toEncodable",null,"gV0",2,3,null,77,23,[],188,[]],
+gZE:function(){return C.Ap},
+gHe:function(){return C.A3},
 $asUk:function(){return[P.a,J.O]}},
-pD:{
-"":"wI;Xi",
+dI:{
+"^":"wI;Xi",
 $aswI:function(){return[P.a,J.O]}},
 Cf:{
-"":"wI;N5",
+"^":"wI;N5",
 $aswI:function(){return[J.O,P.a]}},
 Sh:{
-"":"a;WE,Mw,JN",
+"^":"a;WE,Mw,JN",
 Tt:function(a){return this.WE.call$1(a)},
 WD:[function(a){var z=this.JN
 if(z.tg(0,a))throw H.b(P.TP(a))
-z.h(0,a)},"call$1","gUW",2,0,null,6],
+z.h(0,a)},"call$1","gUW",2,0,null,6,[]],
 rl:[function(a){var z,y,x,w,v
 if(!this.IS(a)){x=a
 w=this.JN
@@ -14624,7 +14883,7 @@
 if(!this.IS(z)){x=P.ox(a,null)
 throw H.b(x)}w.Rz(0,a)}catch(v){x=H.Ru(v)
 y=x
-throw H.b(P.ox(a,y))}}},"call$1","gO5",2,0,null,6],
+throw H.b(P.ox(a,y))}}},"call$1","gO5",2,0,null,6,[]],
 IS:[function(a){var z,y,x,w
 z={}
 if(typeof a==="number"){if(!C.CD.gx8(a))return!1
@@ -14655,12 +14914,12 @@
 y.aN(a,new P.tF(z,this))
 w.KF("}")
 this.JN.Rz(0,a)
-return!0}else return!1}},"call$1","gjQ",2,0,null,6],
-static:{"":"P3,kD,IE,Yz,ij,fg,SW,KQz,MU,ql,NXu,PBv,QVv",Vg:[function(a,b){var z
+return!0}else return!1}},"call$1","gjQ",2,0,null,6,[]],
+static:{"^":"P3,kD,IE,Yz,No,fg,SW,KQz,MU,ql,NXu,CE,QVv",Vg:[function(a,b){var z
 b=P.BC()
 z=P.p9("")
 new P.Sh(b,z,P.yv(null)).rl(a)
-return z.vM},"call$2","Sr",4,0,null,6,188],NY:[function(a,b){var z,y,x,w,v,u,t
+return z.vM},"call$2","ab",4,0,null,6,[],188,[]],NY:[function(a,b){var z,y,x,w,v,u,t
 z=J.U6(b)
 y=z.gB(b)
 x=H.VM([],[J.im])
@@ -14690,9 +14949,9 @@
 x.push(t<10?48+t:87+t)
 break}w=!0}else if(u===34||u===92){x.push(92)
 x.push(u)
-w=!0}else x.push(u)}a.KF(w?P.HM(x):b)},"call$2","qW",4,0,null,189,86]}},
+w=!0}else x.push(u)}a.KF(w?P.HM(x):b)},"call$2","qW",4,0,null,189,[],86,[]]}},
 tF:{
-"":"Tp:428;a,b",
+"^":"Tp:424;a,b",
 call$2:[function(a,b){var z,y,x
 z=this.a
 y=this.b
@@ -14701,14 +14960,14 @@
 x.KF("\"")}P.NY(x,a)
 x.KF("\":")
 y.rl(b)
-z.a=!1},"call$2",null,4,0,null,42,23,"call"],
+z.a=!1},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 z0:{
-"":"Zi;lH",
+"^":"Zi;lH",
 goc:function(a){return"utf-8"},
 gZE:function(){return new P.E3()}},
 E3:{
-"":"wI;",
+"^":"wI;",
 WJ:[function(a){var z,y,x
 z=J.U6(a)
 y=J.p0(z.gB(a),3)
@@ -14716,10 +14975,10 @@
 y=H.VM(Array(y),[J.im])
 x=new P.Rw(0,0,y)
 if(x.fJ(a,0,z.gB(a))!==z.gB(a))x.Lb(z.j(a,J.xH(z.gB(a),1)),0)
-return C.Nm.D6(y,0,x.ZP)},"call$1","gmC",2,0,null,26],
+return C.Nm.D6(y,0,x.ZP)},"call$1","gmC",2,0,null,26,[]],
 $aswI:function(){return[J.O,[J.Q,J.im]]}},
 Rw:{
-"":"a;WF,ZP,EN",
+"^":"a;WF,ZP,EN",
 Lb:[function(a,b){var z,y,x,w,v
 z=this.EN
 y=this.ZP
@@ -14752,7 +15011,7 @@
 this.ZP=y+1
 if(y>=v)return H.e(z,y)
 z[y]=128|a&63
-return!1}},"call$2","gkL",4,0,null,429,430],
+return!1}},"call$2","gkL",4,0,null,425,[],426,[]],
 fJ:[function(a,b,c){var z,y,x,w,v,u,t,s
 if(b!==c&&(J.lE(a,J.xH(c,1))&64512)===55296)c=J.xH(c,1)
 if(typeof c!=="number")return H.s(c)
@@ -14785,82 +15044,11 @@
 z[s]=128|v>>>6&63
 this.ZP=u+1
 if(u>=y)return H.e(z,u)
-z[u]=128|v&63}}return w},"call$3","gkH",6,0,null,340,115,116],
-static:{"":"Ij"}},
-GY:{
-"":"wI;lH",
-WJ:[function(a){var z,y
-z=P.p9("")
-y=new P.jZ(this.lH,z,!0,0,0,0)
-y.ME(a,0,J.q8(a))
-y.fZ()
-return z.vM},"call$1","gmC",2,0,null,431],
-$aswI:function(){return[[J.Q,J.im],J.O]}},
-jZ:{
-"":"a;lH,aS,rU,Ok,TY,VN",
-cO:[function(a){this.fZ()},"call$0","gJK",0,0,null],
-fZ:[function(){if(this.TY>0){if(this.lH!==!0)throw H.b(P.cD("Unfinished UTF-8 octet sequence"))
-this.aS.KF(P.fc(65533))
-this.Ok=0
-this.TY=0
-this.VN=0}},"call$0","gRh",0,0,null],
-ME:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
-z=this.Ok
-y=this.TY
-x=this.VN
-this.Ok=0
-this.TY=0
-this.VN=0
-$loop$0:for(w=this.aS,v=this.lH!==!0,u=J.U6(a),t=b;!0;t=p){$multibyte$2:{if(y>0){do{if(t===c)break $loop$0
-s=u.t(a,t)
-r=J.Wx(s)
-if(r.i(s,192)!==128){if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+r.WZ(s,16)))
-this.rU=!1
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r
-y=0
-break $multibyte$2}else{z=(z<<6|r.i(s,63))>>>0;--y;++t}}while(y>0)
-r=x-1
-if(r<0||r>=4)return H.e(C.Gb,r)
-if(z<=C.Gb[r]){if(v)throw H.b(P.cD("Overlong encoding of 0x"+C.jn.WZ(z,16)))
-z=65533
-y=0
-x=0}if(z>1114111){if(v)throw H.b(P.cD("Character outside valid Unicode range: 0x"+C.jn.WZ(z,16)))
-z=65533}if(!this.rU||z!==65279){q=P.O8(1,z,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}this.rU=!1}}for(;t<c;t=p){p=t+1
-s=u.t(a,t)
-r=J.Wx(s)
-if(r.C(s,0)){if(v)throw H.b(P.cD("Negative UTF-8 code unit: -0x"+C.CD.WZ(r.J(s),16)))
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}else if(r.E(s,127)){this.rU=!1
-q=P.O8(1,s,J.im)
-r=H.eT(q)
-w.vM=w.vM+r}else{if(r.i(s,224)===192){z=r.i(s,31)
-y=1
-x=1
-continue $loop$0}if(r.i(s,240)===224){z=r.i(s,15)
-y=2
-x=2
-continue $loop$0}if(r.i(s,248)===240&&r.C(s,245)){z=r.i(s,7)
-y=3
-x=3
-continue $loop$0}if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+r.WZ(s,16)))
-this.rU=!1
-q=P.O8(1,65533,J.im)
-r=H.eT(q)
-w.vM=w.vM+r
-z=65533
-y=0
-x=0}}break $loop$0}if(y>0){this.Ok=z
-this.TY=y
-this.VN=x}},"call$3","gmC",6,0,null,431,80,125],
-static:{"":"PO"}}}],["dart.core","dart:core",,P,{
-"":"",
-Te:[function(a){return},"call$1","PM",2,0,null,44],
-Wc:[function(a,b){return J.oE(a,b)},"call$2","n4",4,0,190,123,180],
+z[u]=128|v&63}}return w},"call$3","gkH",6,0,null,334,[],115,[],116,[]],
+static:{"^":"n9"}}}],["dart.core","dart:core",,P,{
+"^":"",
+Te:[function(a){return},"call$1","PM",2,0,null,44,[]],
+Wc:[function(a,b){return J.oE(a,b)},"call$2","n4",4,0,190,123,[],180,[]],
 hl:[function(a){var z,y,x,w,v,u
 if(typeof a==="number"||typeof a==="boolean"||null==a)return J.AG(a)
 if(typeof a==="string"){z=new P.Rn("")
@@ -14884,11 +15072,11 @@
 w=z.vM+w
 z.vM=w}}y=w+"\""
 z.vM=y
-return y}return"Instance of '"+H.lh(a)+"'"},"call$1","Zx",2,0,null,6],
+return y}return"Instance of '"+H.lh(a)+"'"},"call$1","Zx",2,0,null,6,[]],
 FM:function(a){return new P.HG(a)},
-ad:[function(a,b){return a==null?b==null:a===b},"call$2","N3",4,0,192,123,180],
-xv:[function(a){return H.CU(a)},"call$1","J2",2,0,193,6],
-QA:[function(a,b,c){return H.BU(a,c,b)},function(a){return P.QA(a,null,null)},null,function(a,b){return P.QA(a,b,null)},null,"call$3$onError$radix","call$1","call$2$onError","ya",2,5,194,77,77,27,156,28],
+ad:[function(a,b){return a==null?b==null:a===b},"call$2","N3",4,0,192,123,[],180,[]],
+xv:[function(a){return H.CU(a)},"call$1","J2",2,0,193,6,[]],
+QA:[function(a,b,c){return H.BU(a,c,b)},function(a){return P.QA(a,null,null)},null,function(a,b){return P.QA(a,b,null)},null,"call$3$onError$radix","call$1","call$2$onError","ya",2,5,194,77,77,27,[],156,[],28,[]],
 O8:function(a,b,c){var z,y,x
 z=J.Qi(a,c)
 if(a!==0&&b!=null)for(y=z.length,x=0;x<y;++x)z[x]=b
@@ -14909,39 +15097,39 @@
 z=H.d(a)
 y=$.oK
 if(y==null)H.qw(z)
-else y.call$1(z)},"call$1","Pl",2,0,null,6],
+else y.call$1(z)},"call$1","Pl",2,0,null,6,[]],
 HM:function(a){return H.eT(a)},
 fc:function(a){return P.HM(P.O8(1,a,J.im))},
 HB:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,a.gfN(a),b)},"call$2",null,4,0,null,129,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,a.gfN(a),b)},"call$2",null,4,0,null,129,[],23,[],"call"],
 $isEH:true},
 CL:{
-"":"Tp:384;a",
+"^":"Tp:378;a",
 call$2:[function(a,b){var z=this.a
 if(z.b>0)z.a.KF(", ")
 z.a.KF(J.GL(a))
 z.a.KF(": ")
 z.a.KF(P.hl(b))
-z.b=z.b+1},"call$2",null,4,0,null,42,23,"call"],
+z.b=z.b+1},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 p4:{
-"":"a;OF",
+"^":"a;OF",
 bu:[function(a){return"Deprecated feature. Will be removed "+this.OF},"call$0","gXo",0,0,null]},
 a2:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return this?"true":"false"},"call$0","gXo",0,0,null],
 $isbool:true},
 fR:{
-"":"a;"},
+"^":"a;"},
 iP:{
-"":"a;y3<,aL",
+"^":"a;y3<,aL",
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isiP)return!1
-return this.y3===b.y3&&this.aL===b.aL},"call$1","gUJ",2,0,null,104],
-iM:[function(a,b){return C.CD.iM(this.y3,b.gy3())},"call$1","gYc",2,0,null,104],
+return this.y3===b.y3&&this.aL===b.aL},"call$1","gUJ",2,0,null,104,[]],
+iM:[function(a,b){return C.CD.iM(this.y3,b.gy3())},"call$1","gYc",2,0,null,104,[]],
 giO:function(a){return this.y3},
 bu:[function(a){var z,y,x,w,v,u,t,s,r,q
 z=new P.B5()
@@ -14957,11 +15145,11 @@
 q=new P.Zl().call$1(z)
 if(y)return H.d(w)+"-"+H.d(v)+"-"+H.d(u)+" "+H.d(t)+":"+H.d(s)+":"+H.d(r)+"."+H.d(q)+"Z"
 else return H.d(w)+"-"+H.d(v)+"-"+H.d(u)+" "+H.d(t)+":"+H.d(s)+":"+H.d(r)+"."+H.d(q)},"call$0","gXo",0,0,null],
-h:[function(a,b){return P.Wu(this.y3+b.gVs(),this.aL)},"call$1","ght",2,0,null,159],
+h:[function(a,b){return P.Wu(this.y3+b.gVs(),this.aL)},"call$1","ght",2,0,null,159,[]],
 EK:function(){H.o2(this)},
 RM:function(a,b){if(Math.abs(a)>8640000000000000)throw H.b(new P.AT(a))},
 $isiP:true,
-static:{"":"aV,bI,df,Kw,h2,mo,EQe,Qg,tp1,Gi,k3,cR,E0,mj,lT,Nr,bm,FI,Kz,J7,TO,lme",Gl:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
+static:{"^":"aV,bI,Hq,Kw,h2,pa,EQe,NXt,tp1,Gi,k3,cR,E0,fH,Ne,Nr,bmS,FI,Kz,J7,dM,lme",Gl:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=new H.VR(H.v4("^([+-]?\\d?\\d\\d\\d\\d)-?(\\d\\d)-?(\\d\\d)(?:[ T](\\d\\d)(?::?(\\d\\d)(?::?(\\d\\d)(.\\d{1,6})?)?)?( ?[zZ]| ?\\+00(?::?00)?)?)?$",!1,!0,!1),null,null).ej(a)
 if(z!=null){y=new P.MF()
 x=z.QK
@@ -14984,60 +15172,60 @@
 if(8>=x.length)return H.e(x,8)
 o=x[8]!=null
 n=H.zW(w,v,u,t,s,r,q,o)
-return P.Wu(p?n+1:n,o)}else throw H.b(P.cD(a))},"call$1","lel",2,0,null,191],Wu:function(a,b){var z=new P.iP(a,b)
+return P.Wu(p?n+1:n,o)}else throw H.b(P.cD(a))},"call$1","lel",2,0,null,191,[]],Wu:function(a,b){var z=new P.iP(a,b)
 z.RM(a,b)
 return z}}},
 MF:{
-"":"Tp:433;",
+"^":"Tp:428;",
 call$1:[function(a){if(a==null)return 0
-return H.BU(a,null,null)},"call$1",null,2,0,null,432,"call"],
+return H.BU(a,null,null)},"call$1",null,2,0,null,427,[],"call"],
 $isEH:true},
 Rq:{
-"":"Tp:434;",
+"^":"Tp:429;",
 call$1:[function(a){if(a==null)return 0
-return H.IH(a,null)},"call$1",null,2,0,null,432,"call"],
+return H.IH(a,null)},"call$1",null,2,0,null,427,[],"call"],
 $isEH:true},
 Hn:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){var z,y
 z=Math.abs(a)
 y=a<0?"-":""
 if(z>=1000)return""+a
 if(z>=100)return y+"0"+H.d(z)
 if(z>=10)return y+"00"+H.d(z)
-return y+"000"+H.d(z)},"call$1",null,2,0,null,292,"call"],
+return y+"000"+H.d(z)},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Zl:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=100)return""+a
 if(a>=10)return"0"+a
-return"00"+a},"call$1",null,2,0,null,292,"call"],
+return"00"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 B5:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=10)return""+a
-return"0"+a},"call$1",null,2,0,null,292,"call"],
+return"0"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 a6:{
-"":"a;Fq<",
-g:[function(a,b){return P.k5(0,0,this.Fq+b.gFq(),0,0,0)},"call$1","gF1n",2,0,null,104],
-W:[function(a,b){return P.k5(0,0,this.Fq-b.gFq(),0,0,0)},"call$1","gTG",2,0,null,104],
+"^":"a;Fq<",
+g:[function(a,b){return P.k5(0,0,this.Fq+b.gFq(),0,0,0)},"call$1","gF1n",2,0,null,104,[]],
+W:[function(a,b){return P.k5(0,0,this.Fq-b.gFq(),0,0,0)},"call$1","gTG",2,0,null,104,[]],
 U:[function(a,b){if(typeof b!=="number")return H.s(b)
-return P.k5(0,0,C.CD.yu(C.CD.UD(this.Fq*b)),0,0,0)},"call$1","gEH",2,0,null,435],
+return P.k5(0,0,C.CD.yu(C.CD.UD(this.Fq*b)),0,0,0)},"call$1","gEH",2,0,null,430,[]],
 Z:[function(a,b){if(b===0)throw H.b(P.zl())
-return P.k5(0,0,C.jn.Z(this.Fq,b),0,0,0)},"call$1","gdG",2,0,null,436],
-C:[function(a,b){return this.Fq<b.gFq()},"call$1","gix",2,0,null,104],
-D:[function(a,b){return this.Fq>b.gFq()},"call$1","gh1",2,0,null,104],
-E:[function(a,b){return this.Fq<=b.gFq()},"call$1","gf5",2,0,null,104],
-F:[function(a,b){return this.Fq>=b.gFq()},"call$1","gNH",2,0,null,104],
+return P.k5(0,0,C.jn.Z(this.Fq,b),0,0,0)},"call$1","gdG",2,0,null,431,[]],
+C:[function(a,b){return this.Fq<b.gFq()},"call$1","gix",2,0,null,104,[]],
+D:[function(a,b){return this.Fq>b.gFq()},"call$1","gh1",2,0,null,104,[]],
+E:[function(a,b){return this.Fq<=b.gFq()},"call$1","gf5",2,0,null,104,[]],
+F:[function(a,b){return this.Fq>=b.gFq()},"call$1","gNH",2,0,null,104,[]],
 gVs:function(){return C.jn.cU(this.Fq,1000)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isa6)return!1
-return this.Fq===b.Fq},"call$1","gUJ",2,0,null,104],
+return this.Fq===b.Fq},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return this.Fq&0x1FFFFFFF},
-iM:[function(a,b){return C.jn.iM(this.Fq,b.gFq())},"call$1","gYc",2,0,null,104],
+iM:[function(a,b){return C.jn.iM(this.Fq,b.gFq())},"call$1","gYc",2,0,null,104,[]],
 bu:[function(a){var z,y,x,w,v
 z=new P.DW()
 y=this.Fq
@@ -15047,43 +15235,43 @@
 v=new P.P7().call$1(C.jn.JV(y,1000000))
 return""+C.jn.cU(y,3600000000)+":"+H.d(x)+":"+H.d(w)+"."+H.d(v)},"call$0","gXo",0,0,null],
 $isa6:true,
-static:{"":"Wt,S4d,dk,uU,RD,b2,q9,ll,Do,f4,vd,IJZ,iI,Vk,Nw,yn",k5:function(a,b,c,d,e,f){return new P.a6(a*86400000000+b*3600000000+e*60000000+f*1000000+d*1000+c)}}},
+static:{"^":"Wt,S4d,dk,uU,RD,b2,q9,ll,Do,f4,kTB,IJZ,iI,Vk,Nw,yn",k5:function(a,b,c,d,e,f){return new P.a6(a*86400000000+b*3600000000+e*60000000+f*1000000+d*1000+c)}}},
 P7:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=100000)return""+a
 if(a>=10000)return"0"+a
 if(a>=1000)return"00"+a
 if(a>=100)return"000"+a
 if(a>=10)return"0000"+a
-return"00000"+a},"call$1",null,2,0,null,292,"call"],
+return"00000"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 DW:{
-"":"Tp:391;",
+"^":"Tp:387;",
 call$1:[function(a){if(a>=10)return""+a
-return"0"+a},"call$1",null,2,0,null,292,"call"],
+return"0"+a},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Ge:{
-"":"a;",
+"^":"a;",
 gI4:function(){return new H.XO(this.$thrownJsError,null)},
 $isGe:true},
 LK:{
-"":"Ge;",
+"^":"Ge;",
 bu:[function(a){return"Throw of null."},"call$0","gXo",0,0,null]},
 AT:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){var z=this.G1
 if(z!=null)return"Illegal argument(s): "+H.d(z)
 return"Illegal argument(s)"},"call$0","gXo",0,0,null],
 static:{u:function(a){return new P.AT(a)}}},
 bJ:{
-"":"AT;G1",
+"^":"AT;G1",
 bu:[function(a){return"RangeError: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{C3:function(a){return new P.bJ(a)},N:function(a){return new P.bJ("value "+H.d(a))},TE:function(a,b,c){return new P.bJ("value "+H.d(a)+" not in range "+H.d(b)+".."+H.d(c))}}},
 Np:{
-"":"Ge;",
+"^":"Ge;",
 static:{hS:function(){return new P.Np()}}},
 mp:{
-"":"Ge;uF,UP,mP,SA,mZ",
+"^":"Ge;uF,UP,mP,SA,mZ",
 bu:[function(a){var z,y,x,w,v,u,t
 z={}
 z.a=P.p9("")
@@ -15100,92 +15288,92 @@
 $ismp:true,
 static:{lr:function(a,b,c,d,e){return new P.mp(a,b,c,d,e)}}},
 ub:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"Unsupported operation: "+this.G1},"call$0","gXo",0,0,null],
 static:{f:function(a){return new P.ub(a)}}},
 ds:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){var z=this.G1
 return z!=null?"UnimplementedError: "+H.d(z):"UnimplementedError"},"call$0","gXo",0,0,null],
 $isGe:true,
 static:{SY:function(a){return new P.ds(a)}}},
 lj:{
-"":"Ge;G1>",
+"^":"Ge;G1>",
 bu:[function(a){return"Bad state: "+this.G1},"call$0","gXo",0,0,null],
 static:{w:function(a){return new P.lj(a)}}},
 UV:{
-"":"Ge;YA",
+"^":"Ge;YA",
 bu:[function(a){var z=this.YA
 if(z==null)return"Concurrent modification during iteration."
 return"Concurrent modification during iteration: "+H.d(P.hl(z))+"."},"call$0","gXo",0,0,null],
 static:{a4:function(a){return new P.UV(a)}}},
 VS:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"Stack Overflow"},"call$0","gXo",0,0,null],
 gI4:function(){return},
 $isGe:true},
 t7:{
-"":"Ge;Wo",
+"^":"Ge;Wo",
 bu:[function(a){return"Reading static variable '"+this.Wo+"' during its initialization"},"call$0","gXo",0,0,null],
 static:{Gz:function(a){return new P.t7(a)}}},
 HG:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){var z=this.G1
 if(z==null)return"Exception"
 return"Exception: "+H.d(z)},"call$0","gXo",0,0,null]},
 aE:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"FormatException: "+H.d(this.G1)},"call$0","gXo",0,0,null],
 static:{cD:function(a){return new P.aE(a)}}},
 eV:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"IntegerDivisionByZeroException"},"call$0","gXo",0,0,null],
 static:{zl:function(){return new P.eV()}}},
 kM:{
-"":"a;oc>",
+"^":"a;oc>",
 bu:[function(a){return"Expando:"+this.oc},"call$0","gXo",0,0,null],
 t:[function(a,b){var z=H.of(b,"expando$values")
-return z==null?null:H.of(z,this.Qz())},"call$1","gIA",2,0,null,6],
+return z==null?null:H.of(z,this.Qz())},"call$1","gIA",2,0,null,6,[]],
 u:[function(a,b,c){var z=H.of(b,"expando$values")
 if(z==null){z=new P.a()
-H.aw(b,"expando$values",z)}H.aw(z,this.Qz(),c)},"call$2","gj3",4,0,null,6,23],
+H.aw(b,"expando$values",z)}H.aw(z,this.Qz(),c)},"call$2","gj3",4,0,null,6,[],23,[]],
 Qz:[function(){var z,y
 z=H.of(this,"expando$key")
 if(z==null){y=$.Ss
 $.Ss=y+1
 z="expando$key$"+y
 H.aw(this,"expando$key",z)}return z},"call$0","gwT",0,0,null],
-static:{"":"Xa,rly,Ss"}},
+static:{"^":"bZ,rly,Ss"}},
 EH:{
-"":"a;",
+"^":"a;",
 $isEH:true},
 cX:{
-"":"a;",
+"^":"a;",
 $iscX:true,
 $ascX:null},
 Yl:{
-"":"a;"},
+"^":"a;"},
 Z0:{
-"":"a;",
+"^":"a;",
 $isZ0:true},
 L9:{
-"":"a;",
+"^":"a;",
 bu:[function(a){return"null"},"call$0","gXo",0,0,null]},
 a:{
-"":";",
-n:[function(a,b){return this===b},"call$1","gUJ",2,0,null,104],
+"^":";",
+n:[function(a,b){return this===b},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){return H.eQ(this)},
 bu:[function(a){return H.a5(this)},"call$0","gXo",0,0,null],
-T:[function(a,b){throw H.b(P.lr(this,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,332],
+T:[function(a,b){throw H.b(P.lr(this,b.gWa(),b.gnd(),b.gVm(),null))},"call$1","gxK",2,0,null,326,[]],
 gbx:function(a){return new H.cu(H.dJ(this),null)},
 $isa:true},
 Od:{
-"":"a;",
+"^":"a;",
 $isOd:true},
 MN:{
-"":"a;"},
+"^":"a;"},
 WU:{
-"":"a;Qk,SU,Oq,Wn",
+"^":"a;Qk,SU,Oq,Wn",
 gl:function(){return this.Wn},
 G:[function(){var z,y,x,w,v,u
 z=this.Oq
@@ -15203,14 +15391,14 @@
 this.Wn=65536+((w&1023)<<10>>>0)+(u&1023)
 return!0}}this.Oq=v
 this.Wn=w
-return!0},"call$0","guK",0,0,null]},
+return!0},"call$0","gqy",0,0,null]},
 Rn:{
-"":"a;vM<",
+"^":"a;vM<",
 gB:function(a){return this.vM.length},
 gl0:function(a){return this.vM.length===0},
 gor:function(a){return this.vM.length!==0},
 KF:[function(a){var z=typeof a==="string"?a:H.d(a)
-this.vM=this.vM+z},"call$1","gMG",2,0,null,93],
+this.vM=this.vM+z},"call$1","gMG",2,0,null,93,[]],
 We:[function(a,b){var z,y
 z=J.GP(a)
 if(!z.G())return
@@ -15221,7 +15409,7 @@
 for(;z.G();){this.vM=this.vM+b
 y=z.gl()
 y=typeof y==="string"?y:H.d(y)
-this.vM=this.vM+y}}},"call$2","gS9",2,2,null,334,419,335],
+this.vM=this.vM+y}}},"call$2","gS9",2,2,null,328,415,[],329,[]],
 V1:[function(a){this.vM=""},"call$0","gyP",0,0,null],
 bu:[function(a){return this.vM},"call$0","gXo",0,0,null],
 PD:function(a){if(typeof a==="string")this.vM=a
@@ -15230,13 +15418,17 @@
 z.PD(a)
 return z}}},
 wv:{
-"":"a;",
+"^":"a;",
 $iswv:true},
 uq:{
-"":"a;",
+"^":"a;",
 $isuq:true},
 iD:{
-"":"a;NN,HC,r0,Fi,iV,tP,Ka,ld,yW",
+"^":"a;NN,HC,r0,Fi,ku,tP,Ka,YG,yW",
+gWu:function(){if(J.de(this.gJf(this),""))return""
+var z=P.p9("")
+this.tb(z)
+return z.vM},
 gJf:function(a){var z,y
 z=this.NN
 if(z!=null&&J.co(z,"[")){y=J.U6(z)
@@ -15247,15 +15439,6 @@
 if(y.n(z,"http"))return 80
 if(y.n(z,"https"))return 443}return this.HC},
 Ja:function(a,b){return this.tP.call$1(b)},
-gFj:function(){var z,y
-z=this.ld
-if(z==null){z=J.FN(this.r0)!==!0&&J.lE(this.r0,0)===47
-y=this.r0
-if(z)y=J.ZZ(y,1)
-z=J.x(y)
-z=z.n(y,"")?C.Fv:H.VM(new H.A8(z.Fr(y,"/"),P.t9()),[null,null]).tt(0,!1)
-z=H.VM(new P.Yp(z),[null])
-this.ld=z}return z},
 x6:[function(a,b){var z,y
 z=a==null
 if(z&&!0)return""
@@ -15264,17 +15447,17 @@
 if(!J.de(this.gJf(this),"")||J.de(this.Fi,"file")){z=J.U6(y)
 z=z.gor(y)&&!z.nC(y,"/")}else z=!1
 if(z)return"/"+H.d(y)
-return y},"call$2","gbQ",4,0,null,266,437],
+return y},"call$2","gbQ",4,0,null,260,[],432,[]],
 Ky:[function(a,b){var z=J.x(a)
 if(z.n(a,""))return"/"+H.d(b)
-return z.Nj(a,0,J.WB(z.cn(a,"/"),1))+H.d(b)},"call$2","gAj",4,0,null,438,439],
+return z.Nj(a,0,J.WB(z.cn(a,"/"),1))+H.d(b)},"call$2","gAj",4,0,null,433,[],434,[]],
 uo:[function(a){var z=J.U6(a)
 if(J.z8(z.gB(a),0)&&z.j(a,0)===58)return!0
-return z.u8(a,"/.")!==-1},"call$1","gaO",2,0,null,266],
+return z.u8(a,"/.")!==-1},"call$1","gaO",2,0,null,260,[]],
 SK:[function(a){var z,y,x,w,v
 if(!this.uo(a))return a
 z=[]
-for(y=J.Gn(a,"/"),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=!1;y.G();){w=y.lo
+for(y=J.uH(a,"/"),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=!1;y.G();){w=y.lo
 if(J.de(w,"..")){v=z.length
 if(v!==0)if(v===1){if(0>=v)return H.e(z,0)
 v=!J.de(z[0],"")}else v=!0
@@ -15283,53 +15466,19 @@
 z.pop()}x=!0}else if("."===w)x=!0
 else{z.push(w)
 x=!1}}if(x)z.push("")
-return C.Nm.zV(z,"/")},"call$1","ghK",2,0,null,266],
-mS:[function(a){var z,y,x,w,v,u,t,s
-z=a.Fi
-if(!J.de(z,"")){y=a.iV
-x=a.gJf(a)
-w=a.gtp(a)
-v=this.SK(a.r0)
-u=a.tP}else{if(!J.de(a.gJf(a),"")){y=a.iV
-x=a.gJf(a)
-w=a.gtp(a)
-v=this.SK(a.r0)
-u=a.tP}else{if(J.de(a.r0,"")){v=this.r0
-u=a.tP
-u=!J.de(u,"")?u:this.tP}else{t=J.co(a.r0,"/")
-s=a.r0
-v=t?this.SK(s):this.SK(this.Ky(this.r0,s))
-u=a.tP}y=this.iV
-x=this.gJf(this)
-w=this.gtp(this)}z=this.Fi}return P.R6(a.Ka,x,v,null,w,u,null,z,y)},"call$1","gUw",2,0,null,439],
-Dm:[function(a){var z,y,x
-z=this.Fi
-y=J.x(z)
-if(!y.n(z,"")&&!y.n(z,"file"))throw H.b(P.f("Cannot extract a file path from a "+H.d(z)+" URI"))
-if(!y.n(z,"")&&!y.n(z,"file"))throw H.b(P.f("Cannot extract a file path from a "+H.d(z)+" URI"))
-if(!J.de(this.tP,""))throw H.b(P.f("Cannot extract a file path from a URI with a query component"))
-if(!J.de(this.Ka,""))throw H.b(P.f("Cannot extract a file path from a URI with a fragment component"))
-if(!J.de(this.gJf(this),""))H.vh(P.f("Cannot extract a non-Windows file path from a file URI with an authority"))
-P.i8(this.gFj(),!1)
-x=P.p9("")
-if(this.grj())x.KF("/")
-x.We(this.gFj(),"/")
-z=x.vM
-return z},function(){return this.Dm(null)},"t4","call$1$windows",null,"gK1",0,3,null,77,440],
-grj:function(){var z=this.r0
-if(z==null||J.FN(z)===!0)return!1
-return J.co(this.r0,"/")},
+return C.Nm.zV(z,"/")},"call$1","ghK",2,0,null,260,[]],
+tb:[function(a){var z=this.ku
+if(""!==z){a.KF(z)
+a.KF("@")}z=this.NN
+a.KF(z==null?"null":z)
+if(!J.de(this.HC,0)){a.KF(":")
+a.KF(J.AG(this.HC))}},"call$1","gyL",2,0,null,435,[]],
 bu:[function(a){var z,y
 z=P.p9("")
 y=this.Fi
 if(""!==y){z.KF(y)
 z.KF(":")}if(!J.de(this.gJf(this),"")||J.de(y,"file")){z.KF("//")
-y=this.iV
-if(""!==y){z.KF(y)
-z.KF("@")}y=this.NN
-z.KF(y==null?"null":y)
-if(!J.de(this.HC,0)){z.KF(":")
-z.KF(J.AG(this.HC))}}z.KF(this.r0)
+this.tb(z)}z.KF(this.r0)
 y=this.tP
 if(""!==y){z.KF("?")
 z.KF(y)}y=this.Ka
@@ -15339,16 +15488,16 @@
 if(b==null)return!1
 z=J.RE(b)
 if(typeof b!=="object"||b===null||!z.$isiD)return!1
-return J.de(this.Fi,b.Fi)&&J.de(this.iV,b.iV)&&J.de(this.gJf(this),z.gJf(b))&&J.de(this.gtp(this),z.gtp(b))&&J.de(this.r0,b.r0)&&J.de(this.tP,b.tP)&&J.de(this.Ka,b.Ka)},"call$1","gUJ",2,0,null,104],
+return J.de(this.Fi,b.Fi)&&J.de(this.ku,b.ku)&&J.de(this.gJf(this),z.gJf(b))&&J.de(this.gtp(this),z.gtp(b))&&J.de(this.r0,b.r0)&&J.de(this.tP,b.tP)&&J.de(this.Ka,b.Ka)},"call$1","gUJ",2,0,null,104,[]],
 giO:function(a){var z=new P.XZ()
-return z.call$2(this.Fi,z.call$2(this.iV,z.call$2(this.gJf(this),z.call$2(this.gtp(this),z.call$2(this.r0,z.call$2(this.tP,z.call$2(this.Ka,1)))))))},
+return z.call$2(this.Fi,z.call$2(this.ku,z.call$2(this.gJf(this),z.call$2(this.gtp(this),z.call$2(this.r0,z.call$2(this.tP,z.call$2(this.Ka,1)))))))},
 n3:function(a,b,c,d,e,f,g,h,i){var z=J.x(h)
 if(z.n(h,"http")&&J.de(e,80))this.HC=0
 else if(z.n(h,"https")&&J.de(e,443))this.HC=0
 else this.HC=e
 this.r0=this.x6(c,d)},
 $isiD:true,
-static:{"":"Um,B4,Bx,iR,ti,mv,nR,we,jR,Qq,O2w,ux,vI,SF,Nv,IL,Q5,zk,om,pk,O5,eq,qf,ML,y3,Pk,R1,oe,lL,I9,t2,H5,zst,eK,bf,Sp,nU,uj,Ai,ne",r6:function(a){var z,y,x,w,v,u,t,s
+static:{"^":"Um,KU,Bx,iR,ti,My,nR,jJY,d2,Qq,q7,ux,vI,SF,fd,IL,Q5,zk,om,fC,O5,eq,qf,ML,y3,Pk,R1,qs,lL,I9,t2,H5,wb,eK,ws,Sp,jH,Qd,Ai,ne",r6:function(a){var z,y,x,w,v,u,t,s
 z=a.QK
 if(1>=z.length)return H.e(z,1)
 y=z[1]
@@ -15379,9 +15528,7 @@
 return u},R6:function(a,b,c,d,e,f,g,h,i){var z=P.iy(h)
 z=new P.iD(P.L7(b),null,null,z,i,P.LE(f,g),P.UJ(a),null,null)
 z.n3(a,b,c,d,e,f,g,h,i)
-return z},uo:function(){var z=H.mz()
-if(z!=null)return P.r6($.cO().ej(z))
-throw H.b(P.f("'Uri.base' is not supported"))},i8:[function(a,b){a.aN(a,new P.In(b))},"call$2","Lq",4,0,null,195,196],L7:[function(a){var z,y,x
+return z},L7:[function(a){var z,y,x
 if(a==null||J.FN(a)===!0)return a
 z=J.rY(a)
 if(z.j(a,0)===91){if(z.j(a,J.xH(z.gB(a),1))!==93)throw H.b(P.cD("Missing end `]` to match `[` in host"))
@@ -15391,7 +15538,7 @@
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
 if(z.j(a,y)===58){P.eg(a)
-return"["+H.d(a)+"]"}++y}return a},"call$1","jC",2,0,null,197],iy:[function(a){var z,y,x,w,v,u,t,s
+return"["+H.d(a)+"]"}++y}return a},"call$1","jC",2,0,null,195,[]],iy:[function(a){var z,y,x,w,v,u,t,s
 z=new P.hb()
 y=new P.XX()
 if(a==null)return""
@@ -15406,7 +15553,7 @@
 s=!s}else s=!1
 if(s)throw H.b(new P.AT("Illegal scheme: "+H.d(a)))
 if(z.call$1(t)!==!0){if(y.call$1(t)===!0);else throw H.b(new P.AT("Illegal scheme: "+H.d(a)))
-v=!1}}return v?a:x.hc(a)},"call$1","oL",2,0,null,198],LE:[function(a,b){var z,y,x
+v=!1}}return v?a:x.hc(a)},"call$1","oL",2,0,null,196,[]],LE:[function(a,b){var z,y,x
 z={}
 y=a==null
 if(y&&!0)return""
@@ -15415,8 +15562,8 @@
 x=P.p9("")
 z.a=!0
 C.jN.aN(b,new P.yZ(z,x))
-return x.vM},"call$2","wF",4,0,null,199,200],UJ:[function(a){if(a==null)return""
-return P.Xc(a)},"call$1","p7",2,0,null,201],Xc:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
+return x.vM},"call$2","wF",4,0,null,197,[],198,[]],UJ:[function(a){if(a==null)return""
+return P.Xc(a)},"call$1","p7",2,0,null,199,[]],Xc:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z={}
 y=new P.Gs()
 x=new P.Tw()
@@ -15463,14 +15610,14 @@
 r=n}if(z.a!=null&&z.c!==r)s.call$0()
 z=z.a
 if(z==null)return a
-return J.AG(z)},"call$1","ZX",2,0,null,202],n7:[function(a){if(a!=null&&!J.de(a,""))return H.BU(a,null,null)
-else return 0},"call$1","dl",2,0,null,203],K6:[function(a,b){if(a!=null)return a
+return J.AG(z)},"call$1","Sy",2,0,null,200,[]],n7:[function(a){if(a!=null&&!J.de(a,""))return H.BU(a,null,null)
+else return 0},"call$1","dl",2,0,null,201,[]],K6:[function(a,b){if(a!=null)return a
 if(b!=null)return b
-return""},"call$2","xX",4,0,null,204,205],Mt:[function(a){return P.pE(a,C.xM,!1)},"call$1","t9",2,0,206,207],q5:[function(a){var z,y
+return""},"call$2","xX",4,0,null,202,[],203,[]],q5:[function(a){var z,y
 z=new P.Mx()
 y=a.split(".")
 if(y.length!==4)z.call$1("IPv4 address should contain exactly 4 parts")
-return H.VM(new H.A8(y,new P.C9(z)),[null,null]).br(0)},"call$1","cf",2,0,null,197],eg:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
+return H.VM(new H.A8(y,new P.C9(z)),[null,null]).br(0)},"call$1","cf",2,0,null,195,[]],eg:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
 z=new P.kZ()
 y=new P.JT(a,z)
 if(J.u6(J.q8(a),2))z.call$1("address is too short")
@@ -15503,7 +15650,7 @@
 z.call$1("invalid end of IPv6 address.")}}if(u){if(J.q8(x)>7)z.call$1("an address with a wildcard must have less than 7 parts")}else if(J.q8(x)!==8)z.call$1("an address without a wildcard must contain exactly 8 parts")
 s=new H.kV(x,new P.d9(x))
 s.$builtinTypeInfo=[null,null]
-return P.F(s,!0,H.ip(s,"mW",0))},"call$1","kS",2,0,null,197],jW:[function(a,b,c,d){var z,y,x,w,v,u,t,s
+return P.F(s,!0,H.ip(s,"mW",0))},"call$1","y9",2,0,null,195,[]],jW:[function(a,b,c,d){var z,y,x,w,v,u,t,s
 z=new P.rI()
 y=P.p9("")
 x=c.gZE().WJ(b)
@@ -15519,62 +15666,29 @@
 y.vM=y.vM+u}else{s=P.O8(1,37,J.im)
 u=H.eT(s)
 y.vM=y.vM+u
-z.call$2(v,y)}}return y.vM},"call$4$encoding$spaceToPlus","jd",4,5,null,208,209,210,211,212,213],oh:[function(a,b){var z,y,x,w
-for(z=J.rY(a),y=0,x=0;x<2;++x){w=z.j(a,b+x)
-if(48<=w&&w<=57)y=y*16+w-48
-else{w|=32
-if(97<=w&&w<=102)y=y*16+w-87
-else throw H.b(new P.AT("Invalid URL encoding"))}}return y},"call$2","Mm",4,0,null,86,214],pE:[function(a,b,c){var z,y,x,w,v,u,t
-z=J.U6(a)
-y=!0
-x=0
-while(!0){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(!(x<w&&y))break
-v=z.j(a,x)
-y=v!==37&&v!==43;++x}if(y)if(b===C.xM||!1)return a
-else u=z.gZm(a)
-else{u=[]
-x=0
-while(!0){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(!(x<w))break
-v=z.j(a,x)
-if(v>127)throw H.b(new P.AT("Illegal percent encoding in URI"))
-if(v===37){w=z.gB(a)
-if(typeof w!=="number")return H.s(w)
-if(x+3>w)throw H.b(new P.AT("Truncated URI"))
-u.push(P.oh(a,x+1))
-x+=2}else if(c&&v===43)u.push(32)
-else u.push(v);++x}}t=b.lH
-return new P.GY(t).WJ(u)},"call$3$encoding$plusToSpace","Ci",2,5,null,208,209,211,212,215]}},
-In:{
-"":"Tp:229;a",
-call$1:[function(a){if(J.kE(a,"/")===!0)if(this.a)throw H.b(new P.AT("Illegal path character "+H.d(a)))
-else throw H.b(P.f("Illegal path character "+H.d(a)))},"call$1",null,2,0,null,441,"call"],
-$isEH:true},
+z.call$2(v,y)}}return y.vM},"call$4$encoding$spaceToPlus","jd",4,5,null,204,205,206,[],207,[],208,[],209,[]]}},
 hb:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=a>>>4
 if(z>=8)return H.e(C.HE,z)
 z=(C.HE[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 XX:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=a>>>4
 if(z>=8)return H.e(C.mK,z)
 z=(C.mK[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 Kd:{
-"":"Tp:229;",
-call$1:[function(a){return P.jW(C.Wd,a,C.xM,!1)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return P.jW(C.Wd,a,C.xM,!1)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 yZ:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z=this.a
 if(!z.a)this.b.KF("&")
 z.a=!1
@@ -15582,47 +15696,47 @@
 z.KF(P.jW(C.kg,a,C.xM,!0))
 b.gl0(b)
 z.KF("=")
-z.KF(P.jW(C.kg,b,C.xM,!0))},"call$2",null,4,0,null,42,23,"call"],
+z.KF(P.jW(C.kg,b,C.xM,!0))},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 Gs:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(!(48<=a&&a<=57))z=65<=a&&a<=70
 else z=!0
-return z},"call$1",null,2,0,null,444,"call"],
+return z},"call$1",null,2,0,null,438,[],"call"],
 $isEH:true},
 pm:{
-"":"Tp:443;",
-call$1:[function(a){return 97<=a&&a<=102},"call$1",null,2,0,null,444,"call"],
+"^":"Tp:437;",
+call$1:[function(a){return 97<=a&&a<=102},"call$1",null,2,0,null,438,[],"call"],
 $isEH:true},
 Tw:{
-"":"Tp:443;",
+"^":"Tp:437;",
 call$1:[function(a){var z
 if(a<128){z=C.jn.GG(a,4)
 if(z>=8)return H.e(C.kg,z)
 z=(C.kg[z]&C.jn.W4(1,a&15))!==0}else z=!1
-return z},"call$1",null,2,0,null,442,"call"],
+return z},"call$1",null,2,0,null,436,[],"call"],
 $isEH:true},
 wm:{
-"":"Tp:445;b,c,d",
+"^":"Tp:439;b,c,d",
 call$1:[function(a){var z,y
 z=this.b
 y=J.lE(z,a)
 if(this.d.call$1(y)===!0)return y-32
 else if(this.c.call$1(y)!==!0)throw H.b(new P.AT("Invalid URI component: "+H.d(z)))
-else return y},"call$1",null,2,0,null,47,"call"],
+else return y},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 FB:{
-"":"Tp:445;e",
+"^":"Tp:439;e",
 call$1:[function(a){var z,y,x,w,v
 for(z=this.e,y=J.rY(z),x=0,w=0;w<2;++w){v=y.j(z,a+w)
 if(48<=v&&v<=57)x=x*16+v-48
 else{v|=32
 if(97<=v&&v<=102)x=x*16+v-97+10
-else throw H.b(new P.AT("Invalid percent-encoding in URI component: "+H.d(z)))}}return x},"call$1",null,2,0,null,47,"call"],
+else throw H.b(new P.AT("Invalid percent-encoding in URI component: "+H.d(z)))}}return x},"call$1",null,2,0,null,47,[],"call"],
 $isEH:true},
 Lk:{
-"":"Tp:107;a,f",
+"^":"Tp:107;a,f",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 y=z.a
@@ -15633,52 +15747,54 @@
 else y.KF(J.Nj(w,x,v))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 XZ:{
-"":"Tp:447;",
-call$2:[function(a,b){return b*31+J.v1(a)&1073741823},"call$2",null,4,0,null,446,245,"call"],
+"^":"Tp:441;",
+call$2:[function(a,b){var z=J.v1(a)
+if(typeof z!=="number")return H.s(z)
+return b*31+z&1073741823},"call$2",null,4,0,null,440,[],240,[],"call"],
 $isEH:true},
 Mx:{
-"":"Tp:174;",
-call$1:[function(a){throw H.b(P.cD("Illegal IPv4 address, "+a))},"call$1",null,2,0,null,19,"call"],
+"^":"Tp:174;",
+call$1:[function(a){throw H.b(P.cD("Illegal IPv4 address, "+a))},"call$1",null,2,0,null,19,[],"call"],
 $isEH:true},
 C9:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y
 z=H.BU(a,null,null)
 y=J.Wx(z)
 if(y.C(z,0)||y.D(z,255))this.a.call$1("each part must be in the range of `0..255`")
-return z},"call$1",null,2,0,null,448,"call"],
+return z},"call$1",null,2,0,null,442,[],"call"],
 $isEH:true},
 kZ:{
-"":"Tp:174;",
-call$1:[function(a){throw H.b(P.cD("Illegal IPv6 address, "+a))},"call$1",null,2,0,null,19,"call"],
+"^":"Tp:174;",
+call$1:[function(a){throw H.b(P.cD("Illegal IPv6 address, "+a))},"call$1",null,2,0,null,19,[],"call"],
 $isEH:true},
 JT:{
-"":"Tp:449;a,b",
+"^":"Tp:443;a,b",
 call$2:[function(a,b){var z,y
 if(J.z8(J.xH(b,a),4))this.b.call$1("an IPv6 part can only contain a maximum of 4 hex digits")
 z=H.BU(J.Nj(this.a,a,b),16,null)
 y=J.Wx(z)
 if(y.C(z,0)||y.D(z,65535))this.b.call$1("each part must be in the range of `0x0..0xFFFF`")
-return z},"call$2",null,4,0,null,115,116,"call"],
+return z},"call$2",null,4,0,null,115,[],116,[],"call"],
 $isEH:true},
 d9:{
-"":"Tp:229;c",
+"^":"Tp:223;c",
 call$1:[function(a){var z=J.x(a)
 if(z.n(a,-1))return P.O8((9-this.c.length)*2,0,null)
-else return[z.m(a,8)&255,z.i(a,255)]},"call$1",null,2,0,null,23,"call"],
+else return[z.m(a,8)&255,z.i(a,255)]},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 rI:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){var z=J.Wx(a)
 b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.m(a,4))))
-b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.i(a,15))))},"call$2",null,4,0,null,450,451,"call"],
+b.KF(P.fc(C.xB.j("0123456789ABCDEF",z.i(a,15))))},"call$2",null,4,0,null,444,[],445,[],"call"],
 $isEH:true}}],["dart.dom.html","dart:html",,W,{
-"":"",
+"^":"",
 UE:[function(a){if(P.F7()===!0)return"webkitTransitionEnd"
 else if(P.dg()===!0)return"oTransitionEnd"
-return"transitionend"},"call$1","pq",2,0,216,18],
-r3:[function(a,b){return document.createElement(a)},"call$2","Oe",4,0,null,94,217],
-It:[function(a,b,c){return W.lt(a,null,null,b,null,null,null,c).ml(new W.Kx())},"call$3$onProgress$withCredentials","xF",2,5,null,77,77,218,219,220],
+return"transitionend"},"call$1","pq",2,0,210,18,[]],
+r3:[function(a,b){return document.createElement(a)},"call$2","Oe",4,0,null,94,[],211,[]],
+It:[function(a,b,c){return W.lt(a,null,null,b,null,null,null,c).ml(new W.Kx())},"call$3$onProgress$withCredentials","xF",2,5,null,77,77,212,[],213,[],214,[]],
 lt:[function(a,b,c,d,e,f,g,h){var z,y,x
 z=W.zU
 y=H.VM(new P.Zf(P.Dt(z)),[z])
@@ -15689,33 +15805,33 @@
 z=C.MD.aM(x)
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(y.gYJ()),z.Sg),[H.Kp(z,0)]).Zz()
 x.send()
-return y.MM},"call$8$method$mimeType$onProgress$requestHeaders$responseType$sendData$withCredentials","Za",2,15,null,77,77,77,77,77,77,77,218,221,222,219,223,224,225,220],
+return y.MM},"call$8$method$mimeType$onProgress$requestHeaders$responseType$sendData$withCredentials","Za",2,15,null,77,77,77,77,77,77,77,212,[],215,[],216,[],213,[],217,[],218,[],219,[],214,[]],
 ED:function(a){var z,y
 z=document.createElement("input",null)
-if(a!=null)try{J.cW(z,a)}catch(y){H.Ru(y)}return z},
+if(a!=null)try{J.Lp(z,a)}catch(y){H.Ru(y)}return z},
 uC:[function(a){var z,y,x
 try{z=a
 y=J.x(z)
 return typeof z==="object"&&z!==null&&!!y.$iscS}catch(x){H.Ru(x)
-return!1}},"call$1","e8",2,0,null,226],
+return!1}},"call$1","iJ",2,0,null,220,[]],
 Pv:[function(a){if(a==null)return
-return W.P1(a)},"call$1","Ie",2,0,null,227],
+return W.P1(a)},"call$1","Ie",2,0,null,221,[]],
 qc:[function(a){var z,y
 if(a==null)return
 if("setInterval" in a){z=W.P1(a)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isD0)return z
-return}else return a},"call$1","Wq",2,0,null,18],
-qr:[function(a){return a},"call$1","Ku",2,0,null,18],
-YT:[function(a,b){return new W.vZ(a,b)},"call$2","AD",4,0,null,228,7],
-GO:[function(a){return J.TD(a)},"call$1","V5",2,0,229,41],
-Yb:[function(a){return J.Vq(a)},"call$1","cn",2,0,229,41],
-Qp:[function(a,b,c,d){return J.qd(a,b,c,d)},"call$4","A6",8,0,230,41,12,231,232],
+return}else return a},"call$1","Wq",2,0,null,18,[]],
+qr:[function(a){return a},"call$1","Ku",2,0,null,18,[]],
+YT:[function(a,b){return new W.vZ(a,b)},"call$2","AD",4,0,null,222,[],7,[]],
+GO:[function(a){return J.TD(a)},"call$1","V5",2,0,223,41,[]],
+Yb:[function(a){return J.Vq(a)},"call$1","cn",2,0,223,41,[]],
+Qp:[function(a,b,c,d){return J.qd(a,b,c,d)},"call$4","A6",8,0,224,41,[],12,[],225,[],226,[]],
 wi:[function(a,b,c,d,e){var z,y,x,w,v,u,t,s,r,q
-z=J.Fb(d)
+z=J.Xr(d)
 if(z==null)throw H.b(new P.AT(d))
 y=z.prototype
-x=J.Dp(d,"created")
+x=J.Nq(d,"created")
 if(x==null)throw H.b(new P.AT(H.d(d)+" has no constructor called 'created'"))
 J.ks(W.r3("article",null))
 w=z.$nativeSuperclassTag
@@ -15729,12 +15845,12 @@
                return invokeCallback(this);
              };
           })(H.tR(W.YT(x,y),1)))}
-t.enteredViewCallback={value: ((function(invokeCallback) {
+t.attachedCallback={value: ((function(invokeCallback) {
              return function() {
                return invokeCallback(this);
              };
           })(H.tR(W.V5(),1)))}
-t.leftViewCallback={value: ((function(invokeCallback) {
+t.detachedCallback={value: ((function(invokeCallback) {
              return function() {
                return invokeCallback(this);
              };
@@ -15749,16 +15865,17 @@
 Object.defineProperty(s, init.dispatchPropertyName, {value: r, enumerable: false, writable: true, configurable: true})
 q={prototype: s}
 if(!v)q.extends=e
-b.register(c,q)},"call$5","uz",10,0,null,89,233,94,11,234],
+b.registerElement(c,q)},"call$5","uz",10,0,null,89,[],227,[],94,[],11,[],228,[]],
 aF:[function(a){if(J.de($.X3,C.NU))return a
-return $.X3.oj(a,!0)},"call$1","Rj",2,0,null,150],
-Iq:[function(a){if(J.de($.X3,C.NU))return a
-return $.X3.PT(a,!0)},"call$1","eE",2,0,null,150],
+if(a==null)return
+return $.X3.oj(a,!0)},"call$1","Rj",2,0,null,148,[]],
+K2:[function(a){if(J.de($.X3,C.NU))return a
+return $.X3.PT(a,!0)},"call$1","dB",2,0,null,148,[]],
 qE:{
-"":"cv;",
-"%":"HTMLAppletElement|HTMLBRElement|HTMLBaseFontElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLHRElement|HTMLHeadElement|HTMLHeadingElement|HTMLHtmlElement|HTMLMarqueeElement|HTMLMenuElement|HTMLModElement|HTMLOptGroupElement|HTMLParagraphElement|HTMLPreElement|HTMLQuoteElement|HTMLShadowElement|HTMLSpanElement|HTMLTableCaptionElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableDataCellElement|HTMLTableElement|HTMLTableHeaderCellElement|HTMLTableRowElement|HTMLTableSectionElement|HTMLTitleElement|HTMLUListElement|HTMLUnknownElement;HTMLElement;Sa|Ao|ir|LP|uL|Vf|G6|Ds|xI|kf|pv|Ps|CN|Vfx|vc|Dsd|i6|tuj|FvP|Vct|Ir|m8|D13|jM|DKl|WZq|mk|pva|NM|pR|cda|hx|u7|waa|E7|V0|St|V4|vj|LU|V6|CX|PF|qT|V10|Xd|V11|F1|XP|NQ|knI|V12|fI|V13|nm|V14|Vu"},
+"^":"cv;",
+"%":"HTMLAppletElement|HTMLBRElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLHRElement|HTMLHeadElement|HTMLHeadingElement|HTMLHtmlElement|HTMLMarqueeElement|HTMLMenuElement|HTMLModElement|HTMLOptGroupElement|HTMLParagraphElement|HTMLPreElement|HTMLQuoteElement|HTMLShadowElement|HTMLSpanElement|HTMLTableCaptionElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableDataCellElement|HTMLTableHeaderCellElement|HTMLTitleElement|HTMLUListElement|HTMLUnknownElement;HTMLElement;jpR|GN|ir|LP|uL|Vf|G6|Ds|xI|Tg|pv|Ps|CN|Vfx|vc|Dsd|i6|tuj|Fv|Vct|E9|m8|D13|Gk|GG|WZq|yb|pva|NM|T5|pR|cda|hx|u7|waa|E7|V0|St|V4|vj|LU|V10|T2|PF|qT|V11|Xd|V12|F1|XP|JG|qe|knI|V13|fI|V14|nm|V15|Vu"},
 SV:{
-"":"Gv;",
+"^":"Gv;",
 $isList:true,
 $asWO:function(){return[W.M5]},
 $isyN:true,
@@ -15766,90 +15883,87 @@
 $ascX:function(){return[W.M5]},
 "%":"EntryArray"},
 Gh:{
-"":"qE;N:target=,t5:type%,cC:hash%,mH:href=",
+"^":"qE;N:target=,t5:type%,cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $isGv:true,
 "%":"HTMLAnchorElement"},
-fY:{
-"":"qE;N:target=,cC:hash%,mH:href=",
+na:{
+"^":"qE;N:target=,cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $isGv:true,
 "%":"HTMLAreaElement"},
 Xk:{
-"":"qE;mH:href=,N:target=",
+"^":"qE;mH:href=,N:target=",
 "%":"HTMLBaseElement"},
 W2:{
-"":"ea;O3:url=",
+"^":"ea;O3:url=",
 "%":"BeforeLoadEvent"},
 Az:{
-"":"Gv;t5:type=",
+"^":"Gv;t5:type=",
 $isAz:true,
 "%":";Blob"},
 QP:{
-"":"qE;",
+"^":"qE;",
 $isD0:true,
 $isGv:true,
 "%":"HTMLBodyElement"},
 QW:{
-"":"qE;MB:form=,oc:name%,t5:type%,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,t5:type%,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLButtonElement"},
-OM:{
-"":"uH;Rn:data=,B:length=",
+nx:{
+"^":"KV;Rn:data=,B:length=",
 $isGv:true,
 "%":"Comment;CharacterData"},
 QQ:{
-"":"ea;tT:code=",
+"^":"ea;tT:code=",
 "%":"CloseEvent"},
-wT:{
-"":"Mf;Rn:data=",
+di:{
+"^":"Mf;Rn:data=",
 "%":"CompositionEvent"},
-oJ:{
-"":"BV;B:length=",
-T2:[function(a,b){var z=a.getPropertyValue(b)
-return z!=null?z:""},"call$1","gVw",2,0,null,63],
-"%":"CSS2Properties|CSSStyleDeclaration|MSStyleCSSProperties"},
-DG:{
-"":"ea;",
+He:{
+"^":"ea;",
 gey:function(a){var z=a._dartDetail
 if(z!=null)return z
 return P.o7(a.detail,!0)},
-$isDG:true,
+$isHe:true,
 "%":"CustomEvent"},
-bY:{
-"":"qE;bG:options=",
+vHT:{
+"^":"qE;bG:options=",
 "%":"HTMLDataListElement"},
 QF:{
-"":"uH;",
+"^":"KV;",
 JP:[function(a){return a.createDocumentFragment()},"call$0","gf8",0,0,null],
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
-ek:[function(a,b,c){return a.importNode(b,c)},"call$2","gPp",2,2,null,77,294,295],
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
+ek:[function(a,b,c){return a.importNode(b,c)},"call$2","gPp",2,2,null,77,259,[],289,[]],
 gi9:function(a){return C.mt.aM(a)},
-gVl:function(a){return C.T1.aM(a)},
+gVl:function(a){return C.pi.aM(a)},
 gLm:function(a){return C.i3.aM(a)},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 $isQF:true,
 "%":"Document|HTMLDocument|SVGDocument"},
-hN:{
-"":"uH;",
-gwd:function(a){if(a._children==null)a._children=H.VM(new P.D7(a,new W.e7(a)),[null])
-return a._children},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+Aj:{
+"^":"KV;",
+gwd:function(a){if(a._docChildren==null)a._docChildren=H.VM(new P.D7(a,new W.e7(a)),[null])
+return a._docChildren},
+swd:function(a,b){var z,y,x
+z=P.F(b,!0,null)
+y=this.gwd(a)
+x=J.w1(y)
+x.V1(y)
+x.FV(y,z)},
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 $isGv:true,
 "%":";DocumentFragment"},
-SL:{
-"":"uH;",
-$isGv:true,
-"%":"DocumentType"},
-rv:{
-"":"Gv;G1:message=,oc:name=",
+cm:{
+"^":"Gv;G1:message=,oc:name=",
 "%":";DOMError"},
 Nh:{
-"":"Gv;G1:message=",
+"^":"Gv;G1:message=",
 goc:function(a){var z=a.name
 if(P.F7()===!0&&z==="SECURITY_ERR")return"SecurityError"
 if(P.F7()===!0&&z==="SYNTAX_ERR")return"SyntaxError"
@@ -15858,16 +15972,21 @@
 $isNh:true,
 "%":"DOMException"},
 cv:{
-"":"uH;xr:className%,jO:id%",
+"^":"KV;xr:className%,jO:id%",
 gQg:function(a){return new W.i7(a)},
 gwd:function(a){return new W.VG(a,a.children)},
-Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,296],
-Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,297],
-pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gds",2,0,null,297],
+swd:function(a,b){var z,y
+z=P.F(b,!0,null)
+y=this.gwd(a)
+y.V1(0)
+y.FV(0,z)},
+Md:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gnk",2,0,null,290,[]],
+Ja:[function(a,b){return a.querySelector(b)},"call$1","gtP",2,0,null,291,[]],
+pr:[function(a,b){return W.vD(a.querySelectorAll(b),null)},"call$1","gTU",2,0,null,291,[]],
 gDD:function(a){return new W.I4(a)},
 i4:[function(a){},"call$0","gQd",0,0,null],
 xo:[function(a){},"call$0","gbt",0,0,null],
-aC:[function(a,b,c,d){},"call$3","gxR",6,0,null,12,231,232],
+aC:[function(a,b,c,d){},"call$3","gxR",6,0,null,12,[],225,[],226,[]],
 gqn:function(a){return a.localName},
 bu:[function(a){return a.localName},"call$0","gXo",0,0,null],
 WO:[function(a,b){if(!!a.matches)return a.matches(b)
@@ -15875,16 +15994,16 @@
 else if(!!a.mozMatchesSelector)return a.mozMatchesSelector(b)
 else if(!!a.msMatchesSelector)return a.msMatchesSelector(b)
 else if(!!a.oMatchesSelector)return a.oMatchesSelector(b)
-else throw H.b(P.f("Not supported on this platform"))},"call$1","grM",2,0,null,296],
+else throw H.b(P.f("Not supported on this platform"))},"call$1","grM",2,0,null,290,[]],
 bA:[function(a,b){var z=a
 do{if(J.RF(z,b))return!0
 z=z.parentElement}while(z!=null)
-return!1},"call$1","gMn",2,0,null,296],
+return!1},"call$1","gMn",2,0,null,290,[]],
 er:[function(a){return(a.createShadowRoot||a.webkitCreateShadowRoot).call(a)},"call$0","gzd",0,0,null],
 gKE:function(a){return a.shadowRoot||a.webkitShadowRoot},
 gI:function(a){return new W.DM(a,a)},
 gi9:function(a){return C.mt.f0(a)},
-gVl:function(a){return C.T1.f0(a)},
+gVl:function(a){return C.pi.f0(a)},
 gLm:function(a){return C.i3.f0(a)},
 ZL:function(a){},
 $iscv:true,
@@ -15892,161 +16011,159 @@
 $isD0:true,
 "%":";Element"},
 Fs:{
-"":"qE;oc:name%,LA:src=,t5:type%",
+"^":"qE;oc:name%,LA:src=,t5:type%",
 "%":"HTMLEmbedElement"},
 Ty:{
-"":"ea;kc:error=,G1:message=",
+"^":"ea;kc:error=,G1:message=",
 "%":"ErrorEvent"},
 ea:{
-"":"Gv;It:_selector},Xt:bubbles=,t5:type=",
+"^":"Gv;It:_selector},Xt:bubbles=,t5:type=",
 gN:function(a){return W.qc(a.target)},
 $isea:true,
 "%":"AudioProcessingEvent|AutocompleteErrorEvent|BeforeUnloadEvent|CSSFontFaceLoadEvent|DeviceMotionEvent|DeviceOrientationEvent|HashChangeEvent|IDBVersionChangeEvent|MIDIConnectionEvent|MediaKeyNeededEvent|MediaStreamEvent|MediaStreamTrackEvent|MutationEvent|OfflineAudioCompletionEvent|OverflowEvent|PageTransitionEvent|PopStateEvent|RTCDTMFToneChangeEvent|RTCDataChannelEvent|RTCIceCandidateEvent|SecurityPolicyViolationEvent|SpeechInputEvent|SpeechRecognitionEvent|TrackEvent|WebGLContextEvent|WebKitAnimationEvent;Event"},
 D0:{
-"":"Gv;",
+"^":"Gv;",
 gI:function(a){return new W.Jn(a)},
-On:[function(a,b,c,d){return a.addEventListener(b,H.tR(c,1),d)},"call$3","gNe",4,2,null,77,11,298,299],
-Y9:[function(a,b,c,d){return a.removeEventListener(b,H.tR(c,1),d)},"call$3","gcF",4,2,null,77,11,298,299],
+On:[function(a,b,c,d){return a.addEventListener(b,H.tR(c,1),d)},"call$3","gIV",4,2,null,77,11,[],292,[],293,[]],
+Y9:[function(a,b,c,d){return a.removeEventListener(b,H.tR(c,1),d)},"call$3","gcF",4,2,null,77,11,[],292,[],293,[]],
 $isD0:true,
 "%":";EventTarget"},
 as:{
-"":"qE;MB:form=,oc:name%,t5:type=",
+"^":"qE;MB:form=,oc:name%,t5:type=",
 "%":"HTMLFieldSetElement"},
 hH:{
-"":"Az;oc:name=",
+"^":"Az;oc:name=",
 $ishH:true,
 "%":"File"},
-QU:{
-"":"rv;tT:code=",
+Aa:{
+"^":"cm;tT:code=",
 "%":"FileError"},
-Yu:{
-"":"qE;B:length=,bP:method=,oc:name%,N:target=",
+h4:{
+"^":"qE;B:length=,bP:method=,oc:name%,N:target=",
 "%":"HTMLFormElement"},
-Cv:{
-"":"ma;",
+wa:{
+"^":"Gb;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"HTMLCollection|HTMLFormControlsCollection|HTMLOptionsCollection"},
 zU:{
-"":"wa;iC:responseText=,ys:status=,po:statusText=",
-R3:[function(a,b,c,d,e,f){return a.open(b,c,d,f,e)},function(a,b,c,d){return a.open(b,c,d)},"eo","call$5$async$password$user",null,"gqO",4,7,null,77,77,77,221,218,300,301,302],
-wR:[function(a,b){return a.send(b)},"call$1","gX8",0,2,null,77,237],
+"^":"pk;iC:responseText=,ys:status=,po:statusText=",
+R3:[function(a,b,c,d,e,f){return a.open(b,c,d,f,e)},function(a,b,c,d){return a.open(b,c,d)},"eo","call$5$async$password$user",null,"gcY",4,7,null,77,77,77,215,[],212,[],294,[],295,[],296,[]],
+wR:[function(a,b){return a.send(b)},"call$1","gX8",0,2,null,77,231,[]],
 $iszU:true,
 "%":"XMLHttpRequest"},
-wa:{
-"":"D0;",
+pk:{
+"^":"D0;",
 "%":";XMLHttpRequestEventTarget"},
 tX:{
-"":"qE;oc:name%,LA:src=",
+"^":"qE;oc:name%,LA:src=",
 "%":"HTMLIFrameElement"},
 Sg:{
-"":"Gv;Rn:data=",
+"^":"Gv;Rn:data=",
 $isSg:true,
 "%":"ImageData"},
 pA:{
-"":"qE;LA:src=",
-tZ:function(a){return this.complete.call$0()},
-oo:function(a,b){return this.complete.call$1(b)},
+"^":"qE;LA:src=",
+oo:function(a,b){return a.complete.call$1(b)},
 "%":"HTMLImageElement"},
 Mi:{
-"":"qE;Tq:checked%,MB:form=,aK:list=,oc:name%,LA:src=,t5:type%,P:value%",
-RR:function(a,b){return this.accept.call$1(b)},
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;Tq:checked%,MB:form=,aK:list=,oc:name%,LA:src=,t5:type%,P:value%",
+RR:function(a,b){return a.accept.call$1(b)},
+r6:function(a,b){return a.value.call$1(b)},
 $isMi:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true,
+$isKV:true,
 "%":"HTMLInputElement"},
-ttH:{
-"":"qE;MB:form=,oc:name%,t5:type=",
+In:{
+"^":"qE;MB:form=,oc:name%,t5:type=",
 "%":"HTMLKeygenElement"},
 wP:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLLIElement"},
 eP:{
-"":"qE;MB:form=",
+"^":"qE;MB:form=",
 "%":"HTMLLabelElement"},
 mF:{
-"":"qE;MB:form=",
+"^":"qE;MB:form=",
 "%":"HTMLLegendElement"},
 Qj:{
-"":"qE;mH:href=,t5:type%",
+"^":"qE;mH:href=,t5:type%",
 $isQj:true,
 "%":"HTMLLinkElement"},
 cS:{
-"":"Gv;cC:hash%,mH:href=",
+"^":"Gv;cC:hash%,mH:href=",
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 $iscS:true,
 "%":"Location"},
-M6:{
-"":"qE;oc:name%",
+YI:{
+"^":"qE;oc:name%",
 "%":"HTMLMapElement"},
 El:{
-"":"qE;kc:error=,LA:src=",
-yy:[function(a){return a.pause()},"call$0","gAK",0,0,null],
+"^":"qE;kc:error=,LA:src=",
 "%":"HTMLAudioElement|HTMLMediaElement|HTMLVideoElement"},
 zm:{
-"":"Gv;tT:code=",
+"^":"Gv;tT:code=",
 "%":"MediaError"},
 Y7:{
-"":"Gv;tT:code=",
+"^":"Gv;tT:code=",
 "%":"MediaKeyError"},
 aB:{
-"":"ea;G1:message=",
+"^":"ea;G1:message=",
 "%":"MediaKeyEvent"},
 fJ:{
-"":"ea;G1:message=",
+"^":"ea;G1:message=",
 "%":"MediaKeyMessageEvent"},
 Rv:{
-"":"D0;jO:id=",
+"^":"D0;jO:id=",
 "%":"MediaStream"},
 DD:{
-"":"ea;",
+"^":"ea;",
 gRn:function(a){return P.o7(a.data,!0)},
 $isDD:true,
 "%":"MessageEvent"},
-la:{
-"":"qE;jb:content=,oc:name%",
+EeC:{
+"^":"qE;jb:content=,oc:name%",
 "%":"HTMLMetaElement"},
 Qb:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLMeterElement"},
 Hw:{
-"":"ea;Rn:data=",
+"^":"ea;Rn:data=",
 "%":"MIDIMessageEvent"},
 bn:{
-"":"tH;",
-A8:[function(a,b,c){return a.send(b,c)},function(a,b){return a.send(b)},"wR","call$2",null,"gX8",2,2,null,77,237,303],
+"^":"Imr;",
+LV:[function(a,b,c){return a.send(b,c)},function(a,b){return a.send(b)},"wR","call$2",null,"gX8",2,2,null,77,231,[],297,[]],
 "%":"MIDIOutput"},
-tH:{
-"":"D0;jO:id=,oc:name=,t5:type=",
+Imr:{
+"^":"D0;jO:id=,oc:name=,t5:type=",
 "%":"MIDIInput;MIDIPort"},
-Aj:{
-"":"Mf;",
+Oq:{
+"^":"Mf;",
 nH:[function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){a.initMouseEvent(b,c,d,e,f,g,h,i,j,k,l,m,n,o,W.qr(p))
-return},"call$15","gEx",30,0,null,11,304,305,306,307,308,309,310,311,312,313,314,315,316,317],
-$isAj:true,
+return},"call$15","gEx",30,0,null,11,[],298,[],299,[],300,[],301,[],302,[],303,[],304,[],305,[],306,[],307,[],308,[],309,[],310,[],311,[]],
+$isOq:true,
 "%":"DragEvent|MSPointerEvent|MouseEvent|MouseScrollEvent|MouseWheelEvent|PointerEvent|WheelEvent"},
 H9:{
-"":"Gv;",
+"^":"Gv;",
 jh:[function(a,b,c,d,e,f,g,h,i){var z,y
 z={}
 y=new W.Yg(z)
@@ -16056,155 +16173,167 @@
 y.call$2("subtree",i)
 y.call$2("attributeOldValue",d)
 y.call$2("characterDataOldValue",g)
-a.observe(b,z)},function(a,b,c,d){return this.jh(a,b,null,null,null,null,null,c,d)},"yN","call$8$attributeFilter$attributeOldValue$attributes$characterData$characterDataOldValue$childList$subtree",null,"gTT",2,15,null,77,77,77,77,77,77,77,74,318,319,320,321,322,323,324],
+a.observe(b,z)},function(a,b,c,d){return this.jh(a,b,null,null,null,null,null,c,d)},"yN","call$8$attributeFilter$attributeOldValue$attributes$characterData$characterDataOldValue$childList$subtree",null,"gTT",2,15,null,77,77,77,77,77,77,77,74,[],312,[],313,[],314,[],315,[],316,[],317,[],318,[]],
 "%":"MutationObserver|WebKitMutationObserver"},
 o4:{
-"":"Gv;jL:oldValue=,N:target=,t5:type=",
+"^":"Gv;jL:oldValue=,N:target=,t5:type=",
 "%":"MutationRecord"},
 oU:{
-"":"Gv;",
+"^":"Gv;",
 $isGv:true,
 "%":"Navigator"},
 ih:{
-"":"Gv;G1:message=,oc:name=",
+"^":"Gv;G1:message=,oc:name=",
 "%":"NavigatorUserMediaError"},
-uH:{
-"":"D0;q6:firstChild=,uD:nextSibling=,M0:ownerDocument=,eT:parentElement=,KV:parentNode=,a4:textContent%",
+KV:{
+"^":"D0;q6:firstChild=,uD:nextSibling=,M0:ownerDocument=,eT:parentElement=,KV:parentNode=,a4:textContent%",
 gyT:function(a){return new W.e7(a)},
 wg:[function(a){var z=a.parentNode
 if(z!=null)z.removeChild(a)},"call$0","gRI",0,0,null],
 Tk:[function(a,b){var z,y
 try{z=a.parentNode
-J.ky(z,b,a)}catch(y){H.Ru(y)}return a},"call$1","gdA",2,0,null,325],
+J.ky(z,b,a)}catch(y){H.Ru(y)}return a},"call$1","gdA",2,0,null,319,[]],
 bu:[function(a){var z=a.nodeValue
 return z==null?J.Gv.prototype.bu.call(this,a):z},"call$0","gXo",0,0,null],
-jx:[function(a,b){return a.appendChild(b)},"call$1","gp3",2,0,null,326],
-tg:[function(a,b){return a.contains(b)},"call$1","gdj",2,0,null,104],
-mK:[function(a,b,c){return a.insertBefore(b,c)},"call$2","gHc",4,0,null,326,327],
-dR:[function(a,b,c){return a.replaceChild(b,c)},"call$2","ghn",4,0,null,326,328],
-$isuH:true,
+jx:[function(a,b){return a.appendChild(b)},"call$1","gp3",2,0,null,320,[]],
+tg:[function(a,b){return a.contains(b)},"call$1","gdj",2,0,null,104,[]],
+mK:[function(a,b,c){return a.insertBefore(b,c)},"call$2","gHc",4,0,null,320,[],321,[]],
+dR:[function(a,b,c){return a.replaceChild(b,c)},"call$2","ghn",4,0,null,320,[],322,[]],
+$isKV:true,
 "%":"Entity|Notation;Node"},
 yk:{
-"":"ecX;",
+"^":"ecX;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"NodeList|RadioNodeList"},
 KY:{
-"":"qE;t5:type%",
+"^":"qE;t5:type%",
 "%":"HTMLOListElement"},
 G7:{
-"":"qE;Rn:data=,MB:form=,oc:name%,t5:type%",
+"^":"qE;Rn:data=,MB:form=,oc:name%,t5:type%",
 "%":"HTMLObjectElement"},
 Ql:{
-"":"qE;MB:form=,vH:index=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,vH:index=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 $isQl:true,
 "%":"HTMLOptionElement"},
 Xp:{
-"":"qE;MB:form=,oc:name%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLOutputElement"},
 HD:{
-"":"qE;oc:name%,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;oc:name%,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLParamElement"},
 jg:{
-"":"Gv;tT:code=,G1:message=",
+"^":"Gv;tT:code=,G1:message=",
 "%":"PositionError"},
 nC:{
-"":"OM;N:target=",
+"^":"nx;N:target=",
 "%":"ProcessingInstruction"},
 KR:{
-"":"qE;P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"HTMLProgressElement"},
 ew:{
-"":"ea;",
+"^":"ea;",
 $isew:true,
 "%":"XMLHttpRequestProgressEvent;ProgressEvent"},
 LY:{
-"":"ew;O3:url=",
+"^":"ew;O3:url=",
 "%":"ResourceProgressEvent"},
 j2:{
-"":"qE;LA:src=,t5:type%",
+"^":"qE;LA:src=,t5:type%",
 $isj2:true,
 "%":"HTMLScriptElement"},
 lp:{
-"":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 gbG:function(a){var z=W.vD(a.querySelectorAll("option"),null)
 z=z.ev(z,new W.kI())
 return H.VM(new P.Yp(P.F(z,!0,H.ip(z,"mW",0))),[null])},
 $islp:true,
 "%":"HTMLSelectElement"},
 I0:{
-"":"hN;pQ:applyAuthorStyles=",
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
+"^":"Aj;pQ:applyAuthorStyles=",
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
 $isI0:true,
 "%":"ShadowRoot"},
 QR:{
-"":"qE;LA:src=,t5:type%",
+"^":"qE;LA:src=,t5:type%",
 "%":"HTMLSourceElement"},
-Hd:{
-"":"ea;kc:error=,G1:message=",
+zD9:{
+"^":"ea;kc:error=,G1:message=",
 "%":"SpeechRecognitionError"},
 G5:{
-"":"ea;oc:name=",
+"^":"ea;oc:name=",
 "%":"SpeechSynthesisEvent"},
-wb:{
-"":"ea;G3:key=,zZ:newValue=,jL:oldValue=,O3:url=",
+bk:{
+"^":"ea;G3:key=,zZ:newValue=,jL:oldValue=,O3:url=",
 "%":"StorageEvent"},
 fq:{
-"":"qE;t5:type%",
+"^":"qE;t5:type%",
 "%":"HTMLStyleElement"},
+Tb:{
+"^":"qE;",
+gWT:function(a){return H.VM(new W.Of(a.rows),[W.tV])},
+"%":"HTMLTableElement"},
+tV:{
+"^":"qE;",
+$istV:true,
+"%":"HTMLTableRowElement"},
+BT:{
+"^":"qE;",
+gWT:function(a){return H.VM(new W.Of(a.rows),[W.tV])},
+"%":"HTMLTableSectionElement"},
 yY:{
-"":"qE;jb:content=",
+"^":"qE;jb:content=",
 $isyY:true,
 "%":"HTMLTemplateElement"},
 kJ:{
-"":"OM;",
+"^":"nx;",
 $iskJ:true,
 "%":"CDATASection|Text"},
 AE:{
-"":"qE;MB:form=,oc:name%,t5:type=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"qE;MB:form=,oc:name%,WT:rows%,t5:type=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 $isAE:true,
 "%":"HTMLTextAreaElement"},
 xV:{
-"":"Mf;Rn:data=",
+"^":"Mf;Rn:data=",
 "%":"TextEvent"},
 RH:{
-"":"qE;fY:kind%,LA:src=",
+"^":"qE;fY:kind%,LA:src=",
 "%":"HTMLTrackElement"},
 OJ:{
-"":"ea;",
+"^":"ea;",
 $isOJ:true,
 "%":"TransitionEvent|WebKitTransitionEvent"},
 Mf:{
-"":"ea;",
+"^":"ea;",
 "%":"FocusEvent|KeyboardEvent|SVGZoomEvent|TouchEvent;UIEvent"},
 u9:{
-"":"D0;oc:name%,ys:status=",
+"^":"D0;oc:name%,ys:status=",
 gmW:function(a){var z=a.location
 if(W.uC(z)===!0)return z
 if(null==a._location_wrapper)a._location_wrapper=new W.Dk(z)
 return a._location_wrapper},
-oB:[function(a,b){return a.requestAnimationFrame(H.tR(b,1))},"call$1","gfl",2,0,null,150],
+oB:[function(a,b){return a.requestAnimationFrame(H.tR(b,1))},"call$1","gfl",2,0,null,148,[]],
 hr:[function(a){if(!!(a.requestAnimationFrame&&a.cancelAnimationFrame))return
   (function($this) {
    var vendors = ['ms', 'moz', 'webkit', 'o'];
@@ -16225,88 +16354,97 @@
 geT:function(a){return W.Pv(a.parent)},
 cO:[function(a){return a.close()},"call$0","gJK",0,0,null],
 xc:[function(a,b,c,d){a.postMessage(P.bL(b),c)
-return},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,329,330],
+return},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,[],323,[],324,[]],
 bu:[function(a){return a.toString()},"call$0","gXo",0,0,null],
 gi9:function(a){return C.mt.aM(a)},
-gVl:function(a){return C.T1.aM(a)},
+gVl:function(a){return C.pi.aM(a)},
 gLm:function(a){return C.i3.aM(a)},
 $isu9:true,
 $isGv:true,
 $isD0:true,
 "%":"DOMWindow|Window"},
 Bn:{
-"":"uH;oc:name=,P:value%",
-r6:function(a,b){return this.value.call$1(b)},
+"^":"KV;oc:name=,P:value%",
+r6:function(a,b){return a.value.call$1(b)},
 "%":"Attr"},
+hq:{
+"^":"KV;",
+$isGv:true,
+"%":"DocumentType"},
 Nf:{
-"":"qE;",
+"^":"qE;",
 $isD0:true,
 $isGv:true,
 "%":"HTMLFrameSetElement"},
 QV:{
-"":"w1p;",
+"^":"w1p;",
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
 if(b>>>0!==b||b>=z)throw H.b(P.TE(b,0,z))
-return a[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,23],
+return a[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot assign element of immutable List."))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize immutable List."))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
 throw H.b(new P.lj("No elements"))},
 Zv:[function(a,b){if(b>>>0!==b||b>=a.length)return H.e(a,b)
-return a[b]},"call$1","goY",2,0,null,47],
+return a[b]},"call$1","goY",2,0,null,47,[]],
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]},
+$ascX:function(){return[W.KV]},
 $isXj:true,
 "%":"MozNamedAttrMap|NamedNodeMap"},
 QZ:{
-"":"a;",
-Wt:[function(a,b){return typeof console!="undefined"?console.error(b):null},"call$1","gkc",2,0,452,165],
-To:[function(a){return typeof console!="undefined"?console.info(a):null},"call$1","gqa",2,0,null,165],
-De:[function(a,b){return typeof console!="undefined"?console.profile(b):null},"call$1","gB1",2,0,174,453],
-uj:[function(a){return typeof console!="undefined"?console.time(a):null},"call$1","gFl",2,0,174,453],
-WL:[function(a,b){return typeof console!="undefined"?console.trace(b):null},"call$1","gtN",2,0,452,165],
-static:{"":"wk"}},
-BV:{
-"":"Gv+E1;"},
-E1:{
-"":"a;",
-gyP:function(a){return this.T2(a,"clear")},
-V1:function(a){return this.gyP(a).call$0()},
-gjb:function(a){return this.T2(a,"content")},
-gBb:function(a){return this.T2(a,"left")},
-gT8:function(a){return this.T2(a,"right")},
-gLA:function(a){return this.T2(a,"src")}},
+"^":"a;",
+HH:[function(a){return typeof console!="undefined"?console.count(a):null},"call$1","gOu",2,0,446,165,[]],
+Wt:[function(a,b){return typeof console!="undefined"?console.error(b):null},"call$1","gkc",2,0,446,165,[]],
+To:[function(a){return typeof console!="undefined"?console.info(a):null},"call$1","gqa",2,0,null,165,[]],
+De:[function(a,b){return typeof console!="undefined"?console.profile(b):null},"call$1","gB1",2,0,174,447,[]],
+uj:[function(a){return typeof console!="undefined"?console.time(a):null},"call$1","gFl",2,0,174,447,[]],
+WL:[function(a,b){return typeof console!="undefined"?console.trace(b):null},"call$1","gtN",2,0,446,165,[]],
+static:{"^":"wk"}},
 VG:{
-"":"ar;MW,vG",
-tg:[function(a,b){return J.kE(this.vG,b)},"call$1","gdj",2,0,null,124],
+"^":"ar;MW,vG",
+tg:[function(a,b){return J.kE(this.vG,b)},"call$1","gdj",2,0,null,124,[]],
 gl0:function(a){return this.MW.firstElementChild==null},
 gB:function(a){return this.vG.length},
 t:[function(a,b){var z=this.vG
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=this.vG
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-this.MW.replaceChild(c,z[b])},"call$2","gj3",4,0,null,47,23],
+this.MW.replaceChild(c,z[b])},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot resize element lists"))},
 h:[function(a,b){this.MW.appendChild(b)
-return b},"call$1","ght",2,0,null,23],
+return b},"call$1","ght",2,0,null,23,[]],
 gA:function(a){var z=this.br(this)
 return H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])},
 FV:[function(a,b){var z,y
 z=J.x(b)
-for(z=J.GP(typeof b==="object"&&b!==null&&!!z.$ise7?P.F(b,!0,null):b),y=this.MW;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
-So:[function(a,b){throw H.b(P.f("Cannot sort element lists"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.SY(null))},"call$4","gam",6,2,null,336,115,116,109,117],
+for(z=J.GP(typeof b==="object"&&b!==null&&!!z.$ise7?P.F(b,!0,null):b),y=this.MW;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort element lists"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.SY(null))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 Rz:[function(a,b){var z=J.x(b)
 if(typeof b==="object"&&b!==null&&!!z.$iscv){z=this.MW
 if(b.parentNode===z){z.removeChild(b)
-return!0}}return!1},"call$1","gRI",2,0,null,6],
+return!0}}return!1},"call$1","gRI",2,0,null,6,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.vG.length)throw H.b(P.TE(b,0,this.vG.length))
+z=this.vG
+y=z.length
+x=this.MW
+if(b===y)x.appendChild(c)
+else{if(b<0||b>=y)return H.e(z,b)
+x.insertBefore(c,z[b])}},"call$2","gQG",4,0,null,47,[],124,[]],
 V1:[function(a){this.MW.textContent=""},"call$0","gyP",0,0,null],
+KI:[function(a,b){var z,y
+z=this.vG
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+this.MW.removeChild(y)
+return y},"call$1","gNM",2,0,null,47,[]],
 grZ:function(a){var z=this.MW.lastElementChild
 if(z==null)throw H.b(new P.lj("No elements"))
 return z},
@@ -16314,18 +16452,18 @@
 $asWO:function(){return[W.cv]},
 $ascX:function(){return[W.cv]}},
 wz:{
-"":"ar;Sn,Sc",
+"^":"ar;Sn,Sc",
 gB:function(a){return this.Sn.length},
 t:[function(a,b){var z=this.Sn
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
-u:[function(a,b,c){throw H.b(P.f("Cannot modify list"))},"call$2","gj3",4,0,null,47,23],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){throw H.b(P.f("Cannot modify list"))},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){throw H.b(P.f("Cannot modify list"))},
-So:[function(a,b){throw H.b(P.f("Cannot sort list"))},"call$1","gH7",0,2,null,77,128],
+GT:[function(a,b){throw H.b(P.f("Cannot sort list"))},"call$1","gH7",0,2,null,77,128,[]],
 grZ:function(a){return C.t5.grZ(this.Sn)},
 gDD:function(a){return W.or(this.Sc)},
 gi9:function(a){return C.mt.vo(this)},
-gVl:function(a){return C.T1.vo(this)},
+gVl:function(a){return C.pi.vo(this)},
 gLm:function(a){return C.i3.vo(this)},
 nJ:function(a,b){var z=C.t5.ev(this.Sn,new W.B1())
 this.Sc=P.F(z,!0,H.ip(z,"mW",0))},
@@ -16338,62 +16476,47 @@
 z.nJ(a,b)
 return z}}},
 B1:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,18,"call"],
+return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 M5:{
-"":"Gv;"},
+"^":"Gv;"},
 Jn:{
-"":"a;WK<",
-t:[function(a,b){var z=new W.RO(this.gWK(),b,!1)
-z.$builtinTypeInfo=[null]
-return z},"call$1","gIA",2,0,null,11]},
+"^":"a;WK<",
+t:[function(a,b){return H.VM(new W.RO(this.gWK(),b,!1),[null])},"call$1","gIA",2,0,null,11,[]]},
 DM:{
-"":"Jn;WK:YO<,WK",
-t:[function(a,b){var z,y,x
+"^":"Jn;WK:YO<,WK",
+t:[function(a,b){var z,y
 z=$.Vp()
 y=J.rY(b)
-if(z.gvc(z).Fb.x4(y.hc(b))){x=$.PN
-if(x==null){x=$.L4
-if(x==null){x=window.navigator.userAgent
-x.toString
-x.length
-x=H.m2(x,"Opera",0)
-$.L4=x}if(x!==!0){x=window.navigator.userAgent
-x.toString
-x.length
-x=H.m2(x,"WebKit",0)}else x=!1
-$.PN=x}if(x===!0){z=new W.eu(this.YO,z.t(0,y.hc(b)),!1)
-z.$builtinTypeInfo=[null]
-return z}}z=new W.eu(this.YO,b,!1)
-z.$builtinTypeInfo=[null]
-return z},"call$1","gIA",2,0,null,11],
-static:{"":"fD"}},
+if(z.gvc(z).Fb.x4(y.hc(b)))if(P.F7()===!0)return H.VM(new W.eu(this.YO,z.t(0,y.hc(b)),!1),[null])
+return H.VM(new W.eu(this.YO,b,!1),[null])},"call$1","gIA",2,0,null,11,[]],
+static:{"^":"fD"}},
 RAp:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
-ma:{
-"":"RAp+Gm;",
+$ascX:function(){return[W.KV]}},
+Gb:{
+"^":"RAp+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 Kx:{
-"":"Tp:229;",
-call$1:[function(a){return J.EC(a)},"call$1",null,2,0,null,454,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.EC(a)},"call$1",null,2,0,null,448,[],"call"],
 $isEH:true},
 iO:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.setRequestHeader(a,b)},"call$2",null,4,0,null,455,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.setRequestHeader(a,b)},"call$2",null,4,0,null,449,[],23,[],"call"],
 $isEH:true},
 bU:{
-"":"Tp:229;b,c",
+"^":"Tp:223;b,c",
 call$1:[function(a){var z,y,x
 z=this.c
 y=z.status
@@ -16402,91 +16525,106 @@
 x=this.b
 if(y){y=x.MM
 if(y.Gv!==0)H.vh(new P.lj("Future already completed"))
-y.OH(z)}else x.pm(a)},"call$1",null,2,0,null,18,"call"],
+y.OH(z)}else x.pm(a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Yg:{
-"":"Tp:349;a",
-call$2:[function(a,b){if(b!=null)this.a[a]=b},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){if(b!=null)this.a[a]=b},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 e7:{
-"":"ar;NL",
+"^":"ar;NL",
 grZ:function(a){var z=this.NL.lastChild
 if(z==null)throw H.b(new P.lj("No elements"))
 return z},
-h:[function(a,b){this.NL.appendChild(b)},"call$1","ght",2,0,null,23],
+h:[function(a,b){this.NL.appendChild(b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y,x,w
 z=J.w1(b)
 if(typeof b==="object"&&b!==null&&!!z.$ise7){z=b.NL
 y=this.NL
 if(z!==y)for(x=z.childNodes.length,w=0;w<x;++w)y.appendChild(z.firstChild)
-return}for(z=z.gA(b),y=this.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
+return}for(z=z.gA(b),y=this.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.NL.childNodes.length)throw H.b(P.TE(b,0,this.NL.childNodes.length))
+z=this.NL
+y=z.childNodes
+x=y.length
+if(b===x)z.appendChild(c)
+else{if(b<0||b>=x)return H.e(y,b)
+z.insertBefore(c,y[b])}},"call$2","gQG",4,0,null,47,[],259,[]],
+KI:[function(a,b){var z,y,x
+z=this.NL
+y=z.childNodes
+if(b<0||b>=y.length)return H.e(y,b)
+x=y[b]
+z.removeChild(x)
+return x},"call$1","gNM",2,0,null,47,[]],
 Rz:[function(a,b){var z=J.x(b)
-if(typeof b!=="object"||b===null||!z.$isuH)return!1
+if(typeof b!=="object"||b===null||!z.$isKV)return!1
 z=this.NL
 if(z!==b.parentNode)return!1
 z.removeChild(b)
-return!0},"call$1","gRI",2,0,null,6],
+return!0},"call$1","gRI",2,0,null,6,[]],
 V1:[function(a){this.NL.textContent=""},"call$0","gyP",0,0,null],
 u:[function(a,b,c){var z,y
 z=this.NL
 y=z.childNodes
 if(b>>>0!==b||b>=y.length)return H.e(y,b)
-z.replaceChild(c,y[b])},"call$2","gj3",4,0,null,47,23],
+z.replaceChild(c,y[b])},"call$2","gj3",4,0,null,47,[],23,[]],
 gA:function(a){return C.t5.gA(this.NL.childNodes)},
-So:[function(a,b){throw H.b(P.f("Cannot sort Node list"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on Node list"))},"call$4","gam",6,2,null,336,115,116,109,117],
+GT:[function(a,b){throw H.b(P.f("Cannot sort Node list"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on Node list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 gB:function(a){return this.NL.childNodes.length},
 sB:function(a,b){throw H.b(P.f("Cannot set length on immutable List."))},
 t:[function(a,b){var z=this.NL.childNodes
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 $ise7:true,
-$asar:function(){return[W.uH]},
-$asWO:function(){return[W.uH]},
-$ascX:function(){return[W.uH]}},
+$asar:function(){return[W.KV]},
+$asWO:function(){return[W.KV]},
+$ascX:function(){return[W.KV]}},
 nNL:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 ecX:{
-"":"nNL+Gm;",
+"^":"nNL+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 kI:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isQl},"call$1",null,2,0,null,18,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isQl},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 yoo:{
-"":"Gv+lD;",
+"^":"Gv+lD;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 w1p:{
-"":"yoo+Gm;",
+"^":"yoo+Gm;",
 $isList:true,
-$asWO:function(){return[W.uH]},
+$asWO:function(){return[W.KV]},
 $isyN:true,
 $iscX:true,
-$ascX:function(){return[W.uH]}},
+$ascX:function(){return[W.KV]}},
 tJ:{
-"":"a;",
-FV:[function(a,b){J.kH(b,new W.Zc(this))},"call$1","gDY",2,0,null,104],
+"^":"a;",
+FV:[function(a,b){J.kH(b,new W.Zc(this))},"call$1","gDY",2,0,null,104,[]],
 di:[function(a){var z
-for(z=this.gUQ(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G(););return!1},"call$1","gmc",2,0,null,23],
+for(z=this.gUQ(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G(););return!1},"call$1","gmc",2,0,null,23,[]],
 V1:[function(a){var z
 for(z=this.gvc(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)this.Rz(0,z.lo)},"call$0","gyP",0,0,null],
 aN:[function(a,b){var z,y
 for(z=this.gvc(this),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();){y=z.lo
-b.call$2(y,this.t(0,y))}},"call$1","gjw",2,0,null,110],
+b.call$2(y,this.t(0,y))}},"call$1","gjw",2,0,null,110,[]],
 gvc:function(a){var z,y,x,w
 z=this.MW.attributes
 y=H.VM([],[J.O])
@@ -16504,93 +16642,98 @@
 $isZ0:true,
 $asZ0:function(){return[J.O,J.O]}},
 Zc:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,421,277,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 i7:{
-"":"tJ;MW",
-x4:[function(a){return this.MW.hasAttribute(a)},"call$1","gV9",2,0,null,42],
-t:[function(a,b){return this.MW.getAttribute(b)},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){this.MW.setAttribute(b,c)},"call$2","gj3",4,0,null,42,23],
+"^":"tJ;MW",
+x4:[function(a){return this.MW.hasAttribute(a)},"call$1","gV9",2,0,null,42,[]],
+t:[function(a,b){return this.MW.getAttribute(b)},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){this.MW.setAttribute(b,c)},"call$2","gj3",4,0,null,42,[],23,[]],
 Rz:[function(a,b){var z,y
 z=this.MW
 y=z.getAttribute(b)
 z.removeAttribute(b)
-return y},"call$1","gRI",2,0,null,42],
+return y},"call$1","gRI",2,0,null,42,[]],
 gB:function(a){return this.gvc(this).length},
-FJ:[function(a){return a.namespaceURI==null},"call$1","giG",2,0,null,265]},
+FJ:[function(a){return a.namespaceURI==null},"call$1","giG",2,0,null,259,[]]},
 nF:{
-"":"Ay;QX,Kd",
+"^":"As;QX,Kd",
 lF:[function(){var z=P.Ls(null,null,null,J.O)
 this.Kd.aN(0,new W.Si(z))
 return z},"call$0","gt8",0,0,null],
 p5:[function(a){var z,y
 z=C.Nm.zV(P.F(a,!0,null)," ")
-for(y=this.QX,y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();)J.Pw(y.lo,z)},"call$1","gVH",2,0,null,86],
-OS:[function(a){this.Kd.aN(0,new W.vf(a))},"call$1","gFd",2,0,null,110],
-Rz:[function(a,b){return this.xz(new W.Fc(b))},"call$1","gRI",2,0,null,23],
-xz:[function(a){return this.Kd.es(0,!1,new W.hD(a))},"call$1","gVz",2,0,null,110],
+for(y=this.QX,y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();)J.Pw(y.lo,z)},"call$1","gVH",2,0,null,86,[]],
+OS:[function(a){this.Kd.aN(0,new W.vf(a))},"call$1","gFd",2,0,null,110,[]],
+O4:[function(a,b){return this.xz(new W.Iw(a,b))},function(a){return this.O4(a,null)},"qU","call$2",null,"gMk",2,2,null,77,23,[],450,[]],
+Rz:[function(a,b){return this.xz(new W.Fc(b))},"call$1","gRI",2,0,null,23,[]],
+xz:[function(a){return this.Kd.es(0,!1,new W.hD(a))},"call$1","gVz",2,0,null,110,[]],
 yJ:function(a){this.Kd=H.VM(new H.A8(P.F(this.QX,!0,null),new W.FK()),[null,null])},
 static:{or:function(a){var z=new W.nF(a,null)
 z.yJ(a)
 return z}}},
 FK:{
-"":"Tp:229;",
-call$1:[function(a){return new W.I4(a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new W.I4(a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Si:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a.FV(0,a.lF())},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return this.a.FV(0,a.lF())},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 vf:{
-"":"Tp:229;a",
-call$1:[function(a){return a.OS(this.a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.OS(this.a)},"call$1",null,2,0,null,18,[],"call"],
+$isEH:true},
+Iw:{
+"^":"Tp:223;a,b",
+call$1:[function(a){return a.O4(this.a,this.b)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Fc:{
-"":"Tp:229;a",
-call$1:[function(a){return J.V1(a,this.a)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.V1(a,this.a)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 hD:{
-"":"Tp:349;a",
-call$2:[function(a,b){return this.a.call$1(b)===!0||a===!0},"call$2",null,4,0,null,456,124,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){return this.a.call$1(b)===!0||a===!0},"call$2",null,4,0,null,451,[],124,[],"call"],
 $isEH:true},
 I4:{
-"":"Ay;MW",
+"^":"As;MW",
 lF:[function(){var z,y,x
 z=P.Ls(null,null,null,J.O)
 for(y=J.uf(this.MW).split(" "),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]);y.G();){x=J.rr(y.lo)
 if(x.length!==0)z.h(0,x)}return z},"call$0","gt8",0,0,null],
 p5:[function(a){P.F(a,!0,null)
-J.Pw(this.MW,a.zV(0," "))},"call$1","gVH",2,0,null,86]},
+J.Pw(this.MW,a.zV(0," "))},"call$1","gVH",2,0,null,86,[]]},
 e0:{
-"":"a;Ph",
-zc:[function(a,b){return H.VM(new W.RO(a,this.Ph,b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,209,18,299],
-Qm:[function(a,b){return H.VM(new W.eu(a,this.Ph,b),[null])},function(a){return this.Qm(a,!1)},"f0","call$2$useCapture",null,"gAW",2,3,null,209,18,299],
-jl:[function(a,b){return H.VM(new W.pu(a,b,this.Ph),[null])},function(a){return this.jl(a,!1)},"vo","call$2$useCapture",null,"gcJ",2,3,null,209,18,299]},
+"^":"a;Ph",
+zc:[function(a,b){return H.VM(new W.RO(a,this.Ph,b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,205,18,[],293,[]],
+Qm:[function(a,b){return H.VM(new W.eu(a,this.Ph,b),[null])},function(a){return this.Qm(a,!1)},"f0","call$2$useCapture",null,"gAW",2,3,null,205,18,[],293,[]],
+jl:[function(a,b){return H.VM(new W.pu(a,b,this.Ph),[null])},function(a){return this.jl(a,!1)},"vo","call$2$useCapture",null,"gcJ",2,3,null,205,18,[],293,[]]},
 RO:{
-"":"qh;uv,Ph,Sg",
+"^":"qh;uv,Ph,Sg",
 KR:[function(a,b,c,d){var z=new W.Ov(0,this.uv,this.Ph,W.aF(a),this.Sg)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 z.Zz()
-return z},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156]},
+return z},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]]},
 eu:{
-"":"RO;uv,Ph,Sg",
+"^":"RO;uv,Ph,Sg",
 WO:[function(a,b){var z=H.VM(new P.nO(new W.ie(b),this),[H.ip(this,"qh",0)])
-return H.VM(new P.t3(new W.Ea(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,457],
+return H.VM(new P.t3(new W.Ea(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,452,[]],
 $isqh:true},
 ie:{
-"":"Tp:229;a",
-call$1:[function(a){return J.eI(J.l2(a),this.a)},"call$1",null,2,0,null,405,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.NQ(J.l2(a),this.a)},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 Ea:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){J.og(a,this.b)
-return a},"call$1",null,2,0,null,18,"call"],
+return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 pu:{
-"":"qh;DI,Sg,Ph",
+"^":"qh;DI,Sg,Ph",
 WO:[function(a,b){var z=H.VM(new P.nO(new W.i2(b),this),[H.ip(this,"qh",0)])
-return H.VM(new P.t3(new W.b0(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,457],
+return H.VM(new P.t3(new W.b0(b),z),[H.ip(z,"qh",0),null])},"call$1","grM",2,0,null,452,[]],
 KR:[function(a,b,c,d){var z,y,x,w,v
 z=H.VM(new W.qO(null,P.L5(null,null,null,[P.qh,null],[P.MO,null])),[null])
 z.KS(null)
@@ -16598,26 +16741,28 @@
 v.$builtinTypeInfo=[null]
 z.h(0,v)}y=z.aV
 y.toString
-return H.VM(new P.Ik(y),[H.Kp(y,0)]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,345,346,347,156],
+return H.VM(new P.Ik(y),[H.Kp(y,0)]).KR(a,b,c,d)},function(a,b,c){return this.KR(a,null,b,c)},"zC",function(a){return this.KR(a,null,null,null)},"yI","call$4$cancelOnError$onDone$onError",null,null,"gp8",2,7,null,77,77,77,402,[],396,[],403,[],156,[]],
 $isqh:true},
 i2:{
-"":"Tp:229;a",
-call$1:[function(a){return J.eI(J.l2(a),this.a)},"call$1",null,2,0,null,405,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.NQ(J.l2(a),this.a)},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 b0:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){J.og(a,this.b)
-return a},"call$1",null,2,0,null,18,"call"],
+return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Ov:{
-"":"MO;VP,uv,Ph,u7,Sg",
+"^":"MO;VP,uv,Ph,u7,Sg",
 ed:[function(){if(this.uv==null)return
 this.Ns()
 this.uv=null
-this.u7=null},"call$0","gZS",0,0,null],
+this.u7=null
+return},"call$0","gZS",0,0,null],
 nB:[function(a,b){if(this.uv==null)return
 this.VP=this.VP+1
-this.Ns()},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,404],
+this.Ns()},function(a){return this.nB(a,null)},"yy","call$1",null,"gAK",0,2,null,77,399,[]],
+gRW:function(){return this.VP>0},
 QE:[function(){if(this.uv==null||this.VP<=0)return
 this.VP=this.VP-1
 this.Zz()},"call$0","gDQ",0,0,null],
@@ -16626,42 +16771,68 @@
 Ns:[function(){var z=this.u7
 if(z!=null)J.GJ(this.uv,this.Ph,z,this.Sg)},"call$0","gEv",0,0,null]},
 qO:{
-"":"a;aV,eM",
+"^":"a;aV,eM",
 h:[function(a,b){var z,y
 z=this.eM
 if(z.x4(b))return
 y=this.aV
-z.u(0,b,b.zC(y.ght(y),new W.RX(this,b),this.aV.gXB()))},"call$1","ght",2,0,null,458],
+z.u(0,b,b.zC(y.ght(y),new W.RX(this,b),this.aV.gXB()))},"call$1","ght",2,0,null,453,[]],
 Rz:[function(a,b){var z=this.eM.Rz(0,b)
-if(z!=null)z.ed()},"call$1","gRI",2,0,null,458],
+if(z!=null)z.ed()},"call$1","gRI",2,0,null,453,[]],
 cO:[function(a){var z,y
 for(z=this.eM,y=z.gUQ(z),y=H.VM(new H.MH(null,J.GP(y.l6),y.T6),[H.Kp(y,0),H.Kp(y,1)]);y.G();)y.lo.ed()
 z.V1(0)
 this.aV.cO(0)},"call$0","gJK",0,0,107],
 KS:function(a){this.aV=P.bK(this.gJK(this),null,!0,a)}},
 RX:{
-"":"Tp:108;a,b",
+"^":"Tp:108;a,b",
 call$0:[function(){return this.a.Rz(0,this.b)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-hP:{
-"":"a;Vy",
-cN:function(a){return this.Vy.call$1(a)},
-zc:[function(a,b){return H.VM(new W.RO(a,this.cN(a),b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,209,18,299]},
+bO:{
+"^":"a;xY",
+cN:function(a){return this.xY.call$1(a)},
+zc:[function(a,b){return H.VM(new W.RO(a,this.cN(a),b),[null])},function(a){return this.zc(a,!1)},"aM","call$2$useCapture",null,"gII",2,3,null,205,18,[],293,[]]},
 Gm:{
-"":"a;",
+"^":"a;",
 gA:function(a){return H.VM(new W.W9(a,this.gB(a),-1,null),[H.ip(a,"Gm",0)])},
-h:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","ght",2,0,null,23],
-FV:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","gDY",2,0,null,109],
-So:[function(a,b){throw H.b(P.f("Cannot sort immutable List."))},"call$1","gH7",0,2,null,77,128],
-Rz:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gRI",2,0,null,6],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on immutable List."))},"call$4","gam",6,2,null,336,115,116,109,117],
+h:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","ght",2,0,null,23,[]],
+FV:[function(a,b){throw H.b(P.f("Cannot add to immutable List."))},"call$1","gDY",2,0,null,109,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort immutable List."))},"call$1","gH7",0,2,null,77,128,[]],
+xe:[function(a,b,c){throw H.b(P.f("Cannot add to immutable List."))},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gNM",2,0,null,454,[]],
+Rz:[function(a,b){throw H.b(P.f("Cannot remove from immutable List."))},"call$1","gRI",2,0,null,6,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on immutable List."))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
+Of:{
+"^":"ar;xa",
+gA:function(a){return H.VM(new W.Qg(J.GP(this.xa)),[null])},
+gB:function(a){return this.xa.length},
+h:[function(a,b){J.bi(this.xa,b)},"call$1","ght",2,0,null,124,[]],
+Rz:[function(a,b){return J.V1(this.xa,b)},"call$1","gRI",2,0,null,124,[]],
+V1:[function(a){J.U2(this.xa)},"call$0","gyP",0,0,null],
+t:[function(a,b){var z=this.xa
+if(b>>>0!==b||b>=z.length)return H.e(z,b)
+return z[b]},"call$1","gIA",2,0,null,47,[]],
+u:[function(a,b,c){var z=this.xa
+if(b>>>0!==b||b>=z.length)return H.e(z,b)
+z[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+sB:function(a,b){J.wg(this.xa,b)},
+GT:[function(a,b){J.LH(this.xa,b)},"call$1","gH7",0,2,null,77,128,[]],
+XU:[function(a,b,c){return J.hf(this.xa,b,c)},function(a,b){return this.XU(a,b,0)},"u8","call$2",null,"gIz",2,2,null,330,124,[],115,[]],
+Pk:[function(a,b,c){return J.ff(this.xa,b,c)},function(a,b){return this.Pk(a,b,null)},"cn","call$2",null,"gph",2,2,null,77,124,[],115,[]],
+xe:[function(a,b,c){return J.Nv(this.xa,b,c)},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){return J.tH(this.xa,b)},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){J.VZ(this.xa,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]]},
+Qg:{
+"^":"a;je",
+G:[function(){return this.je.G()},"call$0","gqy",0,0,null],
+gl:function(){return this.je.QZ}},
 W9:{
-"":"a;nj,vN,Nq,QZ",
+"^":"a;nj,vN,Nq,QZ",
 G:[function(){var z,y
 z=this.Nq+1
 y=this.vN
@@ -16669,278 +16840,295 @@
 this.Nq=z
 return!0}this.QZ=null
 this.Nq=y
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 gl:function(){return this.QZ}},
 vZ:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=H.Va(this.b)
 Object.defineProperty(a, init.dispatchPropertyName, {value: z, enumerable: false, writable: true, configurable: true})
-return this.a(a)},"call$1",null,2,0,null,41,"call"],
+a.constructor=a.__proto__.constructor
+return this.a(a)},"call$1",null,2,0,null,41,[],"call"],
 $isEH:true},
 dW:{
-"":"a;Ui",
+"^":"a;Ui",
 geT:function(a){return W.P1(this.Ui.parent)},
 cO:[function(a){return this.Ui.close()},"call$0","gJK",0,0,null],
-xc:[function(a,b,c,d){this.Ui.postMessage(b,c)},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,329,330],
+xc:[function(a,b,c,d){this.Ui.postMessage(b,c)},function(a,b,c){return this.xc(a,b,c,null)},"X6","call$3",null,"gmF",4,2,null,77,20,[],323,[],324,[]],
+gI:function(a){return H.vh(P.SY(null))},
+On:[function(a,b,c,d){return H.vh(P.SY(null))},"call$3","gIV",4,2,null,77,11,[],292,[],293,[]],
+Y9:[function(a,b,c,d){return H.vh(P.SY(null))},"call$3","gcF",4,2,null,77,11,[],292,[],293,[]],
 $isD0:true,
 $isGv:true,
 static:{P1:[function(a){if(a===window)return a
-else return new W.dW(a)},"call$1","lG",2,0,null,235]}},
+else return new W.dW(a)},"call$1","lG",2,0,null,229,[]]}},
 Dk:{
-"":"a;WK",
+"^":"a;WK",
 gcC:function(a){return this.WK.hash},
 scC:function(a,b){this.WK.hash=b},
 gmH:function(a){return this.WK.href},
 bu:[function(a){return this.WK.toString()},"call$0","gXo",0,0,null],
 $iscS:true,
 $isGv:true}}],["dart.dom.indexed_db","dart:indexed_db",,P,{
-"":"",
+"^":"",
 hF:{
-"":"Gv;",
+"^":"Gv;",
 $ishF:true,
 "%":"IDBKeyRange"}}],["dart.dom.svg","dart:svg",,P,{
-"":"",
+"^":"",
 Dh:{
-"":"zp;N:target=,mH:href=",
+"^":"zp;N:target=,mH:href=",
 $isGv:true,
 "%":"SVGAElement"},
 ZJ:{
-"":"Eo;mH:href=",
+"^":"Eo;mH:href=",
 $isGv:true,
 "%":"SVGAltGlyphElement"},
 ui:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGAnimateColorElement|SVGAnimateElement|SVGAnimateMotionElement|SVGAnimateTransformElement|SVGAnimationElement|SVGSetElement"},
-vO:{
-"":"zp;",
+mk:{
+"^":"d0;",
 $isGv:true,
 "%":"SVGCircleElement"},
 DQ:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGClipPathElement"},
 Sm:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGDefsElement"},
 es:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGEllipseElement"},
 eG:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEBlendElement"},
 lv:{
-"":"GN;t5:type=,UQ:values=",
+"^":"d5;t5:type=,UQ:values=",
 $isGv:true,
 "%":"SVGFEColorMatrixElement"},
 pf:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEComponentTransferElement"},
 NV:{
-"":"GN;kp:operator=",
+"^":"d5;kp:operator=",
 $isGv:true,
 "%":"SVGFECompositeElement"},
 W1:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEConvolveMatrixElement"},
-HC:{
-"":"GN;",
+mCz:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDiffuseLightingElement"},
 kK:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDisplacementMapElement"},
 bb:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEFloodElement"},
 tk:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEGaussianBlurElement"},
 me:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGFEImageElement"},
-bO:{
-"":"GN;",
+oB:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEMergeElement"},
 EI:{
-"":"GN;kp:operator=",
+"^":"d5;kp:operator=",
 $isGv:true,
 "%":"SVGFEMorphologyElement"},
 MI:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEOffsetElement"},
-zt:{
-"":"GN;",
+um:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGFESpecularLightingElement"},
 kL:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFETileElement"},
 Fu:{
-"":"GN;t5:type=",
+"^":"d5;t5:type=",
 $isGv:true,
 "%":"SVGFETurbulenceElement"},
-OE:{
-"":"GN;mH:href=",
+QN:{
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGFilterElement"},
 N9:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGForeignObjectElement"},
 BA:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGGElement"},
+d0:{
+"^":"zp;",
+"%":";SVGGeometryElement"},
 zp:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":";SVGGraphicsElement"},
 br:{
-"":"zp;mH:href=",
+"^":"zp;mH:href=",
 $isGv:true,
 "%":"SVGImageElement"},
 PIw:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGLineElement"},
 Jq:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMarkerElement"},
 Yd:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMaskElement"},
 lZ:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPathElement"},
 Gr:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGPatternElement"},
 XE:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPolygonElement"},
 GH:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGPolylineElement"},
 NJ:{
-"":"zp;",
+"^":"d0;",
 $isGv:true,
 "%":"SVGRectElement"},
 Ue:{
-"":"GN;t5:type%,mH:href=",
+"^":"d5;t5:type%,mH:href=",
 $isGv:true,
 "%":"SVGScriptElement"},
-Lu:{
-"":"GN;t5:type%",
+Lx:{
+"^":"d5;t5:type%",
 "%":"SVGStyleElement"},
-GN:{
-"":"cv;",
+d5:{
+"^":"cv;",
 gDD:function(a){if(a._cssClassSet==null)a._cssClassSet=new P.O7(a)
 return a._cssClassSet},
 gwd:function(a){return H.VM(new P.D7(a,new W.e7(a)),[W.cv])},
+swd:function(a,b){var z=H.VM(new P.D7(a,new W.e7(a)),[W.cv])
+z.h2.NL.textContent=""
+z.FV(0,b)},
 gi9:function(a){return C.mt.f0(a)},
-gVl:function(a){return C.T1.f0(a)},
+gVl:function(a){return C.pi.f0(a)},
 gLm:function(a){return C.i3.f0(a)},
 $isD0:true,
 $isGv:true,
 "%":"SVGAltGlyphDefElement|SVGAltGlyphItemElement|SVGComponentTransferFunctionElement|SVGDescElement|SVGFEDistantLightElement|SVGFEFuncAElement|SVGFEFuncBElement|SVGFEFuncGElement|SVGFEFuncRElement|SVGFEMergeNodeElement|SVGFEPointLightElement|SVGFESpotLightElement|SVGFontElement|SVGFontFaceElement|SVGFontFaceFormatElement|SVGFontFaceNameElement|SVGFontFaceSrcElement|SVGFontFaceUriElement|SVGGlyphElement|SVGHKernElement|SVGMetadataElement|SVGMissingGlyphElement|SVGStopElement|SVGTitleElement|SVGVKernElement;SVGElement"},
 hy:{
-"":"zp;",
-Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,293],
+"^":"zp;",
+Kb:[function(a,b){return a.getElementById(b)},"call$1","giu",2,0,null,288,[]],
 $ishy:true,
 $isGv:true,
 "%":"SVGSVGElement"},
 mq:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":"SVGSwitchElement"},
 Ke:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGSymbolElement"},
 Xe:{
-"":"zp;",
+"^":"zp;",
 $isGv:true,
 "%":";SVGTextContentElement"},
 Rk4:{
-"":"Xe;bP:method=,mH:href=",
+"^":"Xe;bP:method=,mH:href=",
 $isGv:true,
 "%":"SVGTextPathElement"},
 Eo:{
-"":"Xe;",
+"^":"Xe;",
 "%":"SVGTSpanElement|SVGTextElement;SVGTextPositioningElement"},
 pyk:{
-"":"zp;mH:href=",
+"^":"zp;mH:href=",
 $isGv:true,
 "%":"SVGUseElement"},
 ZD:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGViewElement"},
 wD:{
-"":"GN;mH:href=",
+"^":"d5;mH:href=",
 $isGv:true,
 "%":"SVGGradientElement|SVGLinearGradientElement|SVGRadialGradientElement"},
-zI:{
-"":"GN;",
+mj:{
+"^":"d5;",
 $isGv:true,
 "%":"SVGCursorElement"},
 cB:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGFEDropShadowElement"},
 nb:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGGlyphRefElement"},
 xt:{
-"":"GN;",
+"^":"d5;",
 $isGv:true,
 "%":"SVGMPathElement"},
 O7:{
-"":"Ay;LO",
+"^":"As;LO",
 lF:[function(){var z,y,x,w
 z=this.LO.getAttribute("class")
 y=P.Ls(null,null,null,J.O)
 if(z==null)return y
 for(x=z.split(" "),x=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);x.G();){w=J.rr(x.lo)
 if(w.length!==0)y.h(0,w)}return y},"call$0","gt8",0,0,null],
-p5:[function(a){this.LO.setAttribute("class",a.zV(0," "))},"call$1","gVH",2,0,null,86]}}],["dart.dom.web_sql","dart:web_sql",,P,{
-"":"",
+p5:[function(a){this.LO.setAttribute("class",a.zV(0," "))},"call$1","gVH",2,0,null,86,[]]}}],["dart.dom.web_sql","dart:web_sql",,P,{
+"^":"",
 TM:{
-"":"Gv;tT:code=,G1:message=",
-"%":"SQLError"}}],["dart.js","dart:js",,P,{
-"":"",
-xZ:[function(a,b){return function(_call, f, captureThis) {return function() {return _call(f, captureThis, this, Array.prototype.slice.apply(arguments));}}(P.R4, a, b)},"call$2$captureThis","Kc",2,3,null,209,110,236],
+"^":"Gv;tT:code=,G1:message=",
+"%":"SQLError"}}],["dart.isolate","dart:isolate",,P,{
+"^":"",
+IU:{
+"^":"a;",
+$isIU:true,
+static:{Jz:function(){return new H.ku((Math.random()*0x100000000>>>0)+(Math.random()*0x100000000>>>0)*4294967296)}}}}],["dart.js","dart:js",,P,{
+"^":"",
+xZ:[function(a,b){return function(_call, f, captureThis) {return function() {return _call(f, captureThis, this, Array.prototype.slice.apply(arguments));}}(P.R4, a, b)},"call$2$captureThis","Kc",2,3,null,205,110,[],230,[]],
 R4:[function(a,b,c,d){var z
 if(b===!0){z=[c]
 C.Nm.FV(z,d)
-d=z}return P.wY(H.Ek(a,P.F(J.C0(d,P.Xl()),!0,null),P.Te(null)))},"call$4","qH",8,0,null,150,236,161,82],
+d=z}return P.wY(H.Ek(a,P.F(J.C0(d,P.Xl()),!0,null),P.Te(null)))},"call$4","qH",8,0,null,148,[],230,[],161,[],82,[]],
 Dm:[function(a,b,c){var z
 if(Object.isExtensible(a))try{Object.defineProperty(a, b, { value: c})
-return!0}catch(z){H.Ru(z)}return!1},"call$3","bE",6,0,null,91,12,23],
+return!0}catch(z){H.Ru(z)}return!1},"call$3","bE",6,0,null,91,[],12,[],23,[]],
+Om:[function(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]
+return},"call$2","Cb",4,0,null,91,[],12,[]],
 wY:[function(a){var z
 if(a==null)return
 else{if(typeof a!=="string")if(typeof a!=="number")if(typeof a!=="boolean"){z=J.x(a)
-z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isuH||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!0
+z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isKV||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!0
 else z=!0
 else z=!0
 if(z)return a
@@ -16948,36 +17136,36 @@
 if(typeof a==="object"&&a!==null&&!!z.$isiP)return H.o2(a)
 else if(typeof a==="object"&&a!==null&&!!z.$isE4)return a.eh
 else if(typeof a==="object"&&a!==null&&!!z.$isEH)return P.hE(a,"$dart_jsFunction",new P.DV())
-else return P.hE(a,"_$dart_jsObject",new P.Hp())}}},"call$1","En",2,0,229,91],
-hE:[function(a,b,c){var z=a[b]
+else return P.hE(a,"_$dart_jsObject",new P.Hp())}}},"call$1","En",2,0,223,91,[]],
+hE:[function(a,b,c){var z=P.Om(a,b)
 if(z==null){z=c.call$1(a)
-P.Dm(a,b,z)}return z},"call$3","nB",6,0,null,91,63,238],
+P.Dm(a,b,z)}return z},"call$3","nB",6,0,null,91,[],63,[],232,[]],
 dU:[function(a){var z
 if(a==null||typeof a=="string"||typeof a=="number"||typeof a=="boolean")return a
 else{if(a instanceof Object){z=J.x(a)
-z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isuH||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!1
+z=typeof a==="object"&&a!==null&&!!z.$isAz||typeof a==="object"&&a!==null&&!!z.$isea||typeof a==="object"&&a!==null&&!!z.$ishF||typeof a==="object"&&a!==null&&!!z.$isSg||typeof a==="object"&&a!==null&&!!z.$isKV||typeof a==="object"&&a!==null&&!!z.$isHY||typeof a==="object"&&a!==null&&!!z.$isu9}else z=!1
 if(z)return a
 else if(a instanceof Date)return P.Wu(a.getMilliseconds(),!1)
 else if(a.constructor===DartObject)return a.o
-else return P.ND(a)}},"call$1","Xl",2,0,187,91],
-ND:[function(a){if(typeof a=="function")return P.iQ(a,"_$dart_dartClosure",new P.Nz())
-else if(a instanceof Array)return P.iQ(a,"_$dart_dartObject",new P.Jd())
-else return P.iQ(a,"_$dart_dartObject",new P.QS())},"call$1","ln",2,0,null,91],
-iQ:[function(a,b,c){var z=a[b]
+else return P.ND(a)}},"call$1","Xl",2,0,187,91,[]],
+ND:[function(a){if(typeof a=="function")return P.iQ(a,$.Dp(),new P.Nz())
+else if(a instanceof Array)return P.iQ(a,$.Iq(),new P.Jd())
+else return P.iQ(a,$.Iq(),new P.QS())},"call$1","ln",2,0,null,91,[]],
+iQ:[function(a,b,c){var z=P.Om(a,b)
 if(z==null||!(a instanceof Object)){z=c.call$1(a)
-P.Dm(a,b,z)}return z},"call$3","yF",6,0,null,91,63,238],
+P.Dm(a,b,z)}return z},"call$3","yF",6,0,null,91,[],63,[],232,[]],
 E4:{
-"":"a;eh",
+"^":"a;eh",
 t:[function(a,b){if(typeof b!=="string"&&typeof b!=="number")throw H.b(new P.AT("property is not a String or num"))
-return P.dU(this.eh[b])},"call$1","gIA",2,0,null,66],
+return P.dU(this.eh[b])},"call$1","gIA",2,0,null,66,[]],
 u:[function(a,b,c){if(typeof b!=="string"&&typeof b!=="number")throw H.b(new P.AT("property is not a String or num"))
-this.eh[b]=P.wY(c)},"call$2","gj3",4,0,null,66,23],
+this.eh[b]=P.wY(c)},"call$2","gj3",4,0,null,66,[],23,[]],
 giO:function(a){return 0},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isE4&&this.eh===b.eh},"call$1","gUJ",2,0,null,104],
-Bm:[function(a){return a in this.eh},"call$1","gVOe",2,0,null,66],
+return typeof b==="object"&&b!==null&&!!z.$isE4&&this.eh===b.eh},"call$1","gUJ",2,0,null,104,[]],
+Bm:[function(a){return a in this.eh},"call$1","gVOe",2,0,null,66,[]],
 bu:[function(a){var z,y
 try{z=String(this.eh)
 return z}catch(y){H.Ru(y)
@@ -16985,7 +17173,7 @@
 V7:[function(a,b){var z,y
 z=this.eh
 y=b==null?null:P.F(J.C0(b,P.En()),!0,null)
-return P.dU(z[a].apply(z,y))},function(a){return this.V7(a,null)},"nQ","call$2",null,"gah",2,2,null,77,221,258],
+return P.dU(z[a].apply(z,y))},function(a){return this.V7(a,null)},"nQ","call$2",null,"gah",2,2,null,77,215,[],263,[]],
 $isE4:true,
 static:{uw:function(a,b){var z,y,x
 z=P.wY(a)
@@ -16995,9 +17183,9 @@
 C.Nm.FV(y,H.VM(new H.A8(b,P.En()),[null,null]))
 x=z.bind.apply(z,y)
 String(x)
-return P.ND(new x())},jT:function(a){return P.ND(P.M0(a))},M0:[function(a){return new P.Xb(P.UD(null,null)).call$1(a)},"call$1","Gf",2,0,null,237]}},
-Xb:{
-"":"Tp:229;a",
+return P.ND(new x())},jT:function(a){return P.ND(P.M0(a))},M0:[function(a){return new P.Gn(P.UD(null,null)).call$1(a)},"call$1","Ij",2,0,null,231,[]]}},
+Gn:{
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w,v
 z=this.a
 if(z.x4(a))return z.t(0,a)
@@ -17008,74 +17196,89 @@
 x[w]=this.call$1(y.t(a,w))}return x}else if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!y.$iscX)){v=[]
 z.u(0,a,v)
 C.Nm.FV(v,y.ez(a,this))
-return v}else return P.wY(a)},"call$1",null,2,0,null,91,"call"],
+return v}else return P.wY(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 r7:{
-"":"E4;eh"},
+"^":"E4;eh"},
 Tz:{
-"":"Wk;eh",
+"^":"Wk;eh",
+fz:[function(a,b){var z
+if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
+if(typeof z!=="number")return H.s(z)
+z=b>=z}else z=!0
+else z=!1
+if(z)throw H.b(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))},"call$1","gvs",2,0,null,47,[]],
 t:[function(a,b){var z
 if(typeof b==="number"&&b===C.CD.yu(b)){if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
 if(typeof z!=="number")return H.s(z)
 z=b>=z}else z=!0
 else z=!1
-if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}return P.E4.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,47],
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}return P.E4.prototype.t.call(this,this,b)},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z
 if(typeof b==="number"&&b===C.CD.yu(b)){if(typeof b==="number"&&Math.floor(b)===b)if(!(b<0)){z=P.E4.prototype.t.call(this,this,"length")
 if(typeof z!=="number")return H.s(z)
 z=b>=z}else z=!0
 else z=!1
-if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}P.E4.prototype.u.call(this,this,b,c)},"call$2","gj3",4,0,null,47,23],
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))}P.E4.prototype.u.call(this,this,b,c)},"call$2","gj3",4,0,null,47,[],23,[]],
 gB:function(a){return P.E4.prototype.t.call(this,this,"length")},
 sB:function(a,b){P.E4.prototype.u.call(this,this,"length",b)},
-h:[function(a,b){this.V7("push",[b])},"call$1","ght",2,0,null,23],
-FV:[function(a,b){this.V7("push",b instanceof Array?b:P.F(b,!0,null))},"call$1","gDY",2,0,null,109],
-YW:[function(a,b,c,d,e){var z,y,x
-z=P.E4.prototype.t.call(this,this,"length")
+h:[function(a,b){this.V7("push",[b])},"call$1","ght",2,0,null,23,[]],
+FV:[function(a,b){this.V7("push",b instanceof Array?b:P.F(b,!0,null))},"call$1","gDY",2,0,null,109,[]],
+xe:[function(a,b,c){var z
+if(b>=0){z=J.WB(P.E4.prototype.t.call(this,this,"length"),1)
 if(typeof z!=="number")return H.s(z)
-z=b>z
+z=b>=z}else z=!0
+if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))
+this.V7("splice",[b,0,c])},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){this.fz(0,b)
+return J.UQ(this.V7("splice",[b,1]),0)},"call$1","gNM",2,0,null,47,[]],
+YW:[function(a,b,c,d,e){var z,y,x
+if(b>=0){z=P.E4.prototype.t.call(this,this,"length")
+if(typeof z!=="number")return H.s(z)
+z=b>z}else z=!0
 if(z)H.vh(P.TE(b,0,P.E4.prototype.t.call(this,this,"length")))
 z=J.Wx(c)
 if(z.C(c,b)||z.D(c,P.E4.prototype.t.call(this,this,"length")))H.vh(P.TE(c,b,P.E4.prototype.t.call(this,this,"length")))
 y=z.W(c,b)
 if(J.de(y,0))return
+if(e<0)throw H.b(new P.AT(e))
 x=[b,y]
 z=new H.nH(d,e,null)
 z.$builtinTypeInfo=[null]
 if(e<0)H.vh(P.N(e))
 C.Nm.FV(x,z.qZ(0,y))
-this.V7("splice",x)},"call$4","gam",6,2,null,336,115,116,109,117],
-So:[function(a,b){this.V7("sort",[b])},"call$1","gH7",0,2,null,77,128]},
+this.V7("splice",x)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+GT:[function(a,b){this.V7("sort",[b])},"call$1","gH7",0,2,null,77,128,[]]},
 Wk:{
-"":"E4+lD;",
+"^":"E4+lD;",
 $isList:true,
 $asWO:null,
 $isyN:true,
 $iscX:true,
 $ascX:null},
 DV:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=P.xZ(a,!1)
-P.Dm(z,"_$dart_dartClosure",a)
-return z},"call$1",null,2,0,null,91,"call"],
+P.Dm(z,$.Dp(),a)
+return z},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Hp:{
-"":"Tp:229;",
-call$1:[function(a){return new DartObject(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new DartObject(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Nz:{
-"":"Tp:229;",
-call$1:[function(a){return new P.r7(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new P.r7(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 Jd:{
-"":"Tp:229;",
-call$1:[function(a){return H.VM(new P.Tz(a),[null])},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return H.VM(new P.Tz(a),[null])},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true},
 QS:{
-"":"Tp:229;",
-call$1:[function(a){return new P.E4(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return new P.E4(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true}}],["dart.math","dart:math",,P,{
-"":"",
+"^":"",
 J:[function(a,b){var z
 if(typeof a!=="number")throw H.b(new P.AT(a))
 if(typeof b!=="number")throw H.b(new P.AT(b))
@@ -17085,289 +17288,360 @@
 if(a===0)z=b===0?1/b<0:b<0
 else z=!1
 if(z||isNaN(b))return b
-return a}return a},"call$2","yT",4,0,null,123,180],
+return a}return a},"call$2","yT",4,0,null,123,[],180,[]],
 y:[function(a,b){if(typeof a!=="number")throw H.b(new P.AT(a))
 if(typeof b!=="number")throw H.b(new P.AT(b))
 if(a>b)return a
 if(a<b)return b
 if(typeof b==="number"){if(typeof a==="number")if(a===0)return a+b
-if(C.YI.gG0(b))return b
+if(C.ON.gG0(b))return b
 return a}if(b===0&&C.CD.gzP(a))return b
-return a},"call$2","Yr",4,0,null,123,180]}],["dart.mirrors","dart:mirrors",,P,{
-"":"",
+return a},"call$2","Yr",4,0,null,123,[],180,[]]}],["dart.mirrors","dart:mirrors",,P,{
+"^":"",
 re:[function(a){var z,y
 z=J.x(a)
 if(typeof a!=="object"||a===null||!z.$isuq||z.n(a,C.HH))throw H.b(new P.AT(H.d(a)+" does not denote a class"))
 y=P.o1(a)
 z=J.x(y)
 if(typeof y!=="object"||y===null||!z.$isMs)throw H.b(new P.AT(H.d(a)+" does not denote a class"))
-return y.gJi()},"call$1","vG",2,0,null,42],
+return y.gJi()},"call$1","vG",2,0,null,42,[]],
 o1:[function(a){if(J.de(a,C.HH)){$.Cm().toString
-return $.Cr()}return H.jO(a.gLU())},"call$1","o9",2,0,null,42],
+return $.P8()}return H.jO(a.gLU())},"call$1","o9",2,0,null,42,[]],
 ej:{
-"":"a;",
+"^":"a;",
 $isej:true},
 NL:{
-"":"a;",
+"^":"a;",
 $isNL:true,
 $isej:true},
 vr:{
-"":"a;",
+"^":"a;",
 $isvr:true,
 $isej:true},
 D4:{
-"":"a;",
+"^":"a;",
 $isD4:true,
 $isej:true,
 $isNL:true},
 X9:{
-"":"a;",
+"^":"a;",
 $isX9:true,
 $isNL:true,
 $isej:true},
 Ms:{
-"":"a;",
+"^":"a;",
 $isMs:true,
 $isej:true,
 $isX9:true,
 $isNL:true},
-tg:{
-"":"X9;",
-$istg:true},
+ac:{
+"^":"X9;",
+$isac:true},
 RS:{
-"":"a;",
+"^":"a;",
 $isRS:true,
 $isNL:true,
 $isej:true},
 RY:{
-"":"a;",
+"^":"a;",
 $isRY:true,
 $isNL:true,
 $isej:true},
 Ys:{
-"":"a;",
+"^":"a;",
 $isYs:true,
 $isRY:true,
 $isNL:true,
 $isej:true},
 WS4:{
-"":"a;EE,m2,nV,V3"}}],["dart.pkg.collection.wrappers","package:collection/wrappers.dart",,Q,{
-"":"",
+"^":"a;ew,yz,nV,V3"}}],["dart.pkg.collection.wrappers","package:collection/wrappers.dart",,Q,{
+"^":"",
 ah:[function(){throw H.b(P.f("Cannot modify an unmodifiable Map"))},"call$0","A9",0,0,null],
-A2:{
-"":"U4;EV"},
+Gj:{
+"^":"U4;EV"},
 U4:{
-"":"Nx+B8q;",
+"^":"Nx+B8q;",
 $isZ0:true},
 B8q:{
-"":"a;",
-u:[function(a,b,c){return Q.ah()},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){return Q.ah()},"call$1","gDY",2,0,null,104],
-Rz:[function(a,b){Q.ah()},"call$1","gRI",2,0,null,42],
+"^":"a;",
+u:[function(a,b,c){return Q.ah()},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){return Q.ah()},"call$1","gDY",2,0,null,104,[]],
+Rz:[function(a,b){Q.ah()},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){return Q.ah()},"call$0","gyP",0,0,null],
 $isZ0:true},
 Nx:{
-"":"a;",
-t:[function(a,b){return this.EV.t(0,b)},"call$1","gIA",2,0,null,42],
-u:[function(a,b,c){this.EV.u(0,b,c)},"call$2","gj3",4,0,null,42,23],
-FV:[function(a,b){this.EV.FV(0,b)},"call$1","gDY",2,0,null,104],
+"^":"a;",
+t:[function(a,b){return this.EV.t(0,b)},"call$1","gIA",2,0,null,42,[]],
+u:[function(a,b,c){this.EV.u(0,b,c)},"call$2","gj3",4,0,null,42,[],23,[]],
+FV:[function(a,b){this.EV.FV(0,b)},"call$1","gDY",2,0,null,104,[]],
 V1:[function(a){this.EV.V1(0)},"call$0","gyP",0,0,null],
-x4:[function(a){return this.EV.x4(a)},"call$1","gV9",2,0,null,42],
-di:[function(a){return this.EV.di(a)},"call$1","gmc",2,0,null,23],
-aN:[function(a,b){this.EV.aN(0,b)},"call$1","gjw",2,0,null,110],
+x4:[function(a){return this.EV.x4(a)},"call$1","gV9",2,0,null,42,[]],
+di:[function(a){return this.EV.di(a)},"call$1","gmc",2,0,null,23,[]],
+aN:[function(a,b){this.EV.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 gl0:function(a){return this.EV.X5===0},
 gor:function(a){return this.EV.X5!==0},
 gvc:function(a){var z=this.EV
 return H.VM(new P.i5(z),[H.Kp(z,0)])},
 gB:function(a){return this.EV.X5},
-Rz:[function(a,b){return this.EV.Rz(0,b)},"call$1","gRI",2,0,null,42],
+Rz:[function(a,b){return this.EV.Rz(0,b)},"call$1","gRI",2,0,null,42,[]],
 gUQ:function(a){var z=this.EV
 return z.gUQ(z)},
-$isZ0:true}}],["dart.typed_data","dart:typed_data",,P,{
-"":"",
-q3:function(a){a.toString
+$isZ0:true}}],["dart.typed_data.implementation","dart:_native_typed_data",,H,{
+"^":"",
+UI:function(a){a.toString
 return a},
-l6:function(a){a.toString
+bu:function(a){a.toString
 return a},
-am:function(a){a.toString
+aR:function(a){a.toString
 return a},
-I2:{
-"":"Gv;",
-$isI2:true,
+WZ:{
+"^":"Gv;",
+gbx:function(a){return C.PT},
+$isWZ:true,
 "%":"ArrayBuffer"},
-HY:{
-"":"Gv;",
-aq:[function(a,b,c){var z=J.Wx(b)
+rn:{
+"^":"Gv;",
+J2:[function(a,b,c){var z=J.Wx(b)
 if(z.C(b,0)||z.F(b,c))throw H.b(P.TE(b,0,c))
-else throw H.b(new P.AT("Invalid list index "+H.d(b)))},"call$2","gDq",4,0,null,47,331],
-iA:[function(a,b,c){if(b>>>0!=b||J.J5(b,c))this.aq(a,b,c)},"call$2","gur",4,0,null,47,331],
-Im:[function(a,b,c,d){var z=d+1
-this.iA(a,b,z)
+else throw H.b(new P.AT("Invalid list index "+H.d(b)))},"call$2","gYE",4,0,null,47,[],325,[]],
+XL:[function(a,b,c){if(b>>>0!=b||J.J5(b,c))this.J2(a,b,c)},"call$2","gDR",4,0,null,47,[],325,[]],
+PZ:[function(a,b,c,d){var z=d+1
+this.XL(a,b,z)
 if(c==null)return d
-this.iA(a,c,z)
+this.XL(a,c,z)
 if(typeof c!=="number")return H.s(c)
 if(b>c)throw H.b(P.TE(b,0,c))
-return c},"call$3","gEU",6,0,null,115,116,331],
+return c},"call$3","gyD",6,0,null,115,[],116,[],325,[]],
+$isrn:true,
 $isHY:true,
-"%":"DataView;ArrayBufferView;ue|Y8|Bk|GG|C0A|RAK|iY"},
-Nn:{
-"":"GG;",
+"%":";ArrayBufferView;LZ|Ob|Ip|Dg|Nb|nA|Pg"},
+df:{
+"^":"rn;",
+gbx:function(a){return C.T1},
+$isHY:true,
+"%":"DataView"},
+Hg:{
+"^":"Dg;",
+gbx:function(a){return C.hN},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Float32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Float32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.GW]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.GW]},
+$isHY:true,
 "%":"Float32Array"},
-Un:{
-"":"GG;",
+L3:{
+"^":"Dg;",
+gbx:function(a){return C.lk},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Float64Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Float64Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.GW]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.GW]},
+$isHY:true,
 "%":"Float64Array"},
-rF:{
-"":"iY;",
+xj:{
+"^":"Pg;",
+gbx:function(a){return C.jV},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int16Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int16Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int16Array"},
-Sb:{
-"":"iY;",
+dE:{
+"^":"Pg;",
+gbx:function(a){return C.Im},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int32Array"},
-UZ:{
-"":"iY;",
+Eb:{
+"^":"Pg;",
+gbx:function(a){return C.la},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Int8Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Int8Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Int8Array"},
-yc:{
-"":"iY;",
+dT:{
+"^":"Pg;",
+gbx:function(a){return C.iN},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint16Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint16Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Uint16Array"},
-Aw:{
-"":"iY;",
+N2:{
+"^":"Pg;",
+gbx:function(a){return C.Vh},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint32Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint32Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"Uint32Array"},
-jx:{
-"":"iY;",
+eE:{
+"^":"Pg;",
+gbx:function(a){return C.nG},
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint8ClampedArray(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint8ClampedArray(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":"CanvasPixelArray|Uint8ClampedArray"},
-F0:{
-"":"iY;",
+V6:{
+"^":"Pg;",
+gbx:function(a){return C.eY},
 gB:function(a){return a.length},
 t:[function(a,b){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-return a[b]},"call$1","gIA",2,0,null,47],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+return a[b]},"call$1","gIA",2,0,null,47,[]],
 u:[function(a,b,c){var z=a.length
-if(b>>>0!=b||J.J5(b,z))this.aq(a,b,z)
-a[b]=c},"call$2","gj3",4,0,null,47,23],
-D6:[function(a,b,c){return new Uint8Array(a.subarray(b,this.Im(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,116],
+if(b>>>0!=b||J.J5(b,z))this.J2(a,b,z)
+a[b]=c},"call$2","gj3",4,0,null,47,[],23,[]],
+D6:[function(a,b,c){return new Uint8Array(a.subarray(b,this.PZ(a,b,c,a.length)))},function(a,b){return this.D6(a,b,null)},"Jk","call$2",null,"gli",2,2,null,77,115,[],116,[]],
+$isList:true,
+$asWO:function(){return[J.im]},
+$isyN:true,
+$iscX:true,
+$ascX:function(){return[J.im]},
+$isHY:true,
 "%":";Uint8Array"},
-ue:{
-"":"HY;",
+LZ:{
+"^":"rn;",
 gB:function(a){return a.length},
-wY:[function(a,b,c,d,e){var z,y,x
+oZ:[function(a,b,c,d,e){var z,y,x
 z=a.length+1
-this.iA(a,b,z)
-this.iA(a,c,z)
+this.XL(a,b,z)
+this.XL(a,c,z)
 if(typeof c!=="number")return H.s(c)
 if(b>c)throw H.b(P.TE(b,0,c))
 y=c-b
+if(e<0)throw H.b(new P.AT(e))
 x=d.length
 if(x-e<y)throw H.b(new P.lj("Not enough elements"))
 if(e!==0||x!==y)d=d.subarray(e,e+y)
-a.set(d,b)},"call$4","gzB",8,0,null,115,116,27,117],
+a.set(d,b)},"call$4","gP7",8,0,null,115,[],116,[],27,[],117,[]],
 $isXj:true},
-GG:{
-"":"Bk;",
+Dg:{
+"^":"Ip;",
 YW:[function(a,b,c,d,e){var z=J.x(d)
-if(!!z.$isGG){this.wY(a,b,c,d,e)
-return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,336,115,116,109,117],
-$isGG:true,
+if(!!z.$isDg){this.oZ(a,b,c,d,e)
+return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+$isDg:true,
 $isList:true,
 $asWO:function(){return[J.GW]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.GW]}},
-Y8:{
-"":"ue+lD;",
+Ob:{
+"^":"LZ+lD;",
 $isList:true,
 $asWO:function(){return[J.GW]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.GW]}},
-Bk:{
-"":"Y8+SU7;"},
-iY:{
-"":"RAK;",
+Ip:{
+"^":"Ob+SU7;"},
+Pg:{
+"^":"nA;",
 YW:[function(a,b,c,d,e){var z=J.x(d)
-if(!!z.$isiY){this.wY(a,b,c,d,e)
-return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,336,115,116,109,117],
-$isiY:true,
+if(!!z.$isPg){this.oZ(a,b,c,d,e)
+return}P.lD.prototype.YW.call(this,a,b,c,d,e)},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+$isPg:true,
 $isList:true,
 $asWO:function(){return[J.im]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.im]}},
-C0A:{
-"":"ue+lD;",
+Nb:{
+"^":"LZ+lD;",
 $isList:true,
 $asWO:function(){return[J.im]},
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.im]}},
-RAK:{
-"":"C0A+SU7;"}}],["dart2js._js_primitives","dart:_js_primitives",,H,{
-"":"",
+nA:{
+"^":"Nb+SU7;"}}],["dart2js._js_primitives","dart:_js_primitives",,H,{
+"^":"",
 qw:[function(a){if(typeof dartPrint=="function"){dartPrint(a)
 return}if(typeof console=="object"&&typeof console.log=="function"){console.log(a)
 return}if(typeof window=="object")return
 if(typeof print=="function"){print(a)
-return}throw "Unable to print message: " + String(a)},"call$1","XU",2,0,null,26]}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{
-"":"",
-FvP:{
-"":["tuj;m0%-459,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gNI:[function(a){return a.m0},null,null,1,0,460,"instruction",359,360],
-sNI:[function(a,b){a.m0=this.ct(a,C.eJ,a.m0,b)},null,null,3,0,461,23,"instruction",359],
+return}throw "Unable to print message: " + String(a)},"call$1","XU",2,0,null,26,[]]}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{
+"^":"",
+Fv:{
+"^":["tuj;F8%-455,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNI:[function(a){return a.F8},null,null,1,0,456,"instruction",351,352],
+sNI:[function(a,b){a.F8=this.ct(a,C.eJ,a.F8,b)},null,null,3,0,457,23,[],"instruction",351],
 "@":function(){return[C.Vy]},
 static:{AH:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17377,19 +17651,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.Tl.ZL(a)
-C.Tl.oX(a)
-return a},null,null,0,0,108,"new DisassemblyEntryElement$created" /* new DisassemblyEntryElement$created:0:0 */]}},
-"+DisassemblyEntryElement":[462],
+a.X0=w
+C.er.ZL(a)
+C.er.G6(a)
+return a},null,null,0,0,108,"new DisassemblyEntryElement$created"]}},
+"+DisassemblyEntryElement":[458],
 tuj:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["error_view_element","package:observatory/src/observatory_elements/error_view.dart",,F,{
-"":"",
-Ir:{
-"":["Vct;Py%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gkc:[function(a){return a.Py},null,null,1,0,358,"error",359,360],
-skc:[function(a,b){a.Py=this.ct(a,C.YU,a.Py,b)},null,null,3,0,361,23,"error",359],
+"^":"",
+E9:{
+"^":["Vct;Py%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gkc:[function(a){return a.Py},null,null,1,0,350,"error",351,352],
+skc:[function(a,b){a.Py=this.ct(a,C.YU,a.Py,b)},null,null,3,0,353,23,[],"error",351],
 "@":function(){return[C.uW]},
 static:{TW:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17399,17 +17673,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.OD.ZL(a)
-C.OD.oX(a)
-return a},null,null,0,0,108,"new ErrorViewElement$created" /* new ErrorViewElement$created:0:0 */]}},
-"+ErrorViewElement":[463],
+C.OD.G6(a)
+return a},null,null,0,0,108,"new ErrorViewElement$created"]}},
+"+ErrorViewElement":[459],
 Vct:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["field_ref_element","package:observatory/src/observatory_elements/field_ref.dart",,D,{
-"":"",
+"^":"",
 m8:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.E6]},
 static:{Tt:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17418,18 +17692,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.MC.ZL(a)
-C.MC.oX(a)
-return a},null,null,0,0,108,"new FieldRefElement$created" /* new FieldRefElement$created:0:0 */]}},
-"+FieldRefElement":[364]}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{
-"":"",
-jM:{
-"":["D13;vt%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gt0:[function(a){return a.vt},null,null,1,0,358,"field",359,360],
-st0:[function(a,b){a.vt=this.ct(a,C.WQ,a.vt,b)},null,null,3,0,361,23,"field",359],
+C.MC.G6(a)
+return a},null,null,0,0,108,"new FieldRefElement$created"]}},
+"+FieldRefElement":[357]}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{
+"^":"",
+Gk:{
+"^":["D13;vt%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gt0:[function(a){return a.vt},null,null,1,0,350,"field",351,352],
+st0:[function(a,b){a.vt=this.ct(a,C.WQ,a.vt,b)},null,null,3,0,353,23,[],"field",351],
 "@":function(){return[C.Tq]},
 static:{cY:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17439,17 +17714,17 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.LT.ZL(a)
-C.LT.oX(a)
-return a},null,null,0,0,108,"new FieldViewElement$created" /* new FieldViewElement$created:0:0 */]}},
-"+FieldViewElement":[464],
+C.LT.G6(a)
+return a},null,null,0,0,108,"new FieldViewElement$created"]}},
+"+FieldViewElement":[460],
 D13:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["function_ref_element","package:observatory/src/observatory_elements/function_ref.dart",,U,{
-"":"",
-DKl:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":"",
+GG:{
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.YQ]},
 static:{v9:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17458,18 +17733,19 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Xo.ZL(a)
-C.Xo.oX(a)
-return a},null,null,0,0,108,"new FunctionRefElement$created" /* new FunctionRefElement$created:0:0 */]}},
-"+FunctionRefElement":[364]}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{
-"":"",
-mk:{
-"":["WZq;Z8%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gMj:[function(a){return a.Z8},null,null,1,0,358,"function",359,360],
-sMj:[function(a,b){a.Z8=this.ct(a,C.nf,a.Z8,b)},null,null,3,0,361,23,"function",359],
+C.Xo.G6(a)
+return a},null,null,0,0,108,"new FunctionRefElement$created"]}},
+"+FunctionRefElement":[357]}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{
+"^":"",
+yb:{
+"^":["WZq;Z8%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gMj:[function(a){return a.Z8},null,null,1,0,350,"function",351,352],
+sMj:[function(a,b){a.Z8=this.ct(a,C.nf,a.Z8,b)},null,null,3,0,353,23,[],"function",351],
 "@":function(){return[C.nu]},
 static:{N0:[function(a){var z,y,x,w
 z=$.Nd()
@@ -17479,19 +17755,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.PJ.ZL(a)
-C.PJ.oX(a)
-return a},null,null,0,0,108,"new FunctionViewElement$created" /* new FunctionViewElement$created:0:0 */]}},
-"+FunctionViewElement":[465],
+a.X0=w
+C.Yu.ZL(a)
+C.Yu.G6(a)
+return a},null,null,0,0,108,"new FunctionViewElement$created"]}},
+"+FunctionViewElement":[461],
 WZq:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["heap_profile_element","package:observatory/src/observatory_elements/heap_profile.dart",,K,{
-"":"",
+"^":"",
 NM:{
-"":["pva;GQ%-77,J0%-77,Oc%-77,CO%-77,e6%-77,an%-77,Ol%-355,X3%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gB1:[function(a){return a.Ol},null,null,1,0,358,"profile",359,360],
-sB1:[function(a,b){a.Ol=this.ct(a,C.vb,a.Ol,b)},null,null,3,0,361,23,"profile",359],
+"^":["pva;GQ%-77,J0%-77,Oc%-77,CO%-77,e6%-77,an%-77,Ol%-347,X3%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gB1:[function(a){return a.Ol},null,null,1,0,350,"profile",351,352],
+sB1:[function(a,b){a.Ol=this.ct(a,C.vb,a.Ol,b)},null,null,3,0,353,23,[],"profile",351],
 i4:[function(a){var z,y
 Z.uL.prototype.i4.call(this,a)
 z=(a.shadowRoot||a.webkitShadowRoot).querySelector("#table")
@@ -17499,8 +17775,8 @@
 y.YZ=P.uw(J.UQ($.NR,"Table"),[z])
 a.an=y
 y.bG.u(0,"allowHtml",!0)
-J.kW(J.Wy(a.an),"sortColumn",1)
-J.kW(J.Wy(a.an),"sortAscending",!1)
+J.kW(J.wc(a.an),"sortColumn",1)
+J.kW(J.wc(a.an),"sortAscending",!1)
 y=(a.shadowRoot||a.webkitShadowRoot).querySelector("#newPieChart")
 z=new L.qu(null,P.L5(null,null,null,null,null))
 z.YZ=P.uw(J.UQ($.NR,"PieChart"),[y])
@@ -17549,33 +17825,33 @@
 case 6:return J.UQ(J.UQ(b,"old"),5)
 case 7:return J.UQ(J.UQ(b,"old"),1)
 case 8:return J.UQ(J.UQ(b,"old"),3)
-default:}},"call$2","gJ2",4,0,466,277,47,"_columnValue"],
+default:}return},"call$2","gGm",4,0,462,272,[],47,[],"_columnValue"],
 Ub:[function(a,b,c,d){var z,y
 z=a.hm.gZ6().R6()
 if(a.hm.gnI().AQ(z)==null){N.Jx("").To("No isolate found.")
 return}y="/"+z+"/allocationprofile"
-a.hm.glw().fB(y).ml(new K.bd(a)).OA(new K.LS())},"call$3","gFz",6,0,376,18,307,74,"refreshData"],
+a.hm.gDF().fB(y).ml(new K.bd(a)).OA(new K.LS())},"call$3","gFz",6,0,369,18,[],301,[],74,[],"refreshData"],
 pM:[function(a,b){this.hZ(a)
 this.ct(a,C.Aq,[],this.gOd(a))
 this.ct(a,C.ST,[],this.goN(a))
-this.ct(a,C.WG,[],this.gBo(a))},"call$1","gaz",2,0,152,231,"profileChanged"],
+this.ct(a,C.WG,[],this.gBo(a))},"call$1","gaz",2,0,150,225,[],"profileChanged"],
 ps:[function(a,b){var z,y,x
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
 x=J.UQ(J.UQ(z,"heaps"),y)
 z=J.U6(x)
-return C.CD.yM(J.FW(J.p0(z.t(x,"time"),1000),z.t(x,"collections")),2)+" ms"},"call$1","gOd",2,0,467,468,"formattedAverage",372],
+return C.CD.yM(J.FW(J.p0(z.t(x,"time"),1000),z.t(x,"collections")),2)+" ms"},"call$1","gOd",2,0,463,464,[],"formattedAverage",365],
 NC:[function(a,b){var z,y
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
-return H.d(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"collections"))},"call$1","gBo",2,0,467,468,"formattedCollections",372],
+return H.d(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"collections"))},"call$1","gBo",2,0,463,464,[],"formattedCollections",365],
 Q0:[function(a,b){var z,y
 z=a.Ol
 if(z==null)return""
 y=b===!0?"new":"old"
-return J.Ez(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"time"),2)+" secs"},"call$1","goN",2,0,467,468,"formattedTotalCollectionTime",372],
+return J.Ez(J.UQ(J.UQ(J.UQ(z,"heaps"),y),"time"),2)+" secs"},"call$1","goN",2,0,463,464,[],"formattedTotalCollectionTime",365],
 Dd:[function(a){var z=new L.Kf(P.uw(J.UQ($.NR,"DataTable"),null))
 a.e6=z
 z.Gl("string","Class")
@@ -17596,7 +17872,7 @@
 z.Gl("string","Type")
 a.Oc.Gl("number","Size")},null,null,0,0,108,"created"],
 "@":function(){return[C.dA]},
-static:{"":"BO<-77,Hg<-77,xK<-77,V1g<-77,jr<-77,d6<-77",op:[function(a){var z,y,x,w
+static:{"^":"BO<-77,Xa<-77,xK<-77,V1g<-77,r1K<-77,d6<-77",op:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -17605,36 +17881,36 @@
 a.X3=!0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Vc.ZL(a)
-C.Vc.oX(a)
+C.Vc.G6(a)
 C.Vc.Dd(a)
-return a},null,null,0,0,108,"new HeapProfileElement$created" /* new HeapProfileElement$created:0:0 */]}},
-"+HeapProfileElement":[469],
+return a},null,null,0,0,108,"new HeapProfileElement$created"]}},
+"+HeapProfileElement":[465],
 pva:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true},
 bd:{
-"":"Tp:361;a-77",
+"^":"Tp:353;a-77",
 call$1:[function(a){var z,y
 z=this.a
 y=J.RE(z)
-y.sOl(z,y.ct(z,C.vb,y.gOl(z),a))},"call$1",null,2,0,361,470,"call"],
+y.sOl(z,y.ct(z,C.vb,y.gOl(z),a))},"call$1",null,2,0,353,466,[],"call"],
 $isEH:true},
-"+HeapProfileElement_refreshData_closure":[471],
+"+HeapProfileElement_refreshData_closure":[467],
 LS:{
-"":"Tp:349;",
-call$2:[function(a,b){N.Jx("").To(H.d(a)+" "+H.d(b))},"call$2",null,4,0,349,18,472,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").To(H.d(a)+" "+H.d(b))},"call$2",null,4,0,341,18,[],468,[],"call"],
 $isEH:true},
-"+HeapProfileElement_refreshData_closure":[471]}],["html_common","dart:html_common",,P,{
-"":"",
+"+HeapProfileElement_refreshData_closure":[467]}],["html_common","dart:html_common",,P,{
+"^":"",
 bL:[function(a){var z,y
 z=[]
 y=new P.Tm(new P.aI([],z),new P.rG(z),new P.yh(z)).call$1(a)
 new P.wO().call$0()
-return y},"call$1","z1",2,0,null,23],
+return y},"call$1","Lq",2,0,null,23,[]],
 o7:[function(a,b){var z=[]
-return new P.xL(b,new P.CA([],z),new P.YL(z),new P.KC(z)).call$1(a)},"call$2$mustCopy","A1",2,3,null,209,6,239],
+return new P.xL(b,new P.CA([],z),new P.YL(z),new P.KC(z)).call$1(a)},"call$2$mustCopy","A1",2,3,null,205,6,[],233,[]],
 dg:function(){var z=$.L4
 if(z==null){z=J.Vw(window.navigator.userAgent,"Opera",0)
 $.L4=z}return z},
@@ -17642,33 +17918,33 @@
 if(z==null){z=P.dg()!==!0&&J.Vw(window.navigator.userAgent,"WebKit",0)
 $.PN=z}return z},
 aI:{
-"":"Tp:181;b,c",
+"^":"Tp:181;b,c",
 call$1:[function(a){var z,y,x
 z=this.b
 y=z.length
 for(x=0;x<y;++x)if(z[x]===a)return x
 z.push(a)
 this.c.push(null)
-return y},"call$1",null,2,0,null,23,"call"],
+return y},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 rG:{
-"":"Tp:390;d",
+"^":"Tp:385;d",
 call$1:[function(a){var z=this.d
 if(a>=z.length)return H.e(z,a)
-return z[a]},"call$1",null,2,0,null,341,"call"],
+return z[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 yh:{
-"":"Tp:473;e",
+"^":"Tp:469;e",
 call$2:[function(a,b){var z=this.e
 if(a>=z.length)return H.e(z,a)
-z[a]=b},"call$2",null,4,0,null,341,21,"call"],
+z[a]=b},"call$2",null,4,0,null,383,[],21,[],"call"],
 $isEH:true},
 wO:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Tm:{
-"":"Tp:229;f,UI,bK",
+"^":"Tp:223;f,UI,bK",
 call$1:[function(a){var z,y,x,w,v,u
 z={}
 if(a==null)return a
@@ -17681,8 +17957,8 @@
 if(typeof a==="object"&&a!==null&&!!y.$ishH)return a
 if(typeof a==="object"&&a!==null&&!!y.$isAz)return a
 if(typeof a==="object"&&a!==null&&!!y.$isSg)return a
-if(typeof a==="object"&&a!==null&&!!y.$isI2)return a
-if(typeof a==="object"&&a!==null&&!!y.$isHY)return a
+if(typeof a==="object"&&a!==null&&!!y.$isWZ)return a
+if(typeof a==="object"&&a!==null&&!!y.$isrn)return a
 if(typeof a==="object"&&a!==null&&!!y.$isZ0){x=this.f.call$1(a)
 w=this.UI.call$1(x)
 z.a=w
@@ -17690,7 +17966,7 @@
 w={}
 z.a=w
 this.bK.call$2(x,w)
-y.aN(a,new P.rz(z,this))
+y.aN(a,new P.q1(z,this))
 return z.a}if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!y.$isList)){v=y.gB(a)
 x=this.f.call$1(a)
 w=this.UI.call$1(x)
@@ -17701,36 +17977,36 @@
 u=0
 for(;u<v;++u){z=this.call$1(y.t(a,u))
 if(u>=w.length)return H.e(w,u)
-w[u]=z}return w}throw H.b(P.SY("structured clone of other type"))},"call$1",null,2,0,null,18,"call"],
+w[u]=z}return w}throw H.b(P.SY("structured clone of other type"))},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
-rz:{
-"":"Tp:349;a,Gq",
-call$2:[function(a,b){this.a.a[a]=this.Gq.call$1(b)},"call$2",null,4,0,null,42,23,"call"],
+q1:{
+"^":"Tp:341;a,Gq",
+call$2:[function(a,b){this.a.a[a]=this.Gq.call$1(b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true},
 CA:{
-"":"Tp:181;a,b",
+"^":"Tp:181;a,b",
 call$1:[function(a){var z,y,x,w
 z=this.a
 y=z.length
 for(x=0;x<y;++x){w=z[x]
 if(w==null?a==null:w===a)return x}z.push(a)
 this.b.push(null)
-return y},"call$1",null,2,0,null,23,"call"],
+return y},"call$1",null,2,0,null,23,[],"call"],
 $isEH:true},
 YL:{
-"":"Tp:390;c",
+"^":"Tp:385;c",
 call$1:[function(a){var z=this.c
 if(a>=z.length)return H.e(z,a)
-return z[a]},"call$1",null,2,0,null,341,"call"],
+return z[a]},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true},
 KC:{
-"":"Tp:473;d",
+"^":"Tp:469;d",
 call$2:[function(a,b){var z=this.d
 if(a>=z.length)return H.e(z,a)
-z[a]=b},"call$2",null,4,0,null,341,21,"call"],
+z[a]=b},"call$2",null,4,0,null,383,[],21,[],"call"],
 $isEH:true},
 xL:{
-"":"Tp:229;e,f,UI,bK",
+"^":"Tp:223;e,f,UI,bK",
 call$1:[function(a){var z,y,x,w,v,u,t
 if(a==null)return a
 if(typeof a==="boolean")return a
@@ -17755,87 +18031,100 @@
 u=J.w1(y)
 t=0
 for(;t<v;++t)u.u(y,t,this.call$1(x.t(a,t)))
-return y}return a},"call$1",null,2,0,null,18,"call"],
+return y}return a},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
-Ay:{
-"":"a;",
+As:{
+"^":"a;",
 bu:[function(a){return this.lF().zV(0," ")},"call$0","gXo",0,0,null],
+O4:[function(a,b){var z,y
+z=this.lF()
+if(!z.tg(0,a)===!0){z.h(0,a)
+y=!0}else{z.Rz(0,a)
+y=!1}this.p5(z)
+return y},function(a){return this.O4(a,null)},"qU","call$2",null,"gMk",2,2,null,77,23,[],450,[]],
 gA:function(a){var z=this.lF()
 z=H.VM(new P.zQ(z,z.zN,null,null),[null])
 z.zq=z.O2.H9
 return z},
-aN:[function(a,b){this.lF().aN(0,b)},"call$1","gjw",2,0,null,110],
-zV:[function(a,b){return this.lF().zV(0,b)},"call$1","gnr",0,2,null,334,335],
+aN:[function(a,b){this.lF().aN(0,b)},"call$1","gjw",2,0,null,110,[]],
+zV:[function(a,b){return this.lF().zV(0,b)},"call$1","gnr",0,2,null,328,329,[]],
 ez:[function(a,b){var z=this.lF()
-return H.K1(z,b,H.ip(z,"mW",0),null)},"call$1","gIr",2,0,null,110],
+return H.K1(z,b,H.ip(z,"mW",0),null)},"call$1","gIr",2,0,null,110,[]],
 ev:[function(a,b){var z=this.lF()
-return H.VM(new H.U5(z,b),[H.ip(z,"mW",0)])},"call$1","gIR",2,0,null,110],
-Vr:[function(a,b){return this.lF().Vr(0,b)},"call$1","gG2",2,0,null,110],
+return H.VM(new H.U5(z,b),[H.ip(z,"mW",0)])},"call$1","gIR",2,0,null,110,[]],
+Vr:[function(a,b){return this.lF().Vr(0,b)},"call$1","gG2",2,0,null,110,[]],
 gl0:function(a){return this.lF().X5===0},
 gor:function(a){return this.lF().X5!==0},
 gB:function(a){return this.lF().X5},
-tg:[function(a,b){return this.lF().tg(0,b)},"call$1","gdj",2,0,null,23],
-Zt:[function(a){return this.lF().tg(0,a)?a:null},"call$1","gQB",2,0,null,23],
-h:[function(a,b){return this.OS(new P.GE(b))},"call$1","ght",2,0,null,23],
+tg:[function(a,b){return this.lF().tg(0,b)},"call$1","gdj",2,0,null,23,[]],
+Zt:[function(a){return this.lF().tg(0,a)?a:null},"call$1","gQB",2,0,null,23,[]],
+h:[function(a,b){return this.OS(new P.GE(b))},"call$1","ght",2,0,null,23,[]],
 Rz:[function(a,b){var z,y
 if(typeof b!=="string")return!1
 z=this.lF()
 y=z.Rz(0,b)
 this.p5(z)
-return y},"call$1","gRI",2,0,null,23],
-FV:[function(a,b){this.OS(new P.rl(b))},"call$1","gDY",2,0,null,109],
+return y},"call$1","gRI",2,0,null,23,[]],
+FV:[function(a,b){this.OS(new P.rl(b))},"call$1","gDY",2,0,null,109,[]],
 grZ:function(a){var z=this.lF().lX
 if(z==null)H.vh(new P.lj("No elements"))
 return z.gGc()},
-tt:[function(a,b){return this.lF().tt(0,b)},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,337,338],
+tt:[function(a,b){return this.lF().tt(0,b)},function(a){return this.tt(a,!0)},"br","call$1$growable",null,"gRV",0,3,null,331,332,[]],
 eR:[function(a,b){var z=this.lF()
-return H.ke(z,b,H.ip(z,"mW",0))},"call$1","gVQ",2,0,null,292],
-Zv:[function(a,b){return this.lF().Zv(0,b)},"call$1","goY",2,0,null,47],
+return H.ke(z,b,H.ip(z,"mW",0))},"call$1","gZo",2,0,null,287,[]],
+Zv:[function(a,b){return this.lF().Zv(0,b)},"call$1","goY",2,0,null,47,[]],
 V1:[function(a){this.OS(new P.uQ())},"call$0","gyP",0,0,null],
 OS:[function(a){var z,y
 z=this.lF()
 y=a.call$1(z)
 this.p5(z)
-return y},"call$1","gFd",2,0,null,110],
+return y},"call$1","gFd",2,0,null,110,[]],
 $isyN:true,
 $iscX:true,
 $ascX:function(){return[J.O]}},
 GE:{
-"":"Tp:229;a",
-call$1:[function(a){return a.h(0,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.h(0,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 rl:{
-"":"Tp:229;a",
-call$1:[function(a){return a.FV(0,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return a.FV(0,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 uQ:{
-"":"Tp:229;",
-call$1:[function(a){return a.V1(0)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a.V1(0)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 D7:{
-"":"ar;F1,h2",
+"^":"ar;F1,h2",
 gzT:function(){var z=this.h2
 return P.F(z.ev(z,new P.hT()),!0,W.cv)},
-aN:[function(a,b){H.bQ(this.gzT(),b)},"call$1","gjw",2,0,null,110],
+aN:[function(a,b){H.bQ(this.gzT(),b)},"call$1","gjw",2,0,null,110,[]],
 u:[function(a,b,c){var z=this.gzT()
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-J.ZP(z[b],c)},"call$2","gj3",4,0,null,47,23],
+J.ZP(z[b],c)},"call$2","gj3",4,0,null,47,[],23,[]],
 sB:function(a,b){var z,y
 z=this.gzT().length
 y=J.Wx(b)
 if(y.F(b,z))return
 else if(y.C(b,0))throw H.b(new P.AT("Invalid list length"))
 this.UZ(0,b,z)},
-h:[function(a,b){this.h2.NL.appendChild(b)},"call$1","ght",2,0,null,23],
+h:[function(a,b){this.h2.NL.appendChild(b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y
-for(z=J.GP(b),y=this.h2.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109],
+for(z=J.GP(b),y=this.h2.NL;z.G();)y.appendChild(z.gl())},"call$1","gDY",2,0,null,109,[]],
 tg:[function(a,b){var z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$iscv)return!1
-return b.parentNode===this.F1},"call$1","gdj",2,0,null,102],
-So:[function(a,b){throw H.b(P.f("Cannot sort filtered list"))},"call$1","gH7",0,2,null,77,128],
-YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on filtered list"))},"call$4","gam",6,2,null,336,115,116,109,117],
-UZ:[function(a,b,c){H.bQ(C.Nm.D6(this.gzT(),b,c),new P.GS())},"call$2","gYH",4,0,null,115,116],
+return b.parentNode===this.F1},"call$1","gdj",2,0,null,102,[]],
+GT:[function(a,b){throw H.b(P.f("Cannot sort filtered list"))},"call$1","gH7",0,2,null,77,128,[]],
+YW:[function(a,b,c,d,e){throw H.b(P.f("Cannot setRange on filtered list"))},"call$4","gam",6,2,null,330,115,[],116,[],109,[],117,[]],
+UZ:[function(a,b,c){H.bQ(C.Nm.D6(this.gzT(),b,c),new P.GS())},"call$2","gYH",4,0,null,115,[],116,[]],
 V1:[function(a){this.h2.NL.textContent=""},"call$0","gyP",0,0,null],
+xe:[function(a,b,c){this.h2.xe(0,b,c)},"call$2","gQG",4,0,null,47,[],23,[]],
+KI:[function(a,b){var z,y
+z=this.gzT()
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+J.QC(y)
+return y},"call$1","gNM",2,0,null,47,[]],
 Rz:[function(a,b){var z,y,x
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$iscv)return!1
@@ -17843,50 +18132,77 @@
 if(y>=z.length)return H.e(z,y)
 x=z[y]
 if(x==null?b==null:x===b){J.QC(x)
-return!0}}return!1},"call$1","gRI",2,0,null,124],
+return!0}}return!1},"call$1","gRI",2,0,null,124,[]],
 gB:function(a){return this.gzT().length},
 t:[function(a,b){var z=this.gzT()
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,null,47],
+return z[b]},"call$1","gIA",2,0,null,47,[]],
 gA:function(a){var z=this.gzT()
 return H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])}},
 hT:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,292,"call"],
+return typeof a==="object"&&a!==null&&!!z.$iscv},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 GS:{
-"":"Tp:229;",
-call$1:[function(a){return J.QC(a)},"call$1",null,2,0,null,288,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.QC(a)},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true}}],["instance_ref_element","package:observatory/src/observatory_elements/instance_ref.dart",,B,{
-"":"",
+"^":"",
 pR:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["T5;qX%-355,AP,fn,tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+goE:[function(a){return a.qX},null,null,1,0,366,"expanded",351,352],
+soE:[function(a,b){a.qX=this.ct(a,C.mr,a.qX,b)},null,null,3,0,367,23,[],"expanded",351],
 goc:[function(a){var z=a.tY
 if(z==null)return Q.xI.prototype.goc.call(this,a)
-return J.UQ(z,"preview")},null,null,1,0,369,"name"],
+return J.UQ(z,"preview")},null,null,1,0,362,"name"],
+AZ:[function(a,b,c,d){if(a.qX===!0){J.kW(a.tY,"fields",null)
+J.kW(a.tY,"elements",null)
+a.qX=this.ct(a,C.mr,a.qX,!1)}else a.hm.gDF().fB(this.gO3(a)).ml(new B.YE(a)).OA(new B.we())},"call$3","ghM",6,0,470,123,[],180,[],278,[],"toggleExpand"],
 "@":function(){return[C.VW]},
-static:{lu:[function(a){var z,y,x,w
+static:{b4:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
+a.qX=!1
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.cp.ZL(a)
-C.cp.oX(a)
-return a},null,null,0,0,108,"new InstanceRefElement$created" /* new InstanceRefElement$created:0:0 */]}},
-"+InstanceRefElement":[364]}],["instance_view_element","package:observatory/src/observatory_elements/instance_view.dart",,Z,{
-"":"",
+C.cp.G6(a)
+return a},null,null,0,0,108,"new InstanceRefElement$created"]}},
+"+InstanceRefElement":[471],
+T5:{
+"^":"xI+Pi;",
+$isd3:true},
+YE:{
+"^":"Tp:223;a-77",
+call$1:[function(a){var z,y,x
+z=this.a
+y=J.RE(z)
+x=J.U6(a)
+J.kW(y.gtY(z),"fields",x.t(a,"fields"))
+J.kW(y.gtY(z),"elements",x.t(a,"elements"))
+J.kW(y.gtY(z),"length",x.t(a,"length"))
+y.sqX(z,y.ct(z,C.mr,y.gqX(z),!0))},"call$1",null,2,0,223,144,[],"call"],
+$isEH:true},
+"+InstanceRefElement_toggleExpand_closure":[467],
+we:{
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while expanding instance-ref: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,341,18,[],472,[],"call"],
+$isEH:true},
+"+InstanceRefElement_toggleExpand_closure":[467]}],["instance_view_element","package:observatory/src/observatory_elements/instance_view.dart",,Z,{
+"^":"",
 hx:{
-"":["cda;Xh%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gQr:[function(a){return a.Xh},null,null,1,0,358,"instance",359,360],
-sQr:[function(a,b){a.Xh=this.ct(a,C.fn,a.Xh,b)},null,null,3,0,361,23,"instance",359],
+"^":["cda;Xh%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gQr:[function(a){return a.Xh},null,null,1,0,350,"instance",351,352],
+sQr:[function(a,b){a.Xh=this.ct(a,C.fn,a.Xh,b)},null,null,3,0,353,23,[],"instance",351],
 "@":function(){return[C.be]},
-static:{Co:[function(a){var z,y,x,w
+static:{HC:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
@@ -17894,19 +18210,19 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.yK.ZL(a)
-C.yK.oX(a)
-return a},null,null,0,0,108,"new InstanceViewElement$created" /* new InstanceViewElement$created:0:0 */]}},
-"+InstanceViewElement":[474],
+C.yK.G6(a)
+return a},null,null,0,0,108,"new InstanceViewElement$created"]}},
+"+InstanceViewElement":[473],
 cda:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["isolate_list_element","package:observatory/src/observatory_elements/isolate_list.dart",,L,{
-"":"",
+"^":"",
 u7:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-Ak:[function(a,b,c,d){J.kH(a.hm.gnI().gi2(),new L.fW())},"call$3","gBq",6,0,376,18,307,74,"refresh"],
-"@":function(){return[C.jF]},
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+Ak:[function(a,b,c,d){J.kH(a.hm.gnI().gi2(),new L.fW())},"call$3","gBq",6,0,369,18,[],301,[],74,[],"refresh"],
+"@":function(){return[C.jFV]},
 static:{Cu:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -17915,109 +18231,145 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.b9.ZL(a)
-C.b9.oX(a)
-return a},null,null,0,0,108,"new IsolateListElement$created" /* new IsolateListElement$created:0:0 */]}},
-"+IsolateListElement":[475],
+C.b9.G6(a)
+return a},null,null,0,0,108,"new IsolateListElement$created"]}},
+"+IsolateListElement":[474],
 fW:{
-"":"Tp:349;",
-call$2:[function(a,b){J.KM(b)},"call$2",null,4,0,349,241,14,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){J.KM(b)},"call$2",null,4,0,341,236,[],14,[],"call"],
 $isEH:true},
-"+IsolateListElement_refresh_closure":[471]}],["isolate_profile_element","package:observatory/src/observatory_elements/isolate_profile.dart",,X,{
-"":"",
+"+IsolateListElement_refresh_closure":[467]}],["isolate_profile_element","package:observatory/src/observatory_elements/isolate_profile.dart",,X,{
+"^":"",
+qm:{
+"^":["Y2;Aq>,tT>-359,eT,yt-475,wd-476,oH-477,np,AP,fn",null,function(){return[C.mI]},null,function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null],
+C4:[function(a){if(J.z8(J.q8(this.wd),0))return
+H.bQ(this.tT.gVS(),new X.vO(this))},"call$0","gz7",0,0,null],
+o8:[function(){return},"call$0","gDT",0,0,null],
+Af:function(a,b,c){var z,y,x,w,v,u
+z=this.oH
+y=this.tT
+x=this.Aq
+w=J.RE(x)
+v=J.w1(z)
+v.h(z,X.eI(y.gDu(),w.gB1(x).ghV()))
+if(c==null)v.h(z,"")
+else{u=c.tT
+v.h(z,X.eI(u.dJ(y),u.QQ()))}v.h(z,X.eI(y.gfF(),w.gB1(x).ghV()))},
+static:{eI:[function(a,b){return C.CD.yM(100*J.FW(a,b),2)+"%"},"call$2","rC",4,0,null,123,[],234,[]],Tl:function(a,b,c){var z,y
+z=H.VM([],[L.Y2])
+y=c!=null?J.WB(c.yt,1):0
+z=new X.qm(a,b,c,y,z,[],!1,null,null)
+z.Af(a,b,c)
+return z}}},
+vO:{
+"^":"Tp:479;a",
+call$1:[function(a){var z=this.a
+J.bi(z.wd,X.Tl(z.Aq,J.on(a),z))},"call$1",null,2,0,null,478,[],"call"],
+$isEH:true},
 E7:{
-"":["waa;BA%-476,fb=-477,iZ%-477,qY%-477,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gXc:[function(a){return a.BA},null,null,1,0,478,"methodCountSelected",359,372],
-sXc:[function(a,b){a.BA=this.ct(a,C.fQ,a.BA,b)},null,null,3,0,390,23,"methodCountSelected",359],
-gtK:[function(a){return a.iZ},null,null,1,0,479,"topInclusiveCodes",359,372],
-stK:[function(a,b){a.iZ=this.ct(a,C.Yn,a.iZ,b)},null,null,3,0,480,23,"topInclusiveCodes",359],
-gHu:[function(a){return a.qY},null,null,1,0,479,"topExclusiveCodes",359,372],
-sHu:[function(a,b){a.qY=this.ct(a,C.jI,a.qY,b)},null,null,3,0,480,23,"topExclusiveCodes",359],
-i4:[function(a){var z,y
+"^":["waa;BA%-475,fb=-480,qY%-480,qO=-77,Hm%-481,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gXc:[function(a){return a.BA},null,null,1,0,482,"methodCountSelected",351,365],
+sXc:[function(a,b){a.BA=this.ct(a,C.fQ,a.BA,b)},null,null,3,0,385,23,[],"methodCountSelected",351],
+gHu:[function(a){return a.qY},null,null,1,0,483,"topExclusiveCodes",351,365],
+sHu:[function(a,b){a.qY=this.ct(a,C.jI,a.qY,b)},null,null,3,0,484,23,[],"topExclusiveCodes",351],
+i4:[function(a){var z,y,x,w
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null)return
-this.oC(a,y)},"call$0","gQd",0,0,107,"enteredView"],
+x=[]
+w=R.Jk([])
+C.Nm.FV(x,["Method","Exclusive","Caller","Inclusive"])
+a.Hm=new L.XN(x,w,null,null)
+this.oC(a,y)
+this.f9(a,y)},"call$0","gQd",0,0,107,"enteredView"],
 yG:[function(a){},"call$0","gCn",0,0,107,"_startRequest"],
 M8:[function(a){},"call$0","gjt",0,0,107,"_endRequest"],
 wW:[function(a,b){var z,y
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null)return
-this.oC(a,y)},"call$1","ghj",2,0,229,231,"methodCountSelectedChanged"],
+this.oC(a,y)
+this.f9(a,y)},"call$1","ghj",2,0,223,225,[],"methodCountSelectedChanged"],
 Ub:[function(a,b,c,d){var z,y,x
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null){N.Jx("").To("No isolate found.")
 return}x="/"+z+"/profile"
-a.hm.glw().fB(x).ml(new X.RR(a,y)).OA(new X.EL(a))},"call$3","gFz",6,0,376,18,307,74,"refreshData"],
+a.hm.gDF().fB(x).ml(new X.RR(a,y)).OA(new X.EL(a))},"call$3","gFz",6,0,369,18,[],301,[],74,[],"refreshData"],
 IW:[function(a,b,c,d){J.CJ(b,L.hh(b,d))
-this.oC(a,b)},"call$3","gja",6,0,481,14,482,470,"_loadProfileData"],
-oC:[function(a,b){var z,y,x,w
+this.oC(a,b)
+this.f9(a,b)},"call$3","gja",6,0,485,14,[],486,[],466,[],"_loadProfileData"],
+yF:[function(a,b){this.oC(a,b)
+this.f9(a,b)},"call$1","gAL",2,0,487,14,[],"_refresh"],
+f9:[function(a,b){var z,y
+z=[]
+for(y=J.GP(a.qY);y.G();)z.push(X.Tl(b,y.gl(),null))
+a.Hm.rT(z)
+this.ct(a,C.ep,null,a.Hm)},"call$1","gCK",2,0,487,14,[],"_refreshTree"],
+oC:[function(a,b){var z,y
 J.U2(a.qY)
-J.U2(a.iZ)
 if(b==null||J.Tv(b)==null)return
 z=J.UQ(a.fb,a.BA)
-y=J.RE(b)
-x=y.gB1(b).T0(z)
-J.bj(a.qY,x)
-w=y.gB1(b).hg(z)
-J.bj(a.iZ,w)},"call$1","guE",2,0,483,14,"_refreshTopMethods"],
-nN:[function(a,b,c){if(b==null)return""
-return c===!0?H.d(b.gfF()):H.d(b.gDu())},"call$2","gRb",4,0,484,136,485,"codeTicks"],
-n8:[function(a,b,c){var z,y,x
-if(b==null)return""
-z=a.hm.gZ6().R6()
-y=a.hm.gnI().AQ(z)
-if(y==null)return""
-x=c===!0?b.gfF():b.gDu()
-return C.CD.yM(J.FW(x,J.Tv(y).ghV())*100,2)},"call$2","gCP",4,0,484,136,485,"codePercent"],
-uq:[function(a,b){if(b==null||J.O6(b)==null)return""
-return J.O6(b)},"call$1","gcW",2,0,486,136,"codeName"],
-"@":function(){return[C.bp]},
-static:{jD:[function(a){var z,y,x,w,v,u
+y=J.Tv(b).T0(z)
+J.bj(a.qY,y)},"call$1","guE",2,0,487,14,[],"_refreshTopMethods"],
+ka:[function(a,b){return"padding-left: "+H.d(J.p0(b.gyt(),16))+"px;"},"call$1","gGX",2,0,488,489,[],"padding",365],
+LZ:[function(a,b){var z=J.bY(b.gyt(),5)
+if(z>>>0!==z||z>=5)return H.e(C.PQ,z)
+return C.PQ[z]},"call$1","gth",2,0,488,489,[],"coloring",365],
+YF:[function(a,b,c,d){var z,y,x
+z=J.u3(d)
+y=J.x(z)
+if(typeof z==="object"&&z!==null&&!!y.$istV){y=a.Hm
+x=z.rowIndex
+if(typeof x!=="number")return x.W()
+y.qU(x-1)}},"call$3","gpR",6,0,490,18,[],301,[],74,[],"toggleExpanded",365],
+"@":function(){return[C.jR]},
+static:{jD:[function(a){var z,y,x,w,v
 z=R.Jk([])
-y=R.Jk([])
-x=$.Nd()
-w=P.Py(null,null,null,J.O,W.I0)
-v=J.O
-u=W.cv
-u=H.VM(new V.qC(P.Py(null,null,null,v,u),null,null),[v,u])
+y=$.Nd()
+x=P.Py(null,null,null,J.O,W.I0)
+w=J.O
+v=W.cv
+v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
 a.BA=0
 a.fb=[10,20,50]
-a.iZ=z
-a.qY=y
-a.SO=x
-a.B7=w
-a.ZQ=u
+a.qY=z
+a.qO="#tableTree"
+a.SO=y
+a.B7=x
+a.X0=v
 C.XH.ZL(a)
-C.XH.oX(a)
-return a},null,null,0,0,108,"new IsolateProfileElement$created" /* new IsolateProfileElement$created:0:0 */]}},
-"+IsolateProfileElement":[487],
+C.XH.G6(a)
+return a},null,null,0,0,108,"new IsolateProfileElement$created"]}},
+"+IsolateProfileElement":[491],
 waa:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true},
 RR:{
-"":"Tp:361;a-77,b-77",
-call$1:[function(a){var z,y
+"^":"Tp:353;a-77,b-77",
+call$1:[function(a){var z,y,x,w
 z=J.UQ(a,"samples")
 N.Jx("").To("Profile contains "+H.d(z)+" samples.")
-y=this.b
-J.CJ(y,L.hh(y,a))
-J.fo(this.a,y)},"call$1",null,2,0,361,488,"call"],
+y=this.a
+x=this.b
+J.CJ(x,L.hh(x,a))
+w=J.RE(y)
+w.oC(y,x)
+w.f9(y,x)},"call$1",null,2,0,353,492,[],"call"],
 $isEH:true},
-"+IsolateProfileElement_refreshData_closure":[471],
+"+IsolateProfileElement_refreshData_closure":[467],
 EL:{
-"":"Tp:229;c-77",
-call$1:[function(a){},"call$1",null,2,0,229,18,"call"],
+"^":"Tp:223;c-77",
+call$1:[function(a){},"call$1",null,2,0,223,18,[],"call"],
 $isEH:true},
-"+IsolateProfileElement_refreshData_closure":[471]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{
-"":"",
+"+IsolateProfileElement_refreshData_closure":[467]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{
+"^":"",
 St:{
-"":["V0;Pw%-489,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gAq:[function(a){return a.Pw},null,null,1,0,490,"isolate",359,360],
-sAq:[function(a,b){a.Pw=this.ct(a,C.Y2,a.Pw,b)},null,null,3,0,491,23,"isolate",359],
+"^":["V0;Pw%-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gAq:[function(a){return a.Pw},null,null,1,0,493,"isolate",351,352],
+sAq:[function(a,b){a.Pw=this.ct(a,C.Z8,a.Pw,b)},null,null,3,0,494,23,[],"isolate",351],
 "@":function(){return[C.aM]},
 static:{JR:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18027,43 +18379,43 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.nM.ZL(a)
-C.nM.oX(a)
-return a},null,null,0,0,108,"new IsolateSummaryElement$created" /* new IsolateSummaryElement$created:0:0 */]}},
-"+IsolateSummaryElement":[492],
+a.X0=w
+C.Qt.ZL(a)
+C.Qt.G6(a)
+return a},null,null,0,0,108,"new IsolateSummaryElement$created"]}},
+"+IsolateSummaryElement":[495],
 V0:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["json_view_element","package:observatory/src/observatory_elements/json_view.dart",,Z,{
-"":"",
+"^":"",
 vj:{
-"":["V4;eb%-77,kf%-77,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gvL:[function(a){return a.eb},null,null,1,0,108,"json",359,360],
-svL:[function(a,b){a.eb=this.ct(a,C.Gd,a.eb,b)},null,null,3,0,229,23,"json",359],
+"^":["V4;eb%-77,kf%-77,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gvL:[function(a){return a.eb},null,null,1,0,108,"json",351,352],
+svL:[function(a,b){a.eb=this.ct(a,C.Gd,a.eb,b)},null,null,3,0,223,23,[],"json",351],
 i4:[function(a){Z.uL.prototype.i4.call(this,a)
 a.kf=0},"call$0","gQd",0,0,107,"enteredView"],
-yC:[function(a,b){this.ct(a,C.eR,"a","b")},"call$1","gHl",2,0,152,231,"jsonChanged"],
-gW0:[function(a){return J.AG(a.eb)},null,null,1,0,369,"primitiveString"],
+yC:[function(a,b){this.ct(a,C.eR,"a","b")},"call$1","gHl",2,0,150,225,[],"jsonChanged"],
+gW0:[function(a){return J.AG(a.eb)},null,null,1,0,362,"primitiveString"],
 gmm:[function(a){var z,y
 z=a.eb
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)return"Map"
 else if(typeof z==="object"&&z!==null&&(z.constructor===Array||!!y.$isList))return"List"
-return"Primitive"},null,null,1,0,369,"valueType"],
+return"Primitive"},null,null,1,0,362,"valueType"],
 gkG:[function(a){var z=a.kf
 a.kf=J.WB(z,1)
-return z},null,null,1,0,478,"counter"],
+return z},null,null,1,0,482,"counter"],
 gaK:[function(a){var z,y
 z=a.eb
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&(z.constructor===Array||!!y.$isList))return z
-return[]},null,null,1,0,479,"list"],
+return[]},null,null,1,0,483,"list"],
 gvc:[function(a){var z,y
 z=a.eb
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)return J.qA(y.gvc(z))
-return[]},null,null,1,0,479,"keys"],
-r6:[function(a,b){return J.UQ(a.eb,b)},"call$1","gP",2,0,25,42,"value"],
+return[]},null,null,1,0,483,"keys"],
+r6:[function(a,b){return J.UQ(a.eb,b)},"call$1","gP",2,0,25,42,[],"value"],
 "@":function(){return[C.KH]},
 static:{mA:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18075,18 +18427,18 @@
 a.kf=0
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.GB.ZL(a)
-C.GB.oX(a)
-return a},null,null,0,0,108,"new JsonViewElement$created" /* new JsonViewElement$created:0:0 */]}},
-"+JsonViewElement":[493],
+C.GB.G6(a)
+return a},null,null,0,0,108,"new JsonViewElement$created"]}},
+"+JsonViewElement":[496],
 V4:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["library_ref_element","package:observatory/src/observatory_elements/library_ref.dart",,R,{
-"":"",
+"^":"",
 LU:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-"@":function(){return[C.uy]},
+"^":["xI;tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"@":function(){return[C.QU]},
 static:{rA:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -18094,19 +18446,20 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Z3.ZL(a)
-C.Z3.oX(a)
-return a},null,null,0,0,108,"new LibraryRefElement$created" /* new LibraryRefElement$created:0:0 */]}},
-"+LibraryRefElement":[364]}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{
-"":"",
-CX:{
-"":["V6;N7%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtD:[function(a){return a.N7},null,null,1,0,358,"library",359,360],
-stD:[function(a,b){a.N7=this.ct(a,C.EV,a.N7,b)},null,null,3,0,361,23,"library",359],
-"@":function(){return[C.Ob]},
+C.Z3.G6(a)
+return a},null,null,0,0,108,"new LibraryRefElement$created"]}},
+"+LibraryRefElement":[357]}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{
+"^":"",
+T2:{
+"^":["V10;N7%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtD:[function(a){return a.N7},null,null,1,0,350,"library",351,352],
+stD:[function(a,b){a.N7=this.ct(a,C.EV,a.N7,b)},null,null,3,0,353,23,[],"library",351],
+"@":function(){return[C.Gg]},
 static:{SP:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -18118,17 +18471,17 @@
 a.N7=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.MG.ZL(a)
-C.MG.oX(a)
-return a},null,null,0,0,108,"new LibraryViewElement$created" /* new LibraryViewElement$created:0:0 */]}},
-"+LibraryViewElement":[494],
-V6:{
-"":"uL+Pi;",
+C.MG.G6(a)
+return a},null,null,0,0,108,"new LibraryViewElement$created"]}},
+"+LibraryViewElement":[497],
+V10:{
+"^":"uL+Pi;",
 $isd3:true}}],["logging","package:logging/logging.dart",,N,{
-"":"",
+"^":"",
 TJ:{
-"":"a;oc>,eT>,n2,Cj>,wd>,Gs",
+"^":"a;oc>,eT>,n2,Cj>,wd>,Gs",
 gB8:function(){var z,y,x
 z=this.eT
 y=z==null||J.de(J.O6(z),"")
@@ -18142,7 +18495,7 @@
 else{if(this.eT!=null)throw H.b(P.f("Please set \"hierarchicalLoggingEnabled\" to true if you want to change the level on a non-root logger."))
 $.Y4=a}},
 gSZ:function(){return this.IE()},
-mL:[function(a){return a.P>=this.gOR().P},"call$1","goT",2,0,null,23],
+Im:[function(a){return a.P>=this.gOR().P},"call$1","goT",2,0,null,23,[]],
 Y6:[function(a,b,c,d){var z,y,x,w,v
 if(a.P>=this.gOR().P){z=this.gB8()
 y=new P.iP(Date.now(),!1)
@@ -18152,25 +18505,25 @@
 w=new N.HV(a,b,z,y,x,c,d)
 if($.RL)for(v=this;v!=null;){z=J.RE(v)
 z.od(v,w)
-v=z.geT(v)}else J.EY(N.Jx(""),w)}},"call$4","gA9",4,4,null,77,77,495,20,146,147],
-X2:[function(a,b,c){return this.Y6(C.Ab,a,b,c)},function(a){return this.X2(a,null,null)},"x9","call$3",null,"git",2,4,null,77,77,20,146,147],
-yl:[function(a,b,c){return this.Y6(C.R5,a,b,c)},function(a){return this.yl(a,null,null)},"J4","call$3",null,"gjW",2,4,null,77,77,20,146,147],
-ZG:[function(a,b,c){return this.Y6(C.IF,a,b,c)},function(a){return this.ZG(a,null,null)},"To","call$3",null,"gqa",2,4,null,77,77,20,146,147],
-xH:[function(a,b,c){return this.Y6(C.UP,a,b,c)},function(a){return this.xH(a,null,null)},"j2","call$3",null,"goa",2,4,null,77,77,20,146,147],
-WB:[function(a,b,c){return this.Y6(C.xl,a,b,c)},function(a){return this.WB(a,null,null)},"hh","call$3",null,"gxx",2,4,null,77,77,20,146,147],
+v=z.geT(v)}else J.EY(N.Jx(""),w)}},"call$4","gA9",4,4,null,77,77,498,[],20,[],152,[],153,[]],
+X2:[function(a,b,c){return this.Y6(C.Ab,a,b,c)},function(a){return this.X2(a,null,null)},"x9","call$3",null,"git",2,4,null,77,77,20,[],152,[],153,[]],
+yl:[function(a,b,c){return this.Y6(C.R5,a,b,c)},function(a){return this.yl(a,null,null)},"J4","call$3",null,"gjW",2,4,null,77,77,20,[],152,[],153,[]],
+ZG:[function(a,b,c){return this.Y6(C.IF,a,b,c)},function(a){return this.ZG(a,null,null)},"To","call$3",null,"gqa",2,4,null,77,77,20,[],152,[],153,[]],
+xH:[function(a,b,c){return this.Y6(C.UP,a,b,c)},function(a){return this.xH(a,null,null)},"j2","call$3",null,"goa",2,4,null,77,77,20,[],152,[],153,[]],
+WB:[function(a,b,c){return this.Y6(C.cV,a,b,c)},function(a){return this.WB(a,null,null)},"hh","call$3",null,"gxx",2,4,null,77,77,20,[],152,[],153,[]],
 IE:[function(){if($.RL||this.eT==null){var z=this.Gs
 if(z==null){z=P.bK(null,null,!0,N.HV)
 this.Gs=z}z.toString
-return H.VM(new P.Ik(z),[H.Kp(z,0)])}else return N.Jx("").IE()},"call$0","gOp",0,0,null],
+return H.VM(new P.Ik(z),[H.Kp(z,0)])}else return N.Jx("").IE()},"call$0","gnc",0,0,null],
 od:[function(a,b){var z=this.Gs
 if(z!=null){if(z.Gv>=4)H.vh(z.q7())
-z.Iv(b)}},"call$1","gHh",2,0,null,22],
+z.Iv(b)}},"call$1","gHh",2,0,null,22,[]],
 QL:function(a,b,c){var z=this.eT
 if(z!=null)J.Tr(z).u(0,this.oc,this)},
 $isTJ:true,
-static:{"":"DY",Jx:function(a){return $.U0().to(a,new N.dG(a))}}},
+static:{"^":"DY",Jx:function(a){return $.U0().to(a,new N.dG(a))}}},
 dG:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){var z,y,x,w,v
 z=this.a
 if(C.xB.nC(z,"."))H.vh(new P.AT("name shouldn't start with a '.'"))
@@ -18178,72 +18531,72 @@
 if(y===-1)x=z!==""?N.Jx(""):null
 else{x=N.Jx(C.xB.Nj(z,0,y))
 z=C.xB.yn(z,y+1)}w=P.L5(null,null,null,J.O,N.TJ)
-v=new N.TJ(z,x,null,w,H.VM(new Q.A2(w),[null,null]),null)
+v=new N.TJ(z,x,null,w,H.VM(new Q.Gj(w),[null,null]),null)
 v.QL(z,x,w)
 return v},"call$0",null,0,0,null,"call"],
 $isEH:true},
 qV:{
-"":"a;oc>,P>",
+"^":"a;oc>,P>",
 r6:function(a,b){return this.P.call$1(b)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isqV&&this.P===b.P},"call$1","gUJ",2,0,null,104],
+return typeof b==="object"&&b!==null&&!!z.$isqV&&this.P===b.P},"call$1","gUJ",2,0,null,104,[]],
 C:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P<z},"call$1","gix",2,0,null,104],
+return this.P<z},"call$1","gix",2,0,null,104,[]],
 E:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P<=z},"call$1","gf5",2,0,null,104],
+return this.P<=z},"call$1","gf5",2,0,null,104,[]],
 D:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P>z},"call$1","gh1",2,0,null,104],
+return this.P>z},"call$1","gh1",2,0,null,104,[]],
 F:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P>=z},"call$1","gNH",2,0,null,104],
+return this.P>=z},"call$1","gNH",2,0,null,104,[]],
 iM:[function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")return H.s(z)
-return this.P-z},"call$1","gYc",2,0,null,104],
+return this.P-z},"call$1","gYc",2,0,null,104,[]],
 giO:function(a){return this.P},
 bu:[function(a){return this.oc},"call$0","gXo",0,0,null],
 $isqV:true,
-static:{"":"V7K,tmj,Enk,LkO,reI,pd,Eb,AN,JY,lDu,B9"}},
+static:{"^":"V7K,tmj,Enk,us,reI,pd,Wr,AN,JY,lM,B9"}},
 HV:{
-"":"a;OR<,G1>,iJ,Fl<,O0,kc>,I4<",
+"^":"a;OR<,G1>,iJ,Fl<,O0,kc>,I4<",
 bu:[function(a){return"["+this.OR.oc+"] "+this.iJ+": "+this.G1},"call$0","gXo",0,0,null],
 $isHV:true,
-static:{"":"xO"}}}],["","main.dart",,F,{
-"":"",
+static:{"^":"xO"}}}],["","main.dart",,F,{
+"^":"",
 E2:[function(){N.Jx("").sOR(C.IF)
 N.Jx("").gSZ().yI(new F.em())
 N.Jx("").To("Starting Observatory")
 var z=H.VM(new P.Zf(P.Dt(null)),[null])
 N.Jx("").To("Loading Google Charts API")
 J.UQ($.cM(),"google").V7("load",["visualization","1",P.jT(H.B7(["packages",["corechart","table"],"callback",new P.r7(P.xZ(z.gv6(z),!0))],P.L5(null,null,null,null,null)))])
-z.MM.ml(L.vN()).ml(new F.Lb())},"call$0","lS",0,0,null],
+z.MM.ml(L.vN()).ml(new F.Lb())},"call$0","qg",0,0,null],
 em:{
-"":"Tp:497;",
-call$1:[function(a){P.JS(a.gOR().oc+": "+H.d(a.gFl())+": "+H.d(J.yj(a)))},"call$1",null,2,0,null,496,"call"],
+"^":"Tp:500;",
+call$1:[function(a){P.JS(a.gOR().oc+": "+H.d(a.gFl())+": "+H.d(J.yj(a)))},"call$1",null,2,0,null,499,[],"call"],
 $isEH:true},
 Lb:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){N.Jx("").To("Initializing Polymer")
-A.Ok()},"call$1",null,2,0,null,240,"call"],
+A.Ok()},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true}}],["message_viewer_element","package:observatory/src/observatory_elements/message_viewer.dart",,L,{
-"":"",
+"^":"",
 PF:{
-"":["uL;Gj%-355,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gG1:[function(a){return a.Gj},null,null,1,0,358,"message",360],
+"^":["uL;Gj%-347,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gG1:[function(a){return a.Gj},null,null,1,0,350,"message",352],
 sG1:[function(a,b){a.Gj=b
 this.ct(a,C.US,"",this.gQW(a))
-this.ct(a,C.wt,[],this.glc(a))
-N.Jx("").To("Viewing message of type '"+H.d(J.UQ(a.Gj,"type"))+"'")},null,null,3,0,361,183,"message",360],
+this.ct(a,C.zu,[],this.glc(a))
+N.Jx("").To("Viewing message of type '"+H.d(J.UQ(a.Gj,"type"))+"'")},null,null,3,0,353,183,[],"message",352],
 gQW:[function(a){var z=a.Gj
 if(z==null||J.UQ(z,"type")==null)return"Error"
-return J.UQ(a.Gj,"type")},null,null,1,0,369,"messageType"],
+return J.UQ(a.Gj,"type")},null,null,1,0,362,"messageType"],
 glc:[function(a){var z=a.Gj
 if(z==null||J.UQ(z,"members")==null)return[]
-return J.UQ(a.Gj,"members")},null,null,1,0,498,"members"],
+return J.UQ(a.Gj,"members")},null,null,1,0,501,"members"],
 "@":function(){return[C.rc]},
 static:{A5:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18253,26 +18606,26 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Wp.ZL(a)
-C.Wp.oX(a)
-return a},null,null,0,0,108,"new MessageViewerElement$created" /* new MessageViewerElement$created:0:0 */]}},
-"+MessageViewerElement":[475]}],["metadata","../../../../../../../../../dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{
-"":"",
+C.Wp.G6(a)
+return a},null,null,0,0,108,"new MessageViewerElement$created"]}},
+"+MessageViewerElement":[474]}],["metadata","../../../../../../../../../dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{
+"^":"",
 fA:{
-"":"a;T9,Jt",
-static:{"":"Ze,en,pjg,PZ,xa"}},
+"^":"a;T9,Jt",
+static:{"^":"n4I,en,pjg,PZ,xa"}},
 tz:{
-"":"a;"},
+"^":"a;"},
 jA:{
-"":"a;oc>"},
-Jo:{
-"":"a;"},
+"^":"a;oc>"},
+PO:{
+"^":"a;"},
 c5:{
-"":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{
-"":"",
+"^":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{
+"^":"",
 qT:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.KG]},
 static:{BW:[function(a){var z,y,x,w
 z=$.Nd()
@@ -18282,30 +18635,30 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Xg.ZL(a)
-C.Xg.oX(a)
-return a},null,null,0,0,108,"new NavigationBarElement$created" /* new NavigationBarElement$created:0:0 */]}},
-"+NavigationBarElement":[475]}],["navigation_bar_isolate_element","package:observatory/src/observatory_elements/navigation_bar_isolate.dart",,F,{
-"":"",
+C.Xg.G6(a)
+return a},null,null,0,0,108,"new NavigationBarElement$created"]}},
+"+NavigationBarElement":[474]}],["navigation_bar_isolate_element","package:observatory/src/observatory_elements/navigation_bar_isolate.dart",,F,{
+"^":"",
 Xd:{
-"":["V10;rK%-499,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gNa:[function(a){return a.rK},null,null,1,0,500,"links",359,372],
-sNa:[function(a,b){a.rK=this.ct(a,C.AX,a.rK,b)},null,null,3,0,501,23,"links",359],
+"^":["V11;rK%-477,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNa:[function(a){return a.rK},null,null,1,0,502,"links",351,365],
+sNa:[function(a,b){a.rK=this.ct(a,C.AX,a.rK,b)},null,null,3,0,503,23,[],"links",351],
 Pz:[function(a,b){Z.uL.prototype.Pz.call(this,a,b)
-this.ct(a,C.T7,"",this.gMm(a))},"call$1","gpx",2,0,152,231,"appChanged"],
-lJ:[function(a){var z,y
+this.ct(a,C.T7,"",this.gMm(a))},"call$1","gpx",2,0,150,225,[],"appChanged"],
+Zc:[function(a){var z,y
 z=a.hm
 if(z==null)return""
 y=z.gZ6().Pr()
 if(y==null)return""
-return J.O6(y)},"call$0","gMm",0,0,369,"currentIsolateName"],
-KdI:[function(a,b){var z=a.hm
+return J.O6(y)},"call$0","gMm",0,0,362,"currentIsolateName"],
+Ta:[function(a,b){var z=a.hm
 if(z==null)return""
 switch(b){case"Stacktrace":return z.gZ6().kP("stacktrace")
 case"Library":return z.gZ6().kP("library")
 case"CPU Profile":return z.gZ6().kP("profile")
-default:return z.gZ6().kP("")}},"call$1","gz7",2,0,206,502,"currentIsolateLink"],
+default:return z.gZ6().kP("")}},"call$1","gcD",2,0,504,505,[],"currentIsolateLink"],
 "@":function(){return[C.AR]},
 static:{L1:[function(a){var z,y,x,w,v
 z=R.Jk(["Stacktrace","Library","CPU Profile"])
@@ -18317,21 +18670,21 @@
 a.rK=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.Vn.ZL(a)
-C.Vn.oX(a)
-return a},null,null,0,0,108,"new NavigationBarIsolateElement$created" /* new NavigationBarIsolateElement$created:0:0 */]}},
-"+NavigationBarIsolateElement":[503],
-V10:{
-"":"uL+Pi;",
+C.Vn.G6(a)
+return a},null,null,0,0,108,"new NavigationBarIsolateElement$created"]}},
+"+NavigationBarIsolateElement":[506],
+V11:{
+"^":"uL+Pi;",
 $isd3:true}}],["observatory","package:observatory/observatory.dart",,L,{
-"":"",
+"^":"",
 m7:[function(a){var z
 N.Jx("").To("Google Charts API loaded")
 z=J.UQ(J.UQ($.cM(),"google"),"visualization")
 $.NR=z
-return z},"call$1","vN",2,0,229,240],
-TK:[function(a){var z,y,x,w,v,u
+return z},"call$1","vN",2,0,223,235,[]],
+CX:[function(a){var z,y,x,w,v,u
 z=$.mE().R4(0,a)
 if(z==null)return 0
 try{x=z.gQK().input
@@ -18343,7 +18696,7 @@
 if(typeof w!=="number")return H.s(w)
 y=H.BU(C.xB.yn(x,v+w),16,null)
 return y}catch(u){H.Ru(u)
-return 0}},"call$1","Yh",2,0,null,218],
+return 0}},"call$1","Cz",2,0,null,212,[]],
 r5:[function(a){var z,y,x,w,v
 z=$.kj().R4(0,a)
 if(z==null)return
@@ -18354,10 +18707,10 @@
 if(0>=y.length)return H.e(y,0)
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
-return C.xB.Nj(x,w,v+y)},"call$1","cK",2,0,null,218],
+return C.xB.Nj(x,w,v+y)},"call$1","cK",2,0,null,212,[]],
 Lw:[function(a){var z=L.r5(a)
 if(z==null)return
-return J.ZZ(z,1)},"call$1","J4",2,0,null,218],
+return J.ZZ(z,1)},"call$1","J4",2,0,null,212,[]],
 CB:[function(a){var z,y,x,w
 z=$.XJ().R4(0,a)
 if(z==null)return
@@ -18367,58 +18720,60 @@
 if(0>=y.length)return H.e(y,0)
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
-return C.xB.yn(x,w+y)},"call$1","jU",2,0,null,218],
+return C.xB.yn(x,w+y)},"call$1","jU",2,0,null,212,[]],
 mL:{
-"":["Pi;Z6<-504,lw<-505,nI<-506,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null],
+"^":["Pi;Z6<-507,DF<-508,nI<-509,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null],
 pO:[function(){var z,y,x
 z=this.Z6
 z.sXT(this)
-y=this.lw
+y=this.DF
 y.sXT(this)
 x=this.nI
 x.sXT(this)
 $.tE=this
 y.se0(x.gPI())
 z.kI()},"call$0","gGo",0,0,null],
-AQ:[function(a){return J.UQ(this.nI.gi2(),a)},"call$1","grE",2,0,null,241],
+AQ:[function(a){return J.UQ(this.nI.gi2(),a)},"call$1","grE",2,0,null,236,[]],
 US:function(){this.pO()},
 hq:function(){this.pO()},
-static:{"":"Tj,pQ"}},
+static:{"^":"li,pQ"}},
 Kf:{
-"":"a;oV<",
-Gl:[function(a,b){this.oV.V7("addColumn",[a,b])},"call$2","gGU",4,0,null,11,507],
+"^":"a;oV<",
+goH:function(){return this.oV.nQ("getNumberOfColumns")},
+gWT:function(a){return this.oV.nQ("getNumberOfRows")},
+Gl:[function(a,b){this.oV.V7("addColumn",[a,b])},"call$2","gGU",4,0,null,11,[],510,[]],
 lb:[function(){var z=this.oV
 z.V7("removeRows",[0,z.nQ("getNumberOfRows")])},"call$0","gGL",0,0,null],
 RP:[function(a,b){var z=[]
 C.Nm.FV(z,H.VM(new H.A8(b,P.En()),[null,null]))
-this.oV.V7("addRow",[H.VM(new P.Tz(z),[null])])},"call$1","gJW",2,0,null,508]},
+this.oV.V7("addRow",[H.VM(new P.Tz(z),[null])])},"call$1","gJW",2,0,null,489,[]]},
 qu:{
-"":"a;YZ,bG>",
+"^":"a;YZ,bG>",
 W2:[function(a){var z=P.jT(this.bG)
-this.YZ.V7("draw",[a.goV(),z])},"call$1","gW8",2,0,null,178]},
+this.YZ.V7("draw",[a.goV(),z])},"call$1","gW8",2,0,null,178,[]]},
 bv:{
-"":["Pi;WP,XR<-509,Z0<-510,md,mY,F3,Gg,LE<-511,a3,mU,mM,Td,AP,fn",null,function(){return[C.mI]},function(){return[C.mI]},null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
-gB1:[function(a){return this.WP},null,null,1,0,512,"profile",359,372],
-sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,513,23,"profile",359],
-gjO:[function(a){return this.md},null,null,1,0,369,"id",359,372],
-sjO:[function(a,b){this.md=F.Wi(this,C.EN,this.md,b)},null,null,3,0,25,23,"id",359],
-goc:[function(a){return this.mY},null,null,1,0,369,"name",359,372],
-soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,"name",359],
-gw2:[function(){return this.F3},null,null,1,0,358,"entry",359,372],
-sw2:[function(a){this.F3=F.Wi(this,C.tP,this.F3,a)},null,null,3,0,361,23,"entry",359],
-gVc:[function(){return this.Gg},null,null,1,0,369,"rootLib",359,372],
-sVc:[function(a){this.Gg=F.Wi(this,C.iG,this.Gg,a)},null,null,3,0,25,23,"rootLib",359],
-gS0:[function(){return this.a3},null,null,1,0,478,"newHeapUsed",359,372],
-sS0:[function(a){this.a3=F.Wi(this,C.IO,this.a3,a)},null,null,3,0,390,23,"newHeapUsed",359],
-gcu:[function(){return this.mU},null,null,1,0,478,"oldHeapUsed",359,372],
-scu:[function(a){this.mU=F.Wi(this,C.ap,this.mU,a)},null,null,3,0,390,23,"oldHeapUsed",359],
-gKu:[function(){return this.mM},null,null,1,0,358,"topFrame",359,372],
-sKu:[function(a){this.mM=F.Wi(this,C.ch,this.mM,a)},null,null,3,0,361,23,"topFrame",359],
-gNh:[function(a){return this.Td},null,null,1,0,369,"fileAndLine",359,372],
-bj:function(a,b){return this.gNh(a).call$1(b)},
-sNh:[function(a,b){this.Td=F.Wi(this,C.SK,this.Td,b)},null,null,3,0,25,23,"fileAndLine",359],
+"^":["Pi;WP,XR<-511,Z0<-512,md,mY,F3,rU,LE<-513,iP,mU,mM,Td,AP,fn",null,function(){return[C.mI]},function(){return[C.mI]},null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
+gB1:[function(a){return this.WP},null,null,1,0,514,"profile",351,365],
+sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,515,23,[],"profile",351],
+gjO:[function(a){return this.md},null,null,1,0,362,"id",351,365],
+sjO:[function(a,b){this.md=F.Wi(this,C.EN,this.md,b)},null,null,3,0,25,23,[],"id",351],
+goc:[function(a){return this.mY},null,null,1,0,362,"name",351,365],
+soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,[],"name",351],
+gw2:[function(){return this.F3},null,null,1,0,350,"entry",351,365],
+sw2:[function(a){this.F3=F.Wi(this,C.tP,this.F3,a)},null,null,3,0,353,23,[],"entry",351],
+gVc:[function(){return this.rU},null,null,1,0,362,"rootLib",351,365],
+sVc:[function(a){this.rU=F.Wi(this,C.iF,this.rU,a)},null,null,3,0,25,23,[],"rootLib",351],
+gCi:[function(){return this.iP},null,null,1,0,482,"newHeapUsed",351,365],
+sCi:[function(a){this.iP=F.Wi(this,C.IO,this.iP,a)},null,null,3,0,385,23,[],"newHeapUsed",351],
+guq:[function(){return this.mU},null,null,1,0,482,"oldHeapUsed",351,365],
+suq:[function(a){this.mU=F.Wi(this,C.ap,this.mU,a)},null,null,3,0,385,23,[],"oldHeapUsed",351],
+gKu:[function(){return this.mM},null,null,1,0,350,"topFrame",351,365],
+sKu:[function(a){this.mM=F.Wi(this,C.ch,this.mM,a)},null,null,3,0,353,23,[],"topFrame",351],
+gNh:[function(a){return this.Td},null,null,1,0,362,"fileAndLine",351,365],
+bj:function(a,b){return this.gNh(this).call$1(b)},
+sNh:[function(a,b){this.Td=F.Wi(this,C.SK,this.Td,b)},null,null,3,0,25,23,[],"fileAndLine",351],
 zr:[function(a){var z="/"+H.d(this.md)+"/"
-$.tE.lw.fB(z).ml(new L.eS(this)).OA(new L.IQ())},"call$0","gBq",0,0,null],
+$.tE.DF.fB(z).ml(new L.eS(this)).OA(new L.IQ())},"call$0","gBq",0,0,null],
 eC:[function(a){var z,y,x,w
 z=J.U6(a)
 if(!J.de(z.t(a,"type"),"Isolate")){N.Jx("").hh("Unexpected message type in Isolate.update: "+H.d(z.t(a,"type")))
@@ -18426,12 +18781,11 @@
 return}y=z.t(a,"name")
 this.mY=F.Wi(this,C.YS,this.mY,y)
 y=J.UQ(z.t(a,"rootLib"),"id")
-this.Gg=F.Wi(this,C.iG,this.Gg,y)
+this.rU=F.Wi(this,C.iF,this.rU,y)
 if(z.t(a,"entry")!=null){y=z.t(a,"entry")
 this.F3=F.Wi(this,C.tP,this.F3,y)}if(z.t(a,"topFrame")!=null){y=z.t(a,"topFrame")
 this.mM=F.Wi(this,C.ch,this.mM,y)}x=H.B7([],P.L5(null,null,null,null,null))
 J.kH(z.t(a,"timers"),new L.TI(x))
-P.JS(x)
 y=this.LE
 w=J.w1(y)
 w.u(y,"total",x.t(0,"time_total_runtime"))
@@ -18440,9 +18794,9 @@
 w.u(y,"init",J.WB(J.WB(J.WB(x.t(0,"time_script_loading"),x.t(0,"time_creating_snapshot")),x.t(0,"time_isolate_initialization")),x.t(0,"time_bootstrap")))
 w.u(y,"dart",x.t(0,"time_dart_execution"))
 y=J.UQ(z.t(a,"heap"),"usedNew")
-this.a3=F.Wi(this,C.IO,this.a3,y)
+this.iP=F.Wi(this,C.IO,this.iP,y)
 z=J.UQ(z.t(a,"heap"),"usedOld")
-this.mU=F.Wi(this,C.ap,this.mU,z)},"call$1","gpn",2,0,null,144],
+this.mU=F.Wi(this,C.ap,this.mU,z)},"call$1","gpn",2,0,null,144,[]],
 bu:[function(a){return H.d(this.md)},"call$0","gXo",0,0,null],
 hv:[function(a){var z,y,x,w
 z=this.Z0
@@ -18451,7 +18805,7 @@
 while(!0){w=y.gB(z)
 if(typeof w!=="number")return H.s(w)
 if(!(x<w))break
-if(J.kE(y.t(z,x),a)===!0)return y.t(z,x);++x}},"call$1","gSB",2,0,null,514],
+if(J.kE(y.t(z,x),a)===!0)return y.t(z,x);++x}return},"call$1","gSB",2,0,null,516,[]],
 R7:[function(){var z,y,x,w
 N.Jx("").To("Reset all code ticks.")
 z=this.Z0
@@ -18467,25 +18821,25 @@
 u=J.UQ(v.t(w,"script"),"id")
 t=x.t(y,u)
 if(t==null){t=L.Ak(v.t(w,"script"))
-x.u(y,u,t)}t.o6(v.t(w,"hits"))}},"call$1","gHY",2,0,null,515],
+x.u(y,u,t)}t.o6(v.t(w,"hits"))}},"call$1","gHY",2,0,null,517,[]],
 $isbv:true,
-static:{"":"tE?"}},
+static:{"^":"tE?"}},
 eS:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.eC(a)},"call$1",null,2,0,null,144,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.eC(a)},"call$1",null,2,0,null,144,[],"call"],
 $isEH:true},
 IQ:{
-"":"Tp:349;",
-call$2:[function(a,b){N.Jx("").hh("Error while updating isolate summary: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,null,18,516,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while updating isolate summary: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,null,18,[],472,[],"call"],
 $isEH:true},
 TI:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.U6(a)
-this.a.u(0,z.t(a,"name"),z.t(a,"time"))},"call$1",null,2,0,null,517,"call"],
+this.a.u(0,z.t(a,"name"),z.t(a,"time"))},"call$1",null,2,0,null,518,[],"call"],
 $isEH:true},
-pt:{
-"":["Pi;XT?,i2<-518,AP,fn",null,function(){return[C.mI]},null,null],
-Ou:[function(){J.kH(this.XT.lw.gjR(),new L.dY(this))},"call$0","gPI",0,0,107],
+yU:{
+"^":["Pi;XT?,i2<-519,AP,fn",null,function(){return[C.mI]},null,null],
+Ql:[function(){J.kH(this.XT.DF.gjR(),new L.dY(this))},"call$0","gPI",0,0,107],
 AQ:[function(a){var z,y,x,w,v,u
 z=this.i2
 y=J.U6(z)
@@ -18497,31 +18851,31 @@
 u=R.Jk(u)
 x=new L.bv(null,w,v,a,"",null,null,u,0,0,null,null,null,null)
 y.u(z,a,x)
-return x}return x},"call$1","grE",2,0,null,241],
+return x}return x},"call$1","grE",2,0,null,236,[]],
 N8:[function(a){var z=[]
 J.kH(this.i2,new L.vY(a,z))
 H.bQ(z,new L.zZ(this))
-J.kH(a,new L.dS(this))},"call$1","gajF",2,0,null,242],
-static:{AC:[function(a,b){return J.pb(b,new L.Ub(a))},"call$2","mc",4,0,null,241,242]}},
+J.kH(a,new L.dS(this))},"call$1","gajF",2,0,null,237,[]],
+static:{AC:[function(a,b){return J.pb(b,new L.Ub(a))},"call$2","mc",4,0,null,236,[],237,[]]}},
 Ub:{
-"":"Tp:229;a",
-call$1:[function(a){return J.de(J.UQ(a,"id"),this.a)},"call$1",null,2,0,null,519,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.de(J.UQ(a,"id"),this.a)},"call$1",null,2,0,null,520,[],"call"],
 $isEH:true},
 dY:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.U6(a)
-if(J.de(z.t(a,"type"),"IsolateList"))this.a.N8(z.t(a,"members"))},"call$1",null,2,0,null,470,"call"],
+if(J.de(z.t(a,"type"),"IsolateList"))this.a.N8(z.t(a,"members"))},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 vY:{
-"":"Tp:349;a,b",
-call$2:[function(a,b){if(L.AC(a,this.a)!==!0)this.b.push(a)},"call$2",null,4,0,null,421,277,"call"],
+"^":"Tp:341;a,b",
+call$2:[function(a,b){if(L.AC(a,this.a)!==!0)this.b.push(a)},"call$2",null,4,0,null,417,[],272,[],"call"],
 $isEH:true},
 zZ:{
-"":"Tp:229;c",
-call$1:[function(a){J.V1(this.c.i2,a)},"call$1",null,2,0,null,241,"call"],
+"^":"Tp:223;c",
+call$1:[function(a){J.V1(this.c.i2,a)},"call$1",null,2,0,null,236,[],"call"],
 $isEH:true},
 dS:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z,y,x,w,v,u,t,s
 z=J.U6(a)
 y=z.t(a,"id")
@@ -18534,18 +18888,18 @@
 s=P.L5(null,null,null,J.O,J.GW)
 s=R.Jk(s)
 v=new L.bv(null,u,t,z.t(a,"id"),z.t(a,"name"),null,null,s,0,0,null,null,null,null)
-w.u(x,y,v)}J.KM(v)},"call$1",null,2,0,null,144,"call"],
+w.u(x,y,v)}J.KM(v)},"call$1",null,2,0,null,144,[],"call"],
 $isEH:true},
 dZ:{
-"":"Pi;XT?,WP,kg,UL,AP,fn",
-gB1:[function(a){return this.WP},null,null,1,0,373,"profile",359,372],
-sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,374,23,"profile",359],
-gb8:[function(){return this.kg},null,null,1,0,369,"currentHash",359,372],
-sb8:[function(a){this.kg=F.Wi(this,C.h1,this.kg,a)},null,null,3,0,25,23,"currentHash",359],
-gXX:[function(){return this.UL},null,null,1,0,520,"currentHashUri",359,372],
-sXX:[function(a){this.UL=F.Wi(this,C.tv,this.UL,a)},null,null,3,0,521,23,"currentHashUri",359],
+"^":"Pi;XT?,WP,kg,UL,AP,fn",
+gB1:[function(a){return this.WP},null,null,1,0,366,"profile",351,365],
+sB1:[function(a,b){this.WP=F.Wi(this,C.vb,this.WP,b)},null,null,3,0,367,23,[],"profile",351],
+gb8:[function(){return this.kg},null,null,1,0,362,"currentHash",351,365],
+sb8:[function(a){this.kg=F.Wi(this,C.h1,this.kg,a)},null,null,3,0,25,23,[],"currentHash",351],
+gXX:[function(){return this.UL},null,null,1,0,521,"currentHashUri",351,365],
+sXX:[function(a){this.UL=F.Wi(this,C.tv,this.UL,a)},null,null,3,0,522,23,[],"currentHashUri",351],
 kI:[function(){var z=C.PP.aM(window)
-H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new L.us(this)),z.Sg),[H.Kp(z,0)]).Zz()
+H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new L.Qe(this)),z.Sg),[H.Kp(z,0)]).Zz()
 if(!this.S7())this.df()},"call$0","gMz",0,0,null],
 vI:[function(){var z,y,x,w,v
 z=$.oy().R4(0,this.kg)
@@ -18558,91 +18912,121 @@
 y=J.q8(y[0])
 if(typeof y!=="number")return H.s(y)
 return C.xB.Nj(x,w,v+y)},"call$0","gzJ",0,0,null],
-gwB:[function(){return this.vI()!=null},null,null,1,0,373,"hasCurrentIsolate",372],
+gwB:[function(){return this.vI()!=null},null,null,1,0,366,"hasCurrentIsolate",365],
 R6:[function(){var z=this.vI()
 if(z==null)return""
 return J.ZZ(z,2)},"call$0","gKo",0,0,null],
 Pr:[function(){var z=this.R6()
 if(z==="")return
 return this.XT.nI.AQ(z)},"call$0","gjf",0,0,null],
-S7:[function(){var z=J.ON(C.ol.gmW(window))
+S7:[function(){var z=J.Co(C.ol.gmW(window))
 z=F.Wi(this,C.h1,this.kg,z)
 this.kg=z
 if(J.de(z,"")||J.de(this.kg,"#")){J.We(C.ol.gmW(window),"#/isolates/")
 return!0}return!1},"call$0","goO",0,0,null],
 df:[function(){var z,y,x
-z=J.ON(C.ol.gmW(window))
+z=J.Co(C.ol.gmW(window))
 z=F.Wi(this,C.h1,this.kg,z)
 this.kg=z
 y=J.ZZ(z,1)
-z=P.r6($.cO().ej(y))
+z=P.r6($.qG().ej(y))
 this.UL=F.Wi(this,C.tv,this.UL,z)
 z=$.wf()
 x=this.kg
 z=z.Ej
 if(typeof x!=="string")H.vh(new P.AT(x))
 if(z.test(x))this.WP=F.Wi(this,C.vb,this.WP,!0)
-else{this.XT.lw.ox(y)
+else{this.XT.DF.ox(y)
 this.WP=F.Wi(this,C.vb,this.WP,!1)}},"call$0","glq",0,0,null],
 kP:[function(a){var z=this.R6()
-return"#/"+z+"/"+H.d(a)},"call$1","gVM",2,0,206,279,"currentIsolateRelativeLink",372],
-XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.xM,!1))},"call$1","gOs",2,0,206,522,"currentIsolateScriptLink",372],
-r4:[function(a,b){return"#/"+H.d(a)+"/"+H.d(b)},"call$2","gLc",4,0,523,524,279,"relativeLink",372],
-Lr:[function(a){return"#/"+H.d(a)},"call$1","geP",2,0,206,279,"absoluteLink",372],
-static:{"":"x4,K3D,qY,HT"}},
-us:{
-"":"Tp:229;a",
+return"#/"+z+"/"+H.d(a)},"call$1","gVM",2,0,504,274,[],"currentIsolateRelativeLink",365],
+XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.xM,!1))},"call$1","gOs",2,0,504,523,[],"currentIsolateScriptLink",365],
+r4:[function(a,b,c){return"#/"+H.d(b)+"/"+H.d(c)},"call$2","gLc",4,0,524,525,[],274,[],"relativeLink",365],
+da:[function(a){return"#/"+H.d(a)},"call$1","geP",2,0,504,274,[],"absoluteLink",365],
+static:{"^":"x4,YF,qY,HT"}},
+Qe:{
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 if(z.S7())return
 F.Wi(z,C.D2,z.vI()==null,z.vI()!=null)
-z.df()},"call$1",null,2,0,null,405,"call"],
+z.df()},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 DP:{
-"":["Pi;Yu<-476,m7<-371,L4<-371,Fv,ZZ,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null,null],
-ga0:[function(){return this.Fv},null,null,1,0,478,"ticks",359,372],
-sa0:[function(a){this.Fv=F.Wi(this,C.p1,this.Fv,a)},null,null,3,0,390,23,"ticks",359],
-gGK:[function(){return this.ZZ},null,null,1,0,525,"percent",359,372],
-sGK:[function(a){this.ZZ=F.Wi(this,C.tI,this.ZZ,a)},null,null,3,0,526,23,"percent",359],
+"^":["Pi;Yu<-475,m7<-364,L4<-364,Fv,ZZ,AP,fn",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null,null,null],
+ga0:[function(){return this.Fv},null,null,1,0,482,"ticks",351,365],
+sa0:[function(a){this.Fv=F.Wi(this,C.p1,this.Fv,a)},null,null,3,0,385,23,[],"ticks",351],
+gGK:[function(){return this.ZZ},null,null,1,0,526,"percent",351,365],
+sGK:[function(a){this.ZZ=F.Wi(this,C.tI,this.ZZ,a)},null,null,3,0,527,23,[],"percent",351],
 oS:[function(){var z=this.ZZ
 if(z==null||J.Hb(z,0))return""
-return J.Ez(this.ZZ,2)+"% ("+H.d(this.Fv)+")"},"call$0","gu3",0,0,369,"formattedTicks",372],
-xt:[function(){return"0x"+J.u1(this.Yu,16)},"call$0","gZd",0,0,369,"formattedAddress",372],
-E7:[function(a){var z
-if(a==null||J.de(a.gfF(),0)){this.ZZ=F.Wi(this,C.tI,this.ZZ,null)
-return}z=J.FW(this.Fv,a.gfF())
-z=F.Wi(this,C.tI,this.ZZ,z*100)
-this.ZZ=z
-if(J.Hb(z,0)){this.ZZ=F.Wi(this,C.tI,this.ZZ,null)
-return}},"call$1","gIH",2,0,null,136]},
+return J.Ez(this.ZZ,2)+"% ("+H.d(this.Fv)+")"},"call$0","gu3",0,0,362,"formattedTicks",365],
+xt:[function(){return"0x"+J.u1(this.Yu,16)},"call$0","gZd",0,0,362,"formattedAddress",365]},
 WAE:{
-"":"a;eg",
+"^":"a;eg",
 bu:[function(a){return"CodeKind."+this.eg},"call$0","gXo",0,0,null],
-static:{"":"j6,bS,WAg",CQ:[function(a){var z=J.x(a)
+static:{"^":"j6,pg,WAg",CQ:[function(a){var z=J.x(a)
 if(z.n(a,"Native"))return C.nj
 else if(z.n(a,"Dart"))return C.l8
 else if(z.n(a,"Collected"))return C.WA
-throw H.b(P.hS())},"call$1","Tx",2,0,null,86]}},
+throw H.b(P.hS())},"call$1","Tx",2,0,null,86,[]]}},
 N8:{
-"":"a;Yu<,a0<"},
+"^":"a;Yu<,z4,Iw"},
+Vi:{
+"^":"a;tT>,Ou<"},
 kx:{
-"":["Pi;fY>,vg,Mb,a0<,fF@,Du@,va<-527,Qo,kY,mY,Tl,AP,fn",null,null,null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
-gkx:[function(){return this.Qo},null,null,1,0,358,"functionRef",359,372],
-skx:[function(a){this.Qo=F.Wi(this,C.yg,this.Qo,a)},null,null,3,0,361,23,"functionRef",359],
-gZN:[function(){return this.kY},null,null,1,0,358,"codeRef",359,372],
-sZN:[function(a){this.kY=F.Wi(this,C.EX,this.kY,a)},null,null,3,0,361,23,"codeRef",359],
-goc:[function(a){return this.mY},null,null,1,0,369,"name",359,372],
-soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,"name",359],
-gBr:[function(){return this.Tl},null,null,1,0,369,"user_name",359,372],
-sBr:[function(a){this.Tl=F.Wi(this,C.wj,this.Tl,a)},null,null,3,0,25,23,"user_name",359],
+"^":["Pi;fY>,vg,Mb,a0<,VS<,hw,fF<,Du<,va<-528,Qo,uP,mY,B0,AP,fn",null,null,null,null,null,null,null,null,function(){return[C.mI]},null,null,null,null,null,null],
+gkx:[function(){return this.Qo},null,null,1,0,350,"functionRef",351,365],
+skx:[function(a){this.Qo=F.Wi(this,C.yg,this.Qo,a)},null,null,3,0,353,23,[],"functionRef",351],
+gZN:[function(){return this.uP},null,null,1,0,350,"codeRef",351,365],
+sZN:[function(a){this.uP=F.Wi(this,C.EX,this.uP,a)},null,null,3,0,353,23,[],"codeRef",351],
+goc:[function(a){return this.mY},null,null,1,0,362,"name",351,365],
+soc:[function(a,b){this.mY=F.Wi(this,C.YS,this.mY,b)},null,null,3,0,25,23,[],"name",351],
+giK:[function(){return this.B0},null,null,1,0,362,"userName",351,365],
+siK:[function(a){this.B0=F.Wi(this,C.ct,this.B0,a)},null,null,3,0,25,23,[],"userName",351],
+Ne:[function(a,b){var z,y,x,w,v,u,t
+z=J.U6(b)
+this.fF=H.BU(z.t(b,"inclusive_ticks"),null,null)
+this.Du=H.BU(z.t(b,"exclusive_ticks"),null,null)
+y=z.t(b,"ticks")
+if(y!=null&&J.z8(J.q8(y),0)){z=J.U6(y)
+x=this.a0
+w=0
+while(!0){v=z.gB(y)
+if(typeof v!=="number")return H.s(v)
+if(!(w<v))break
+u=H.BU(z.t(y,w),16,null)
+t=H.BU(z.t(y,w+1),null,null)
+x.push(new L.N8(u,H.BU(z.t(y,w+2),null,null),t))
+w+=3}}},"call$1","gK0",2,0,null,144,[]],
+QQ:[function(){return this.fs(this.VS)},"call$0","gyj",0,0,null],
+dJ:[function(a){return this.U8(this.VS,a)},"call$1","gf7",2,0,null,136,[]],
+fs:[function(a){var z,y,x
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]),y=0;z.G();){x=z.lo.gOu()
+if(typeof x!=="number")return H.s(x)
+y+=x}return y},"call$1","gJ6",2,0,null,529,[]],
+U8:[function(a,b){var z,y
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();){y=z.lo
+if(J.de(J.on(y),b))return y.gOu()}return 0},"call$2","gGp",4,0,null,529,[],136,[]],
+hI:[function(a,b){var z=J.U6(a)
+this.GV(this.VS,z.t(a,"callers"),b)
+this.GV(this.hw,z.t(a,"callees"),b)},"call$2","gL0",4,0,null,136,[],530,[]],
+GV:[function(a,b,c){var z,y,x,w,v
+C.Nm.sB(a,0)
+z=J.U6(b)
+y=0
+while(!0){x=z.gB(b)
+if(typeof x!=="number")return H.s(x)
+if(!(y<x))break
+w=H.BU(z.t(b,y),null,null)
+v=H.BU(z.t(b,y+1),null,null)
+if(w>>>0!==w||w>=c.length)return H.e(c,w)
+a.push(new L.Vi(c[w],v))
+y+=2}H.ZE(a,0,a.length-1,new L.fx())},"call$3","gI1",6,0,null,529,[],231,[],530,[]],
 FB:[function(){this.fF=0
 this.Du=0
 C.Nm.sB(this.a0,0)
 for(var z=J.GP(this.va);z.G();)z.gl().sa0(0)},"call$0","gNB",0,0,null],
-xa:[function(a,b){var z,y
-for(z=J.GP(this.va);z.G();){y=z.gl()
-if(J.de(y.gYu(),a)){y.sa0(J.WB(y.ga0(),b))
-return}}},"call$2","gXO",4,0,null,514,122],
-Pi:[function(a){var z,y,x,w,v
+fo:[function(a){var z,y,x,w,v
 z=this.va
 y=J.w1(z)
 y.V1(z)
@@ -18652,142 +19036,128 @@
 if(typeof v!=="number")return H.s(v)
 if(!(w<v))break
 c$0:{if(J.de(x.t(a,w),""))break c$0
-y.h(z,new L.DP(H.BU(x.t(a,w),null,null),x.t(a,w+1),x.t(a,w+2),0,null,null,null))}w+=3}},"call$1","gwj",2,0,null,528],
+y.h(z,new L.DP(H.BU(x.t(a,w),null,null),x.t(a,w+1),x.t(a,w+2),0,null,null,null))}w+=3}},"call$1","gwj",2,0,null,531,[]],
 tg:[function(a,b){var z=J.Wx(b)
-return z.F(b,this.vg)&&z.C(b,this.Mb)},"call$1","gdj",2,0,null,514],
+return z.F(b,this.vg)&&z.C(b,this.Mb)},"call$1","gdj",2,0,null,516,[]],
 NV:function(a){var z,y
 z=J.U6(a)
 y=z.t(a,"function")
 y=R.Jk(y)
 this.Qo=F.Wi(this,C.yg,this.Qo,y)
 y=H.B7(["type","@Code","id",z.t(a,"id"),"name",z.t(a,"name"),"user_name",z.t(a,"user_name")],P.L5(null,null,null,null,null))
-this.kY=F.Wi(this,C.EX,this.kY,y)
+y=R.Jk(y)
+this.uP=F.Wi(this,C.EX,this.uP,y)
 y=z.t(a,"name")
 this.mY=F.Wi(this,C.YS,this.mY,y)
 y=z.t(a,"user_name")
-this.Tl=F.Wi(this,C.wj,this.Tl,y)
-this.Pi(z.t(a,"disassembly"))},
-$iskx:true,
-static:{Hj:function(a){var z,y,x,w
-z=R.Jk([])
-y=H.B7([],P.L5(null,null,null,null,null))
-y=R.Jk(y)
-x=H.B7([],P.L5(null,null,null,null,null))
-x=R.Jk(x)
-w=J.U6(a)
-x=new L.kx(C.l8,H.BU(w.t(a,"start"),16,null),H.BU(w.t(a,"end"),16,null),[],0,0,z,y,x,null,null,null,null)
-x.NV(a)
-return x}}},
+this.B0=F.Wi(this,C.ct,this.B0,y)
+if(z.t(a,"disassembly")!=null)this.fo(z.t(a,"disassembly"))},
+$iskx:true},
+fx:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.xH(b.gOu(),a.gOu())},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
 CM:{
-"":"a;Aq>,hV<",
-qy:[function(a){var z=J.UQ(a,"code")
-if(z==null)return this.LV(C.l8,a)
-return L.Hj(z)},"call$1","gS5",2,0,null,529],
-LV:[function(a,b){var z,y,x,w,v,u
-z=J.U6(b)
-y=H.BU(z.t(b,"start"),16,null)
-x=H.BU(z.t(b,"end"),16,null)
-w=z.t(b,"name")
-z=R.Jk([])
-v=H.B7([],P.L5(null,null,null,null,null))
-v=R.Jk(v)
-u=H.B7([],P.L5(null,null,null,null,null))
-u=R.Jk(u)
-return new L.kx(a,y,x,[],0,0,z,v,u,w,null,null,null)},"call$2","gAH",4,0,null,530,531],
-U5:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
-z={}
-y=J.U6(a)
-if(!J.de(y.t(a,"type"),"ProfileCode"))return
-x=L.CQ(y.t(a,"kind"))
-w=x===C.l8
-if(w)v=y.t(a,"code")!=null?H.BU(J.UQ(y.t(a,"code"),"start"),16,null):H.BU(y.t(a,"start"),16,null)
-else v=H.BU(y.t(a,"start"),16,null)
-u=this.Aq
-t=u.hv(v)
-z.a=t
-if(t==null){if(w)z.a=this.qy(a)
-else z.a=this.LV(x,a)
-J.bi(u.gZ0(),z.a)}s=H.BU(y.t(a,"inclusive_ticks"),null,null)
-r=H.BU(y.t(a,"exclusive_ticks"),null,null)
-z.a.sfF(s)
-z.a.sDu(r)
-q=y.t(a,"ticks")
-if(q!=null&&J.z8(J.q8(q),0)){y=J.U6(q)
-p=0
-while(!0){w=y.gB(q)
-if(typeof w!=="number")return H.s(w)
-if(!(p<w))break
-v=H.BU(y.t(q,p),16,null)
-o=H.BU(y.t(q,p+1),null,null)
-J.bi(z.a.ga0(),new L.N8(v,o))
-p+=2}}if(J.z8(J.q8(z.a.ga0()),0)&&J.z8(J.q8(z.a.gva()),0)){J.kH(z.a.ga0(),new L.ct(z))
-J.kH(z.a.gva(),new L.hM(z))}},"call$1","gu5",2,0,null,532],
+"^":"a;Aq>,jV,hV<",
+vD:[function(a){var z=J.U6(a)
+if(L.CQ(z.t(a,"kind"))===C.l8&&z.t(a,"code")!=null)return H.BU(J.UQ(z.t(a,"code"),"start"),16,null)
+return H.BU(z.t(a,"start"),16,null)},"call$1","gRU",2,0,null,136,[]],
+U5:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
+z=J.U6(a)
+if(!J.de(z.t(a,"type"),"ProfileCode"))return
+y=this.Aq
+x=y.hv(this.vD(a))
+if(x==null){w=L.CQ(z.t(a,"kind"))
+if(w===C.l8){x=z.t(a,"code")
+if(x!=null){v=J.U6(x)
+u=H.BU(v.t(x,"start"),16,null)
+t=H.BU(v.t(x,"end"),16,null)
+s=v.t(x,"name")
+r=v.t(x,"user_name")
+q=H.B7(["type","@Code","id",v.t(x,"id"),"name",s,"user_name",r],P.L5(null,null,null,null,null))
+p=R.Jk(q)
+v=v.t(x,"function")
+o=R.Jk(v)}else{u=null
+t=null
+s=null
+r=null
+p=null
+o=null}}else{u=null
+t=null
+s=null
+r=null
+p=null
+o=null}if(u==null){u=H.BU(z.t(a,"start"),16,null)
+t=H.BU(z.t(a,"end"),16,null)
+s=z.t(a,"name")
+r=s}v=R.Jk([])
+q=H.B7([],P.L5(null,null,null,null,null))
+q=R.Jk(q)
+n=H.B7([],P.L5(null,null,null,null,null))
+n=R.Jk(n)
+x=new L.kx(w,u,t,[],[],[],0,0,v,q,n,s,null,null,null)
+x.uP=F.Wi(x,C.EX,n,p)
+x.Qo=F.Wi(x,C.yg,x.Qo,o)
+x.B0=F.Wi(x,C.ct,x.B0,r)
+if(z.t(a,"disassembly")!=null)x.fo(z.t(a,"disassembly"))
+J.bi(y.gZ0(),x)}J.eh(x,a)
+this.jV.push(x)},"call$1","gu5",2,0,null,532,[]],
 T0:[function(a){var z,y
 z=this.Aq.gZ0()
 y=J.w1(z)
-y.So(z,new L.vu())
+y.GT(z,new L.vu())
 if(J.u6(y.gB(z),a)||J.de(a,0))return z
-return y.D6(z,0,a)},"call$1","gy8",2,0,null,122],
-hg:[function(a){var z,y
-z=this.Aq.gZ0()
-y=J.w1(z)
-y.So(z,new L.Ja())
-if(J.u6(y.gB(z),a)||J.de(a,0))return z
-return y.D6(z,0,a)},"call$1","geI",2,0,null,122],
-uH:function(a,b){var z,y
+return y.D6(z,0,a)},"call$1","gy8",2,0,null,122,[]],
+uH:function(a,b){var z,y,x,w,v
 z=J.U6(b)
 y=z.t(b,"codes")
 this.hV=z.t(b,"samples")
 z=J.U6(y)
 N.Jx("").To("Creating profile from "+H.d(this.hV)+" samples and "+H.d(z.gB(y))+" code objects.")
 this.Aq.R7()
-z.aN(y,new L.xn(this))},
-static:{hh:function(a,b){var z=new L.CM(a,0)
+x=this.jV
+C.Nm.sB(x,0)
+z.aN(y,new L.xn(this))
+w=0
+while(!0){v=z.gB(y)
+if(typeof v!=="number")return H.s(v)
+if(!(w<v))break
+if(w>=x.length)return H.e(x,w)
+x[w].hI(z.t(y,w),x);++w}C.Nm.sB(x,0)},
+static:{hh:function(a,b){var z=new L.CM(a,H.VM([],[L.kx]),0)
 z.uH(a,b)
 return z}}},
 xn:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y,x,w
 try{this.a.U5(a)}catch(x){w=H.Ru(x)
 z=w
 y=new H.XO(x,null)
-N.Jx("").xH("Error processing code object. "+H.d(z)+" "+H.d(y),z,y)}},"call$1",null,2,0,null,136,"call"],
-$isEH:true},
-ct:{
-"":"Tp:534;a",
-call$1:[function(a){this.a.a.xa(a.gYu(),a.ga0())},"call$1",null,2,0,null,533,"call"],
-$isEH:true},
-hM:{
-"":"Tp:229;a",
-call$1:[function(a){a.E7(this.a.a)},"call$1",null,2,0,null,341,"call"],
+N.Jx("").xH("Error processing code object. "+H.d(z)+" "+H.d(y),z,y)}},"call$1",null,2,0,null,136,[],"call"],
 $isEH:true},
 vu:{
-"":"Tp:535;",
-call$2:[function(a,b){return J.xH(b.gDu(),a.gDu())},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-Ja:{
-"":"Tp:535;",
-call$2:[function(a,b){return J.xH(b.gfF(),a.gfF())},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:533;",
+call$2:[function(a,b){return J.xH(b.gDu(),a.gDu())},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 c2:{
-"":["Pi;Rd<-476,eB,P2,AP,fn",function(){return[C.mI]},null,null,null,null],
-gu9:[function(){return this.eB},null,null,1,0,478,"hits",359,372],
-su9:[function(a){this.eB=F.Wi(this,C.K7,this.eB,a)},null,null,3,0,390,23,"hits",359],
-ga4:[function(a){return this.P2},null,null,1,0,369,"text",359,372],
-sa4:[function(a,b){this.P2=F.Wi(this,C.MB,this.P2,b)},null,null,3,0,25,23,"text",359],
+"^":["Pi;Rd>-475,eB,P2,AP,fn",function(){return[C.mI]},null,null,null,null],
+gu9:[function(){return this.eB},null,null,1,0,482,"hits",351,365],
+su9:[function(a){this.eB=F.Wi(this,C.K7,this.eB,a)},null,null,3,0,385,23,[],"hits",351],
+ga4:[function(a){return this.P2},null,null,1,0,362,"text",351,365],
+sa4:[function(a,b){this.P2=F.Wi(this,C.MB,this.P2,b)},null,null,3,0,25,23,[],"text",351],
 goG:function(){return J.J5(this.eB,0)},
 gVt:function(){return J.z8(this.eB,0)},
 $isc2:true},
 rj:{
-"":["Pi;W6,xN,Hz,Sw<-536,UK,AP,fn",null,null,null,function(){return[C.mI]},null,null,null],
-gfY:[function(a){return this.W6},null,null,1,0,369,"kind",359,372],
-sfY:[function(a,b){this.W6=F.Wi(this,C.fy,this.W6,b)},null,null,3,0,25,23,"kind",359],
-gKC:[function(){return this.xN},null,null,1,0,358,"scriptRef",359,372],
-sKC:[function(a){this.xN=F.Wi(this,C.Be,this.xN,a)},null,null,3,0,361,23,"scriptRef",359],
-gBi:[function(){return this.Hz},null,null,1,0,358,"libraryRef",359,372],
-sBi:[function(a){this.Hz=F.Wi(this,C.cg,this.Hz,a)},null,null,3,0,361,23,"libraryRef",359],
+"^":["Pi;W6,xN,Hz,Sw<-534,UK,AP,fn",null,null,null,function(){return[C.mI]},null,null,null],
+gfY:[function(a){return this.W6},null,null,1,0,362,"kind",351,365],
+sfY:[function(a,b){this.W6=F.Wi(this,C.fy,this.W6,b)},null,null,3,0,25,23,[],"kind",351],
+gKC:[function(){return this.xN},null,null,1,0,350,"scriptRef",351,365],
+sKC:[function(a){this.xN=F.Wi(this,C.Be,this.xN,a)},null,null,3,0,353,23,[],"scriptRef",351],
+gBi:[function(){return this.Hz},null,null,1,0,350,"libraryRef",351,365],
+sBi:[function(a){this.Hz=F.Wi(this,C.cg,this.Hz,a)},null,null,3,0,353,23,[],"libraryRef",351],
 giI:function(){return this.UK},
-gX4:[function(){return J.Pr(this.Sw,1)},null,null,1,0,537,"linesForDisplay",372],
+gX4:[function(){return J.Pr(this.Sw,1)},null,null,1,0,535,"linesForDisplay",365],
 Av:[function(a){var z,y,x,w
 z=this.Sw
 y=J.U6(z)
@@ -18795,16 +19165,16 @@
 if(x.F(a,y.gB(z)))y.sB(z,x.g(a,1))
 w=y.t(z,a)
 if(w==null){w=new L.c2(a,-1,"",null,null)
-y.u(z,a,w)}return w},"call$1","gKN",2,0,null,538],
+y.u(z,a,w)}return w},"call$1","gKN",2,0,null,536,[]],
 lu:[function(a){var z,y,x,w
 if(a==null)return
 N.Jx("").To("Loading source for "+H.d(J.UQ(this.xN,"name")))
-z=J.Gn(a,"\n")
+z=J.uH(a,"\n")
 this.UK=z.length===0
 for(y=0;y<z.length;y=x){x=y+1
 w=this.Av(x)
 if(y>=z.length)return H.e(z,y)
-J.c9(w,z[y])}},"call$1","ghH",2,0,null,27],
+J.c9(w,z[y])}},"call$1","ghH",2,0,null,27,[]],
 o6:[function(a){var z,y,x
 z=J.U6(a)
 y=0
@@ -18812,14 +19182,14 @@
 if(typeof x!=="number")return H.s(x)
 if(!(y<x))break
 this.Av(z.t(a,y)).su9(z.t(a,y+1))
-y+=2}F.Wi(this,C.C2,"","("+C.CD.yM(this.Nk(),1)+"% covered)")},"call$1","gpc",2,0,null,539],
+y+=2}F.Wi(this,C.C2,"","("+C.CD.yM(this.Nk(),1)+"% covered)")},"call$1","gpc",2,0,null,537,[]],
 Nk:[function(){var z,y,x,w
 for(z=J.GP(this.Sw),y=0,x=0;z.G();){w=z.gl()
 if(w==null)continue
 if(!w.goG())continue;++x
 if(!w.gVt())continue;++y}if(x===0)return 0
-return y/x*100},"call$0","gUO",0,0,525,"coveredPercentage",372],
-nZ:[function(){return"("+C.CD.yM(this.Nk(),1)+"% covered)"},"call$0","gic",0,0,369,"coveredPercentageFormatted",372],
+return y/x*100},"call$0","gCx",0,0,526,"coveredPercentage",365],
+nZ:[function(){return"("+C.CD.yM(this.Nk(),1)+"% covered)"},"call$0","gic",0,0,362,"coveredPercentageFormatted",365],
 Ea:function(a){var z,y
 z=J.U6(a)
 y=H.B7(["id",z.t(a,"id"),"name",z.t(a,"name"),"user_name",z.t(a,"user_name")],P.L5(null,null,null,null,null))
@@ -18842,42 +19212,42 @@
 x=new L.rj(null,z,y,x,!0,null,null)
 x.Ea(a)
 return x}}},
-R2:{
-"":"Pi;XT?,e0?",
+Nu:{
+"^":"Pi;XT?,e0?",
 pG:function(){return this.e0.call$0()},
-gIw:[function(){return this.SI},null,null,1,0,369,"prefix",359,372],
-sIw:[function(a){this.SI=F.Wi(this,C.NA,this.SI,a)},null,null,3,0,25,23,"prefix",359],
-gjR:[function(){return this.Tj},null,null,1,0,498,"responses",359,372],
-sjR:[function(a){this.Tj=F.Wi(this,C.wH,this.Tj,a)},null,null,3,0,540,23,"responses",359],
+geG:[function(){return this.SI},null,null,1,0,362,"prefix",351,365],
+seG:[function(a){this.SI=F.Wi(this,C.qb3,this.SI,a)},null,null,3,0,25,23,[],"prefix",351],
+gjR:[function(){return this.Tj},null,null,1,0,501,"responses",351,365],
+sjR:[function(a){this.Tj=F.Wi(this,C.wH,this.Tj,a)},null,null,3,0,538,23,[],"responses",351],
 FH:[function(a){var z,y,x,w,v
 z=null
-try{z=C.lM.kV(a)}catch(w){v=H.Ru(w)
+try{z=C.xr.kV(a)}catch(w){v=H.Ru(w)
 y=v
 x=new H.XO(w,null)
-this.AI(H.d(y)+" "+H.d(x))}return z},"call$1","gkJ",2,0,null,470],
+this.AI(H.d(y)+" "+H.d(x))}return z},"call$1","gkJ",2,0,null,466,[]],
 f3:[function(a){var z,y
 z=this.FH(a)
 if(z==null)return
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isZ0)this.dq([z])
-else this.dq(z)},"call$1","gER",2,0,null,541],
+else this.dq(z)},"call$1","gt7",2,0,null,539,[]],
 dq:[function(a){var z=R.Jk(a)
 this.Tj=F.Wi(this,C.wH,this.Tj,z)
-if(this.e0!=null)this.pG()},"call$1","gvw",2,0,null,375],
+if(this.e0!=null)this.pG()},"call$1","gvw",2,0,null,368,[]],
 AI:[function(a){this.dq([H.B7(["type","Error","errorType","ResponseError","text",a],P.L5(null,null,null,null,null))])
-N.Jx("").hh(a)},"call$1","gug",2,0,null,20],
+N.Jx("").hh(a)},"call$1","gug",2,0,null,20,[]],
 Uu:[function(a){var z,y,x,w,v
 z=L.Lw(a)
 if(z==null){this.AI(z+" is not an isolate id.")
 return}y=this.XT.nI.AQ(z)
 if(y==null){this.AI(z+" could not be found.")
-return}x=L.TK(a)
+return}x=L.CX(a)
 w=J.x(x)
 if(w.n(x,0)){this.AI(a+" is not a valid code request.")
 return}v=y.hv(x)
 if(v!=null){N.Jx("").To("Found code with 0x"+w.WZ(x,16)+" in isolate.")
 this.dq([H.B7(["type","Code","code",v],P.L5(null,null,null,null,null))])
-return}this.ym(0,a).ml(new L.Q4(this,y,x)).OA(this.gSC())},"call$1","gVB",2,0,null,542],
+return}this.ym(0,a).ml(new L.Q4(this,y,x)).OA(this.gSC())},"call$1","gVB",2,0,null,540,[]],
 GY:[function(a){var z,y,x,w,v
 z=L.Lw(a)
 if(z==null){this.AI(z+" is not an isolate id.")
@@ -18890,61 +19260,68 @@
 if(v&&!w.giI()){N.Jx("").To("Found script "+H.d(J.UQ(w.gKC(),"name"))+" in isolate")
 this.dq([H.B7(["type","Script","script",w],P.L5(null,null,null,null,null))])
 return}if(v){this.fB(a).ml(new L.aJ(this,w))
-return}this.fB(a).ml(new L.u4(this,y,x))},"call$1","gPc",2,0,null,542],
-fs:[function(a,b){var z,y,x
+return}this.fB(a).ml(new L.u4(this,y,x))},"call$1","gPc",2,0,null,540,[]],
+xl:[function(a,b){var z,y,x
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isew){z=W.qc(a.target)
 y=J.RE(z)
 x=H.d(y.gys(z))+" "+y.gpo(z)
 if(y.gys(z)===0)x="No service found. Did you run with --enable-vm-service ?"
-this.dq([H.B7(["type","Error","errorType","RequestError","text",x],P.L5(null,null,null,null,null))])}else this.AI(H.d(a)+" "+H.d(b))},"call$2","gSC",4,0,543,18,472],
+this.dq([H.B7(["type","Error","errorType","RequestError","text",x],P.L5(null,null,null,null,null))])}else this.AI(H.d(a)+" "+H.d(b))},"call$2","gSC",4,0,541,18,[],468,[]],
 ox:[function(a){var z=$.mE().Ej
 if(z.test(a)){this.Uu(a)
 return}z=$.Ww().Ej
 if(z.test(a)){this.GY(a)
-return}this.ym(0,a).ml(new L.pF(this)).OA(this.gSC())},"call$1","gRD",2,0,null,542],
-fB:[function(a){return this.ym(0,a).ml(new L.Q2())},"call$1","gHi",2,0,null,542]},
+return}this.ym(0,a).ml(new L.pF(this)).OA(this.gSC())},"call$1","gRD",2,0,null,540,[]],
+fB:[function(a){return this.ym(0,C.xB.nC(a,"#")?C.xB.yn(a,1):a).ml(new L.Q2())},"call$1","gHi",2,0,null,540,[]]},
 Q4:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){var z,y,x
+"^":"Tp:223;a,b,c",
+call$1:[function(a){var z,y,x,w,v,u,t
 z=this.a
 y=z.FH(a)
 if(y==null)return
-x=L.Hj(y)
+x=R.Jk([])
+w=H.B7([],P.L5(null,null,null,null,null))
+w=R.Jk(w)
+v=H.B7([],P.L5(null,null,null,null,null))
+v=R.Jk(v)
+u=J.U6(y)
+t=new L.kx(C.l8,H.BU(u.t(y,"start"),16,null),H.BU(u.t(y,"end"),16,null),[],[],[],0,0,x,w,v,null,null,null,null)
+t.NV(y)
 N.Jx("").To("Added code with 0x"+J.u1(this.c,16)+" to isolate.")
-J.bi(this.b.gZ0(),x)
-z.dq([H.B7(["type","Code","code",x],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,541,"call"],
+J.bi(this.b.gZ0(),t)
+z.dq([H.B7(["type","Code","code",t],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,539,[],"call"],
 $isEH:true},
 aJ:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=this.b
 z.lu(J.UQ(a,"source"))
 N.Jx("").To("Grabbed script "+H.d(J.UQ(z.gKC(),"name"))+" source.")
-this.a.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,470,"call"],
+this.a.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 u4:{
-"":"Tp:229;c,d,e",
+"^":"Tp:223;c,d,e",
 call$1:[function(a){var z=L.Ak(a)
 N.Jx("").To("Added script "+H.d(J.UQ(z.xN,"name"))+" to isolate.")
 this.c.dq([H.B7(["type","Script","script",z],P.L5(null,null,null,null,null))])
-J.kW(this.d.gXR(),this.e,z)},"call$1",null,2,0,null,470,"call"],
+J.kW(this.d.gXR(),this.e,z)},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
 pF:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.f3(a)},"call$1",null,2,0,null,541,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.f3(a)},"call$1",null,2,0,null,539,[],"call"],
 $isEH:true},
 Q2:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z,y
-try{z=C.lM.kV(a)
-return z}catch(y){H.Ru(y)}return},"call$1",null,2,0,null,470,"call"],
+try{z=C.xr.kV(a)
+return z}catch(y){H.Ru(y)}return},"call$1",null,2,0,null,466,[],"call"],
 $isEH:true},
-tb:{
-"":"R2;XT,e0,SI,Tj,AP,fn",
+r1:{
+"^":"Nu;XT,e0,SI,Tj,AP,fn",
 ym:[function(a,b){N.Jx("").To("Requesting "+b)
-return W.It(J.WB(this.SI,b),null,null)},"call$1","gkq",2,0,null,542]},
+return W.It(J.WB(this.SI,b),null,null)},"call$1","gkq",2,0,null,540,[]]},
 Rb:{
-"":"R2;eA,Wj,XT,e0,SI,Tj,AP,fn",
+"^":"Nu;eA,Wj,XT,e0,SI,Tj,AP,fn",
 AJ:[function(a){var z,y,x,w,v
 z=J.RE(a)
 y=J.UQ(z.gRn(a),"id")
@@ -18955,7 +19332,7 @@
 v=z.t(0,y)
 if(v!=null){z.Rz(0,y)
 P.JS("Completing "+H.d(y))
-J.Xf(v,w)}else P.JS("Could not find completer for "+H.d(y))},"call$1","gpJ",2,0,152,19],
+J.Xf(v,w)}else P.JS("Could not find completer for "+H.d(y))},"call$1","gpJ",2,0,150,19,[]],
 ym:[function(a,b){var z,y,x
 z=""+this.Wj
 y=H.B7([],P.L5(null,null,null,null,null))
@@ -18965,14 +19342,64 @@
 this.Wj=this.Wj+1
 x=H.VM(new P.Zf(P.Dt(null)),[null])
 this.eA.u(0,z,x)
-J.Ih(W.Pv(window.parent),C.lM.KP(y),"*")
-return x.MM},"call$1","gkq",2,0,null,542]}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{
-"":"",
+J.Ih(W.Pv(window.parent),C.xr.KP(y),"*")
+return x.MM},"call$1","gkq",2,0,null,540,[]]},
+Y2:{
+"^":["Pi;eT>,yt<-475,wd>-476,oH<-477",null,function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]}],
+goE:function(a){return this.np},
+soE:function(a,b){var z=this.np
+this.np=b
+if(z!==b)if(b)this.C4(0)
+else this.o8()},
+r8:[function(){this.soE(0,!this.np)
+return this.np},"call$0","gMk",0,0,null],
+$isY2:true},
+XN:{
+"^":["Pi;JL,WT>-476,AP,fn",null,function(){return[C.mI]},null,null],
+rT:[function(a){var z,y
+z=this.WT
+y=J.w1(z)
+y.V1(z)
+y.FV(z,a)},"call$1","gE3",2,0,null,542,[]],
+qU:[function(a){var z,y,x
+P.JS(a)
+z=this.WT
+y=J.U6(z)
+P.JS(y.gB(z))
+x=y.t(z,a)
+if(x.r8())this.ad(x)
+else this.cB(x)
+P.JS("e")},"call$1","gMk",2,0,null,543,[]],
+ad:[function(a){var z,y,x,w,v,u,t
+z=this.WT
+y=J.U6(z)
+x=y.u8(z,a)
+w=J.RE(a)
+v=0
+while(!0){u=J.q8(w.gwd(a))
+if(typeof u!=="number")return H.s(u)
+if(!(v<u))break
+u=x+v+1
+t=J.UQ(w.gwd(a),v)
+if(u===-1)y.h(z,t)
+else y.xe(z,u,t);++v}},"call$1","ghF",2,0,null,489,[]],
+cB:[function(a){var z,y,x,w,v
+z=J.RE(a)
+y=J.q8(z.gwd(a))
+if(J.de(y,0))return
+if(typeof y!=="number")return H.s(y)
+x=0
+for(;x<y;++x)if(J.YV(J.UQ(z.gwd(a),x))===!0)this.cB(J.UQ(z.gwd(a),x))
+z.soE(a,!1)
+z=this.WT
+w=J.U6(z)
+for(v=w.u8(z,a)+1,x=0;x<y;++x)w.KI(z,v)},"call$1","gjc",2,0,null,489,[]]}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{
+"^":"",
 F1:{
-"":["V11;k5%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gzj:[function(a){return a.k5},null,null,1,0,373,"devtools",359,360],
-szj:[function(a,b){a.k5=this.ct(a,C.Na,a.k5,b)},null,null,3,0,374,23,"devtools",359],
-te:[function(a){var z,y
+"^":["V12;k5%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gzj:[function(a){return a.k5},null,null,1,0,366,"devtools",351,352],
+szj:[function(a,b){a.k5=this.ct(a,C.Na,a.k5,b)},null,null,3,0,367,23,[],"devtools",351],
+ZB:[function(a){var z,y
 if(a.k5===!0){z=P.L5(null,null,null,null,null)
 y=R.Jk([])
 y=new L.Rb(z,0,null,null,"http://127.0.0.1:8181",y,null,null)
@@ -18980,12 +19407,12 @@
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(y.gpJ()),z.Sg),[H.Kp(z,0)]).Zz()
 z=P.L5(null,null,null,J.O,L.bv)
 z=R.Jk(z)
-z=new L.mL(new L.dZ(null,!1,"",null,null,null),y,new L.pt(null,z,null,null),null,null)
+z=new L.mL(new L.dZ(null,!1,"",null,null,null),y,new L.yU(null,z,null,null),null,null)
 z.hq()
 a.hm=this.ct(a,C.wh,a.hm,z)}else{z=R.Jk([])
 y=P.L5(null,null,null,J.O,L.bv)
 y=R.Jk(y)
-y=new L.mL(new L.dZ(null,!1,"",null,null,null),new L.tb(null,null,"http://127.0.0.1:8181",z,null,null),new L.pt(null,y,null,null),null,null)
+y=new L.mL(new L.dZ(null,!1,"",null,null,null),new L.r1(null,null,"http://127.0.0.1:8181",z,null,null),new L.yU(null,y,null,null),null,null)
 y.US()
 a.hm=this.ct(a,C.wh,a.hm,y)}},null,null,0,0,108,"created"],
 "@":function(){return[C.y2]},
@@ -18998,25 +19425,25 @@
 a.k5=!1
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.k0.ZL(a)
-C.k0.oX(a)
-C.k0.te(a)
-return a},null,null,0,0,108,"new ObservatoryApplicationElement$created" /* new ObservatoryApplicationElement$created:0:0 */]}},
+C.k0.G6(a)
+C.k0.ZB(a)
+return a},null,null,0,0,108,"new ObservatoryApplicationElement$created"]}},
 "+ObservatoryApplicationElement":[544],
-V11:{
-"":"uL+Pi;",
+V12:{
+"^":"uL+Pi;",
 $isd3:true}}],["observatory_element","package:observatory/src/observatory_elements/observatory_element.dart",,Z,{
-"":"",
+"^":"",
 uL:{
-"":["LP;hm%-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"^":["LP;hm%-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 i4:[function(a){A.zs.prototype.i4.call(this,a)},"call$0","gQd",0,0,107,"enteredView"],
 xo:[function(a){A.zs.prototype.xo.call(this,a)},"call$0","gbt",0,0,107,"leftView"],
-aC:[function(a,b,c,d){A.zs.prototype.aC.call(this,a,b,c,d)},"call$3","gxR",6,0,545,12,231,232,"attributeChanged"],
-guw:[function(a){return a.hm},null,null,1,0,546,"app",359,360],
-suw:[function(a,b){a.hm=this.ct(a,C.wh,a.hm,b)},null,null,3,0,547,23,"app",359],
-Pz:[function(a,b){},"call$1","gpx",2,0,152,231,"appChanged"],
-gpQ:[function(a){return!0},null,null,1,0,373,"applyAuthorStyles"],
+aC:[function(a,b,c,d){A.zs.prototype.aC.call(this,a,b,c,d)},"call$3","gxR",6,0,545,12,[],225,[],226,[],"attributeChanged"],
+guw:[function(a){return a.hm},null,null,1,0,546,"app",351,352],
+suw:[function(a,b){a.hm=this.ct(a,C.wh,a.hm,b)},null,null,3,0,547,23,[],"app",351],
+Pz:[function(a,b){},"call$1","gpx",2,0,150,225,[],"appChanged"],
+gpQ:[function(a){return!0},null,null,1,0,366,"applyAuthorStyles"],
 Om:[function(a,b){var z,y,x,w
 if(b==null)return"-"
 z=J.LL(J.p0(b,1000))
@@ -19026,18 +19453,28 @@
 z=C.jn.Y(z,60000)
 w=C.jn.cU(z,1000)
 z=C.jn.Y(z,1000)
-return Z.Ce(y,2)+":"+Z.Ce(x,2)+":"+Z.Ce(w,2)+"."+Z.Ce(z,3)},"call$1","gSs",2,0,548,549,"formatTime"],
+return Z.Ce(y,2)+":"+Z.Ce(x,2)+":"+Z.Ce(w,2)+"."+Z.Ce(z,3)},"call$1","gSs",2,0,548,549,[],"formatTime"],
 Ze:[function(a,b){var z=J.Wx(b)
 if(z.C(b,1024))return H.d(b)+"B"
 else if(z.C(b,1048576))return""+C.CD.yu(C.CD.UD(z.V(b,1024)))+"KB"
 else if(z.C(b,1073741824))return""+C.CD.yu(C.CD.UD(z.V(b,1048576)))+"MB"
 else if(z.C(b,1099511627776))return""+C.CD.yu(C.CD.UD(z.V(b,1073741824)))+"GB"
-else return""+C.CD.yu(C.CD.UD(z.V(b,1099511627776)))+"TB"},"call$1","gbJ",2,0,391,550,"formatSize"],
+else return""+C.CD.yu(C.CD.UD(z.V(b,1099511627776)))+"TB"},"call$1","gbJ",2,0,387,550,[],"formatSize"],
 bj:[function(a,b){var z,y,x
 z=J.U6(b)
 y=J.UQ(z.t(b,"script"),"user_name")
 x=J.U6(y)
-return x.yn(y,J.WB(x.cn(y,"/"),1))+":"+H.d(z.t(b,"line"))},"call$1","gNh",2,0,551,552,"fileAndLine"],
+return x.yn(y,J.WB(x.cn(y,"/"),1))+":"+H.d(z.t(b,"line"))},"call$1","gNh",2,0,551,552,[],"fileAndLine"],
+nt:[function(a,b){return J.de(b,"@Null")},"call$1","gYx",2,0,553,11,[],"isNullRef"],
+Qq:[function(a,b){var z=J.x(b)
+return z.n(b,"@Smi")||z.n(b,"@Mint")||z.n(b,"@Bigint")},"call$1","gBI",2,0,553,11,[],"isIntRef"],
+TJ:[function(a,b){return J.de(b,"@Bool")},"call$1","gUA",2,0,553,11,[],"isBoolRef"],
+qH:[function(a,b){return J.de(b,"@String")},"call$1","gwm",2,0,553,11,[],"isStringRef"],
+JG:[function(a,b){return J.de(b,"@Instance")},"call$1","gUq",2,0,553,11,[],"isInstanceRef"],
+CL:[function(a,b){return J.de(b,"@Closure")},"call$1","gj7",2,0,553,11,[],"isClosureRef"],
+Bk:[function(a,b){var z=J.x(b)
+return z.n(b,"@GrowableObjectArray")||z.n(b,"@Array")},"call$1","gmv",2,0,553,11,[],"isListRef"],
+VR:[function(a,b){return!C.Nm.tg(["@Null","@Smi","@Mint","@Biginit","@Bool","@String","@Closure","@Instance","@GrowableObjectArray","@Array"],b)},"call$1","gua",2,0,553,11,[],"isUnexpectedRef"],
 "@":function(){return[C.Br]},
 static:{Hx:[function(a){var z,y,x,w
 z=$.Nd()
@@ -19047,21 +19484,21 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Pf.ZL(a)
-C.Pf.oX(a)
-return a},null,null,0,0,108,"new ObservatoryElement$created" /* new ObservatoryElement$created:0:0 */],Ce:[function(a,b){var z,y,x,w
+C.Pf.G6(a)
+return a},null,null,0,0,108,"new ObservatoryElement$created"],Ce:[function(a,b){var z,y,x,w
 for(z=J.Wx(a),y="";x=J.Wx(b),x.D(b,1);){w=x.W(b,1)
 if(typeof w!=="number")H.vh(new P.AT(w))
 if(z.C(a,Math.pow(10,w)))y+="0"
-b=x.W(b,1)}return y+H.d(a)},"call$2","px",4,0,243,23,244,"_zeroPad"]}},
-"+ObservatoryElement":[553],
+b=x.W(b,1)}return y+H.d(a)},"call$2","Rz",4,0,238,23,[],239,[],"_zeroPad"]}},
+"+ObservatoryElement":[554],
 LP:{
-"":"ir+Pi;",
+"^":"ir+Pi;",
 $isd3:true}}],["observe.src.change_notifier","package:observe/src/change_notifier.dart",,O,{
-"":"",
+"^":"",
 Pi:{
-"":"a;",
+"^":"a;",
 gUj:function(a){var z=a.AP
 if(z==null){z=this.gqw(a)
 z=P.bK(this.gl1(a),z,!0,null)
@@ -19078,36 +19515,36 @@
 if(x&&z!=null){x=H.VM(new P.Yp(z),[T.z2])
 if(y.Gv>=4)H.vh(y.q7())
 y.Iv(x)
-return!0}return!1},"call$0","gDx",0,0,373],
+return!0}return!1},"call$0","gDx",0,0,366],
 gUV:function(a){var z,y
 z=a.AP
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 return z},
-ct:[function(a,b,c,d){return F.Wi(a,b,c,d)},"call$3","gAn",6,0,null,257,231,232],
+ct:[function(a,b,c,d){return F.Wi(a,b,c,d)},"call$3","gAn",6,0,null,252,[],225,[],226,[]],
 nq:[function(a,b){var z,y
 z=a.AP
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)return
 if(a.fn==null){a.fn=[]
-P.rb(this.gDx(a))}a.fn.push(b)},"call$1","gbW",2,0,null,22],
+P.rb(this.gDx(a))}a.fn.push(b)},"call$1","giA",2,0,null,22,[]],
 $isd3:true}}],["observe.src.change_record","package:observe/src/change_record.dart",,T,{
-"":"",
+"^":"",
 z2:{
-"":"a;",
+"^":"a;",
 $isz2:true},
 qI:{
-"":"z2;WA<,oc>,jL>,zZ>",
+"^":"z2;WA<,oc>,jL>,zZ>",
 bu:[function(a){return"#<PropertyChangeRecord "+H.d(this.oc)+" from: "+H.d(this.jL)+" to: "+H.d(this.zZ)+">"},"call$0","gXo",0,0,null],
 $isqI:true}}],["observe.src.compound_path_observer","package:observe/src/compound_path_observer.dart",,Y,{
-"":"",
+"^":"",
 J3:{
-"":"Pi;b9,kK,Sv,rk,YX,B6,AP,fn",
+"^":"Pi;b9,kK,Sv,rk,YX,B6,AP,fn",
 kb:function(a){return this.rk.call$1(a)},
 gB:function(a){return this.b9.length},
-gP:[function(a){return this.Sv},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+gP:[function(a){return this.Sv},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 wE:[function(a){var z,y,x,w,v
 if(this.YX)return
 this.YX=!0
@@ -19120,7 +19557,7 @@
 x.push(w)}this.Ow()},"call$0","gM",0,0,null],
 TF:[function(a){if(this.B6)return
 this.B6=!0
-P.rb(this.gMc())},"call$1","geu",2,0,152,240],
+P.rb(this.gMc())},"call$1","geu",2,0,150,235,[]],
 Ow:[function(){var z,y
 this.B6=!1
 z=this.b9
@@ -19139,10 +19576,10 @@
 ni:[function(a){return this.cO(0)},"call$0","gl1",0,0,108],
 $isJ3:true},
 E5:{
-"":"Tp:229;",
-call$1:[function(a){return J.Vm(a)},"call$1",null,2,0,null,91,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.Vm(a)},"call$1",null,2,0,null,91,[],"call"],
 $isEH:true}}],["observe.src.dirty_check","package:observe/src/dirty_check.dart",,O,{
-"":"",
+"^":"",
 Y3:[function(){var z,y,x,w,v,u,t,s,r,q
 if($.Td)return
 if($.tW==null)return
@@ -19169,40 +19606,40 @@
 Ht:[function(){var z={}
 z.a=!1
 z=new O.o5(z)
-return new P.zG(null,null,null,null,new O.u3(z),new O.id(z),null,null,null,null,null,null)},"call$0","Zq",0,0,null],
+return new P.zG(null,null,null,null,new O.zI(z),new O.id(z),null,null,null,null,null,null)},"call$0","Zq",0,0,null],
 o5:{
-"":"Tp:554;a",
+"^":"Tp:555;a",
 call$2:[function(a,b){var z=this.a
 if(z.a)return
 z.a=!0
-a.RK(b,new O.b5(z))},"call$2",null,4,0,null,162,148,"call"],
+a.RK(b,new O.b5(z))},"call$2",null,4,0,null,162,[],146,[],"call"],
 $isEH:true},
 b5:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){this.a.a=!1
 O.Y3()},"call$0",null,0,0,null,"call"],
 $isEH:true},
-u3:{
-"":"Tp:163;b",
+zI:{
+"^":"Tp:163;b",
 call$4:[function(a,b,c,d){if(d==null)return d
-return new O.Zb(this.b,b,c,d)},"call$4",null,8,0,null,161,162,148,110,"call"],
+return new O.Zb(this.b,b,c,d)},"call$4",null,8,0,null,161,[],162,[],146,[],110,[],"call"],
 $isEH:true},
 Zb:{
-"":"Tp:108;c,d,e,f",
+"^":"Tp:108;c,d,e,f",
 call$0:[function(){this.c.call$2(this.d,this.e)
 return this.f.call$0()},"call$0",null,0,0,null,"call"],
 $isEH:true},
 id:{
-"":"Tp:555;UI",
+"^":"Tp:556;UI",
 call$4:[function(a,b,c,d){if(d==null)return d
-return new O.iV(this.UI,b,c,d)},"call$4",null,8,0,null,161,162,148,110,"call"],
+return new O.iV(this.UI,b,c,d)},"call$4",null,8,0,null,161,[],162,[],146,[],110,[],"call"],
 $isEH:true},
 iV:{
-"":"Tp:229;bK,Gq,Rm,w3",
+"^":"Tp:223;bK,Gq,Rm,w3",
 call$1:[function(a){this.bK.call$2(this.Gq,this.Rm)
-return this.w3.call$1(a)},"call$1",null,2,0,null,21,"call"],
+return this.w3.call$1(a)},"call$1",null,2,0,null,21,[],"call"],
 $isEH:true}}],["observe.src.list_diff","package:observe/src/list_diff.dart",,G,{
-"":"",
+"^":"",
 f6:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l
 z=J.WB(J.xH(f,e),1)
 y=J.WB(J.xH(c,b),1)
@@ -19238,7 +19675,7 @@
 if(typeof n!=="number")return n.g()
 n=P.J(o+1,n+1)
 if(t>=l)return H.e(m,t)
-m[t]=n}}return x},"call$6","cL",12,0,null,245,246,247,248,249,250],
+m[t]=n}}return x},"call$6","cL",12,0,null,240,[],241,[],242,[],243,[],244,[],245,[]],
 Mw:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
 z=a.length
 y=z-1
@@ -19273,10 +19710,10 @@
 v=p
 y=w}else{u.push(2)
 v=o
-x=s}}}return H.VM(new H.iK(u),[null]).br(0)},"call$1","fZ",2,0,null,251],
+x=s}}}return H.VM(new H.iK(u),[null]).br(0)},"call$1","fZ",2,0,null,246,[]],
 rB:[function(a,b,c){var z,y,x
 for(z=J.U6(a),y=J.U6(b),x=0;x<c;++x)if(!J.de(z.t(a,x),y.t(b,x)))return x
-return c},"call$3","UF",6,0,null,252,253,254],
+return c},"call$3","UF",6,0,null,247,[],248,[],249,[]],
 xU:[function(a,b,c){var z,y,x,w,v,u
 z=J.U6(a)
 y=z.gB(a)
@@ -19287,7 +19724,7 @@
 u=z.t(a,y)
 w=J.xH(w,1)
 u=J.de(u,x.t(b,w))}else u=!1
-if(!u)break;++v}return v},"call$3","M9",6,0,null,252,253,254],
+if(!u)break;++v}return v},"call$3","M9",6,0,null,247,[],248,[],249,[]],
 jj:[function(a,b,c,d,e,f){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=J.Wx(c)
 y=J.Wx(f)
@@ -19337,7 +19774,7 @@
 s=new G.DA(a,y,t,n,0)}J.bi(s.Il,z.t(d,o));++o
 break
 default:}if(s!=null)p.push(s)
-return p},"call$6","Lr",12,0,null,245,246,247,248,249,250],
+return p},"call$6","Lr",12,0,null,240,[],241,[],242,[],243,[],244,[],245,[]],
 m1:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
 z=b.gWA()
 y=J.zj(b)
@@ -19355,8 +19792,7 @@
 y=J.WB(z,J.q8(u.ok.G4))
 x=q.jr
 p=P.J(y,J.WB(x,q.dM))-P.y(z,x)
-if(p>=0){if(r>=a.length)H.vh(new P.bJ("value "+r))
-a.splice(r,1)[0];--r
+if(p>=0){C.Nm.KI(a,r);--r
 z=J.xH(q.dM,J.q8(q.ok.G4))
 if(typeof z!=="number")return H.s(z)
 s-=z
@@ -19377,23 +19813,23 @@
 q.jr=J.WB(q.jr,m)
 if(typeof m!=="number")return H.s(m)
 s+=m
-t=!0}else t=!1}if(!t)a.push(u)},"call$2","c7",4,0,null,255,22],
-VT:[function(a,b){var z,y
+t=!0}else t=!1}if(!t)a.push(u)},"call$2","c7",4,0,null,250,[],22,[]],
+xl:[function(a,b){var z,y
 z=H.VM([],[G.DA])
 for(y=H.VM(new H.a7(b,b.length,0,null),[H.Kp(b,0)]);y.G();)G.m1(z,y.lo)
-return z},"call$2","um",4,0,null,68,256],
-n2:[function(a,b){var z,y,x,w,v,u
+return z},"call$2","bN",4,0,null,68,[],251,[]],
+u2:[function(a,b){var z,y,x,w,v,u
 if(b.length===1)return b
 z=[]
-for(y=G.VT(a,b),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=a.h3;y.G();){w=y.lo
+for(y=G.xl(a,b),y=H.VM(new H.a7(y,y.length,0,null),[H.Kp(y,0)]),x=a.h3;y.G();){w=y.lo
 if(J.de(w.gNg(),1)&&J.de(J.q8(w.gRt().G4),1)){v=J.i4(w.gRt().G4,0)
 u=J.zj(w)
 if(u>>>0!==u||u>=x.length)return H.e(x,u)
 if(!J.de(v,x[u]))z.push(w)
 continue}v=J.RE(w)
-C.Nm.FV(z,G.jj(a,v.gvH(w),J.WB(v.gvH(w),w.gNg()),w.gIl(),0,J.q8(w.gRt().G4)))}return z},"call$2","Pd",4,0,null,68,256],
+C.Nm.FV(z,G.jj(a,v.gvH(w),J.WB(v.gvH(w),w.gNg()),w.gIl(),0,J.q8(w.gRt().G4)))}return z},"call$2","SI",4,0,null,68,[],251,[]],
 DA:{
-"":"a;WA<,ok,Il<,jr,dM",
+"^":"a;WA<,ok,Il<,jr,dM",
 gvH:function(a){return this.jr},
 gRt:function(){return this.ok},
 gNg:function(){return this.dM},
@@ -19404,7 +19840,7 @@
 if(!J.de(this.dM,J.q8(this.ok.G4)))return!0
 z=J.WB(this.jr,this.dM)
 if(typeof z!=="number")return H.s(z)
-return a<z},"call$1","gw9",2,0,null,42],
+return a<z},"call$1","gcW",2,0,null,42,[]],
 bu:[function(a){return"#<ListChangeRecord index: "+H.d(this.jr)+", removed: "+H.d(this.ok)+", addedCount: "+H.d(this.dM)+">"},"call$0","gXo",0,0,null],
 $isDA:true,
 static:{XM:function(a,b,c,d){var z
@@ -19413,46 +19849,46 @@
 z=new P.Yp(d)
 z.$builtinTypeInfo=[null]
 return new G.DA(a,z,d,b,c)}}}}],["observe.src.metadata","package:observe/src/metadata.dart",,K,{
-"":"",
+"^":"",
 nd:{
-"":"a;"},
+"^":"a;"},
 vly:{
-"":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{
-"":"",
+"^":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{
+"^":"",
 Wi:[function(a,b,c,d){var z=J.RE(a)
 if(z.gUV(a)&&!J.de(c,d))z.nq(a,H.VM(new T.qI(a,b,c,d),[null]))
-return d},"call$4","Ha",8,0,null,93,257,231,232],
+return d},"call$4","Ha",8,0,null,93,[],252,[],225,[],226,[]],
 d3:{
-"":"a;",
+"^":"a;",
 $isd3:true},
-X6:{
-"":"Tp:349;a,b",
+lS:{
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z,y,x,w,v
 z=this.b
-y=z.wv.rN(a).Ax
+y=z.wv.rN(a).gAx()
 if(!J.de(b,y)){x=this.a
 w=x.a
 if(w==null){v=[]
 x.a=v
 x=v}else x=w
 x.push(H.VM(new T.qI(z,a,b,y),[null]))
-z.V2.u(0,a,y)}},"call$2",null,4,0,null,12,231,"call"],
+z.V2.u(0,a,y)}},"call$2",null,4,0,null,12,[],225,[],"call"],
 $isEH:true}}],["observe.src.observable_box","package:observe/src/observable_box.dart",,A,{
-"":"",
+"^":"",
 xh:{
-"":"Pi;L1,AP,fn",
-gP:[function(a){return this.L1},null,null,1,0,function(){return H.IG(function(a){return{func:"Oy",ret:a}},this.$receiver,"xh")},"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
-sP:[function(a,b){this.L1=F.Wi(this,C.ls,this.L1,b)},null,null,3,0,function(){return H.IG(function(a){return{func:"qyi",void:true,args:[a]}},this.$receiver,"xh")},232,"value",359],
+"^":"Pi;L1,AP,fn",
+gP:[function(a){return this.L1},null,null,1,0,function(){return H.IG(function(a){return{func:"Oy",ret:a}},this.$receiver,"xh")},"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
+sP:[function(a,b){this.L1=F.Wi(this,C.ls,this.L1,b)},null,null,3,0,function(){return H.IG(function(a){return{func:"lU6",void:true,args:[a]}},this.$receiver,"xh")},226,[],"value",351],
 bu:[function(a){return"#<"+H.d(new H.cu(H.dJ(this),null))+" value: "+H.d(this.L1)+">"},"call$0","gXo",0,0,null]}}],["observe.src.observable_list","package:observe/src/observable_list.dart",,Q,{
-"":"",
+"^":"",
 wn:{
-"":"uF;b3,xg,h3,AP,fn",
+"^":"Ay;b3,xg,h3,AP,fn",
 gvp:function(){var z=this.xg
-if(z==null){z=P.bK(new Q.cj(this),null,!0,null)
+if(z==null){z=P.bK(new Q.Bj(this),null,!0,null)
 this.xg=z}z.toString
 return H.VM(new P.Ik(z),[H.Kp(z,0)])},
-gB:[function(a){return this.h3.length},null,null,1,0,478,"length",359],
+gB:[function(a){return this.h3.length},null,null,1,0,482,"length",351],
 sB:[function(a,b){var z,y,x,w,v,u
 z=this.h3
 y=z.length
@@ -19480,10 +19916,10 @@
 u=[]
 w=new P.Yp(u)
 w.$builtinTypeInfo=[null]
-this.iH(new G.DA(this,w,u,y,x))}C.Nm.sB(z,b)},null,null,3,0,390,23,"length",359],
+this.iH(new G.DA(this,w,u,y,x))}C.Nm.sB(z,b)},null,null,3,0,385,23,[],"length",351],
 t:[function(a,b){var z=this.h3
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
-return z[b]},"call$1","gIA",2,0,function(){return H.IG(function(a){return{func:"Zg",ret:a,args:[J.im]}},this.$receiver,"wn")},47,"[]",359],
+return z[b]},"call$1","gIA",2,0,function(){return H.IG(function(a){return{func:"Zg",ret:a,args:[J.im]}},this.$receiver,"wn")},47,[],"[]",351],
 u:[function(a,b,c){var z,y,x,w
 z=this.h3
 if(b>>>0!==b||b>=z.length)return H.e(z,b)
@@ -19495,75 +19931,98 @@
 w=new P.Yp(x)
 w.$builtinTypeInfo=[null]
 this.iH(new G.DA(this,w,x,b,1))}if(b>=z.length)return H.e(z,b)
-z[b]=c},"call$2","gj3",4,0,function(){return H.IG(function(a){return{func:"GX",void:true,args:[J.im,a]}},this.$receiver,"wn")},47,23,"[]=",359],
-gl0:[function(a){return P.lD.prototype.gl0.call(this,this)},null,null,1,0,373,"isEmpty",359],
-gor:[function(a){return P.lD.prototype.gor.call(this,this)},null,null,1,0,373,"isNotEmpty",359],
+z[b]=c},"call$2","gj3",4,0,function(){return H.IG(function(a){return{func:"UR",void:true,args:[J.im,a]}},this.$receiver,"wn")},47,[],23,[],"[]=",351],
+gl0:[function(a){return P.lD.prototype.gl0.call(this,this)},null,null,1,0,366,"isEmpty",351],
+gor:[function(a){return P.lD.prototype.gor.call(this,this)},null,null,1,0,366,"isNotEmpty",351],
 h:[function(a,b){var z,y,x,w
 z=this.h3
 y=z.length
-this.Fg(y,y+1)
+this.nU(y,y+1)
 x=this.xg
 if(x!=null){w=x.iE
 x=w==null?x!=null:w!==x}else x=!1
 if(x)this.iH(G.XM(this,y,1,null))
-C.Nm.h(z,b)},"call$1","ght",2,0,null,23],
+C.Nm.h(z,b)},"call$1","ght",2,0,null,23,[]],
 FV:[function(a,b){var z,y,x,w
 z=this.h3
 y=z.length
 C.Nm.FV(z,b)
-this.Fg(y,z.length)
+this.nU(y,z.length)
 x=z.length-y
 z=this.xg
 if(z!=null){w=z.iE
 z=w==null?z!=null:w!==z}else z=!1
-if(z&&x>0)this.iH(G.XM(this,y,x,null))},"call$1","gDY",2,0,null,109],
+if(z&&x>0)this.iH(G.XM(this,y,x,null))},"call$1","gDY",2,0,null,109,[]],
 Rz:[function(a,b){var z,y
 for(z=this.h3,y=0;y<z.length;++y)if(J.de(z[y],b)){this.UZ(0,y,y+1)
-return!0}return!1},"call$1","gRI",2,0,null,124],
-UZ:[function(a,b,c){var z,y,x,w,v,u
-if(b>this.h3.length)H.vh(P.TE(b,0,this.h3.length))
-z=c>=b
-if(c<b||c>this.h3.length)H.vh(P.TE(c,b,this.h3.length))
-y=c-b
-x=this.h3
-w=x.length
-v=w-y
-this.ct(this,C.Wn,w,v)
-u=w===0
-v=v===0
-this.ct(this,C.ai,u,v)
-this.ct(this,C.nZ,!u,!v)
-v=this.xg
-if(v!=null){u=v.iE
-v=u==null?v!=null:u!==v}else v=!1
-if(v&&y>0){if(b>x.length)H.vh(P.TE(b,0,x.length))
-if(c<b||c>x.length)H.vh(P.TE(c,b,x.length))
-z=new H.nH(x,b,c)
+return!0}return!1},"call$1","gRI",2,0,null,124,[]],
+UZ:[function(a,b,c){var z,y,x,w,v,u,t
+z=b>=0
+if(!z||b>this.h3.length)H.vh(P.TE(b,0,this.h3.length))
+y=c>=b
+if(!y||c>this.h3.length)H.vh(P.TE(c,b,this.h3.length))
+x=c-b
+w=this.h3
+v=w.length
+u=v-x
+this.ct(this,C.Wn,v,u)
+t=v===0
+u=u===0
+this.ct(this,C.ai,t,u)
+this.ct(this,C.nZ,!t,!u)
+u=this.xg
+if(u!=null){t=u.iE
+u=t==null?u!=null:t!==u}else u=!1
+if(u&&x>0){if(!z||b>w.length)H.vh(P.TE(b,0,w.length))
+if(!y||c>w.length)H.vh(P.TE(c,b,w.length))
+z=new H.nH(w,b,c)
 z.$builtinTypeInfo=[null]
 if(b<0)H.vh(new P.bJ("value "+b))
 if(c<0)H.vh(new P.bJ("value "+c))
 if(b>c)H.vh(P.TE(b,0,c))
 z=z.br(0)
-v=new P.Yp(z)
-v.$builtinTypeInfo=[null]
-this.iH(new G.DA(this,v,z,b,0))}C.Nm.UZ(x,b,c)},"call$2","gYH",4,0,null,115,116],
+y=new P.Yp(z)
+y.$builtinTypeInfo=[null]
+this.iH(new G.DA(this,y,z,b,0))}C.Nm.UZ(w,b,c)},"call$2","gYH",4,0,null,115,[],116,[]],
+xe:[function(a,b,c){var z,y,x
+if(b<0||b>this.h3.length)throw H.b(P.TE(b,0,this.h3.length))
+z=this.h3
+y=z.length
+if(b===y){this.h(0,c)
+return}C.Nm.sB(z,y+1)
+y=z.length
+H.Og(z,b+1,y,this,b)
+y=z.length
+this.nU(y-1,y)
+y=this.xg
+if(y!=null){x=y.iE
+y=x==null?y!=null:x!==y}else y=!1
+if(y)this.iH(G.XM(this,b,1,null))
+if(b<0||b>=z.length)return H.e(z,b)
+z[b]=c},"call$2","gQG",4,0,null,47,[],124,[]],
+KI:[function(a,b){var z,y
+z=this.h3
+if(b<0||b>=z.length)return H.e(z,b)
+y=z[b]
+this.UZ(0,b,b+1)
+return y},"call$1","gNM",2,0,null,47,[]],
 iH:[function(a){var z,y
 z=this.xg
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)return
 if(this.b3==null){this.b3=[]
-P.rb(this.gL6())}this.b3.push(a)},"call$1","gSi",2,0,null,22],
-Fg:[function(a,b){var z,y
+P.rb(this.gL6())}this.b3.push(a)},"call$1","gSi",2,0,null,22,[]],
+nU:[function(a,b){var z,y
 this.ct(this,C.Wn,a,b)
 z=a===0
 y=J.x(b)
 this.ct(this,C.ai,z,y.n(b,0))
-this.ct(this,C.nZ,!z,!y.n(b,0))},"call$2","gdX",4,0,null,231,232],
+this.ct(this,C.nZ,!z,!y.n(b,0))},"call$2","gdX",4,0,null,225,[],226,[]],
 cv:[function(){var z,y,x
 z=this.b3
 if(z==null)return!1
-y=G.n2(this,z)
+y=G.u2(this,z)
 this.b3=null
 z=this.xg
 if(z!=null){x=z.iE
@@ -19571,40 +20030,40 @@
 if(x){x=H.VM(new P.Yp(y),[G.DA])
 if(z.Gv>=4)H.vh(z.q7())
 z.Iv(x)
-return!0}return!1},"call$0","gL6",0,0,373],
+return!0}return!1},"call$0","gL6",0,0,366],
 $iswn:true,
 static:{uX:function(a,b){var z=H.VM([],[b])
 return H.VM(new Q.wn(null,null,z,null,null),[b])}}},
-uF:{
-"":"ar+Pi;",
+Ay:{
+"^":"ar+Pi;",
 $isd3:true},
-cj:{
-"":"Tp:108;a",
+Bj:{
+"^":"Tp:108;a",
 call$0:[function(){this.a.xg=null},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["observe.src.observable_map","package:observe/src/observable_map.dart",,V,{
-"":"",
+"^":"",
 HA:{
-"":"z2;G3>,jL>,zZ>,JD,dr",
+"^":"z2;G3>,jL>,zZ>,JD,dr",
 bu:[function(a){var z
 if(this.JD)z="insert"
 else z=this.dr?"remove":"set"
 return"#<MapChangeRecord "+z+" "+H.d(this.G3)+" from: "+H.d(this.jL)+" to: "+H.d(this.zZ)+">"},"call$0","gXo",0,0,null],
 $isHA:true},
 qC:{
-"":"Pi;Zp,AP,fn",
+"^":"Pi;Zp,AP,fn",
 gvc:[function(a){var z=this.Zp
-return z.gvc(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"pD",ret:[P.cX,a]}},this.$receiver,"qC")},"keys",359],
+return z.gvc(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"pD",ret:[P.cX,a]}},this.$receiver,"qC")},"keys",351],
 gUQ:[function(a){var z=this.Zp
-return z.gUQ(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"NE",ret:[P.cX,b]}},this.$receiver,"qC")},"values",359],
+return z.gUQ(z)},null,null,1,0,function(){return H.IG(function(a,b){return{func:"NE",ret:[P.cX,b]}},this.$receiver,"qC")},"values",351],
 gB:[function(a){var z=this.Zp
-return z.gB(z)},null,null,1,0,478,"length",359],
+return z.gB(z)},null,null,1,0,482,"length",351],
 gl0:[function(a){var z=this.Zp
-return z.gB(z)===0},null,null,1,0,373,"isEmpty",359],
+return z.gB(z)===0},null,null,1,0,366,"isEmpty",351],
 gor:[function(a){var z=this.Zp
-return z.gB(z)!==0},null,null,1,0,373,"isNotEmpty",359],
-di:[function(a){return this.Zp.di(a)},"call$1","gmc",2,0,556,23,"containsValue",359],
-x4:[function(a){return this.Zp.x4(a)},"call$1","gV9",2,0,556,42,"containsKey",359],
-t:[function(a,b){return this.Zp.t(0,b)},"call$1","gIA",2,0,function(){return H.IG(function(a,b){return{func:"JB",ret:b,args:[P.a]}},this.$receiver,"qC")},42,"[]",359],
+return z.gB(z)!==0},null,null,1,0,366,"isNotEmpty",351],
+di:[function(a){return this.Zp.di(a)},"call$1","gmc",2,0,557,23,[],"containsValue",351],
+x4:[function(a){return this.Zp.x4(a)},"call$1","gV9",2,0,557,42,[],"containsKey",351],
+t:[function(a,b){return this.Zp.t(0,b)},"call$1","gIA",2,0,function(){return H.IG(function(a,b){return{func:"JB",ret:b,args:[P.a]}},this.$receiver,"qC")},42,[],"[]",351],
 u:[function(a,b,c){var z,y,x,w,v
 z=this.Zp
 y=z.gB(z)
@@ -19614,15 +20073,9 @@
 if(w!=null){v=w.iE
 w=v==null?w!=null:v!==w}else w=!1
 if(w){z=z.gB(z)
-w=y!==z
-if(w){if(this.gUV(this)&&w){z=new T.qI(this,C.Wn,y,z)
-z.$builtinTypeInfo=[null]
-this.nq(this,z)}z=new V.HA(b,null,c,!0,!1)
-z.$builtinTypeInfo=[null,null]
-this.nq(this,z)}else if(!J.de(x,c)){z=new V.HA(b,x,c,!1,!1)
-z.$builtinTypeInfo=[null,null]
-this.nq(this,z)}}},"call$2","gj3",4,0,function(){return H.IG(function(a,b){return{func:"fK",void:true,args:[a,b]}},this.$receiver,"qC")},42,23,"[]=",359],
-FV:[function(a,b){J.kH(b,new V.zT(this))},"call$1","gDY",2,0,null,104],
+if(y!==z){F.Wi(this,C.Wn,y,z)
+this.nq(this,H.VM(new V.HA(b,null,c,!0,!1),[null,null]))}else if(!J.de(x,c))this.nq(this,H.VM(new V.HA(b,x,c,!1,!1),[null,null]))}},"call$2","gj3",4,0,function(){return H.IG(function(a,b){return{func:"fK",void:true,args:[a,b]}},this.$receiver,"qC")},42,[],23,[],"[]=",351],
+FV:[function(a,b){J.kH(b,new V.zT(this))},"call$1","gDY",2,0,null,104,[]],
 Rz:[function(a,b){var z,y,x,w,v
 z=this.Zp
 y=z.gB(z)
@@ -19631,7 +20084,7 @@
 if(w!=null){v=w.iE
 w=v==null?w!=null:v!==w}else w=!1
 if(w&&y!==z.gB(z)){this.nq(this,H.VM(new V.HA(b,x,null,!1,!0),[null,null]))
-F.Wi(this,C.Wn,y,z.gB(z))}return x},"call$1","gRI",2,0,null,42],
+F.Wi(this,C.Wn,y,z.gB(z))}return x},"call$1","gRI",2,0,null,42,[]],
 V1:[function(a){var z,y,x,w
 z=this.Zp
 y=z.gB(z)
@@ -19640,7 +20093,7 @@
 x=w==null?x!=null:w!==x}else x=!1
 if(x&&y>0){z.aN(0,new V.Lo(this))
 F.Wi(this,C.Wn,y,0)}z.V1(0)},"call$0","gyP",0,0,null],
-aN:[function(a,b){return this.Zp.aN(0,b)},"call$1","gjw",2,0,null,110],
+aN:[function(a,b){return this.Zp.aN(0,b)},"call$1","gjw",2,0,null,110,[]],
 bu:[function(a){return P.vW(this)},"call$0","gXo",0,0,null],
 $isZ0:true,
 static:{WF:function(a,b,c){var z=V.Bq(a,b,c)
@@ -19651,21 +20104,21 @@
 else y=typeof a==="object"&&a!==null&&!!z.$isFo?H.VM(new V.qC(P.L5(null,null,null,b,c),null,null),[b,c]):H.VM(new V.qC(P.Py(null,null,null,b,c),null,null),[b,c])
 return y}}},
 zT:{
-"":"Tp;a",
-call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,23,"call"],
+"^":"Tp;a",
+call$2:[function(a,b){this.a.u(0,a,b)},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a,b){return{func:"vPt",args:[a,b]}},this.a,"qC")}},
 Lo:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=this.a
-z.nq(z,H.VM(new V.HA(a,b,null,!1,!0),[null,null]))},"call$2",null,4,0,null,42,23,"call"],
+z.nq(z,H.VM(new V.HA(a,b,null,!1,!0),[null,null]))},"call$2",null,4,0,null,42,[],23,[],"call"],
 $isEH:true}}],["observe.src.path_observer","package:observe/src/path_observer.dart",,L,{
-"":"",
+"^":"",
 Wa:[function(a,b){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isqI)return J.de(a.oc,b)
 if(typeof a==="object"&&a!==null&&!!z.$isHA){z=J.RE(b)
 if(typeof b==="object"&&b!==null&&!!z.$iswv)b=z.gfN(b)
-return J.de(a.G3,b)}return!1},"call$2","mD",4,0,null,22,42],
+return J.de(a.G3,b)}return!1},"call$2","mD",4,0,null,22,[],42,[]],
 yf:[function(a,b){var z,y,x,w,v
 if(a==null)return
 x=b
@@ -19675,14 +20128,13 @@
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$iswv){z=H.vn(a)
 y=H.jO(J.bB(z.gAx()).LU)
-try{if(L.My(y,b)){x=b
-x=z.tu(x,1,J.GL(x),[])
-return x.Ax}if(L.iN(y,C.fz)){x=J.UQ(a,J.GL(b))
+try{if(L.TH(y,b)){x=z.rN(b).gAx()
+return x}if(L.M6(y,C.fz)){x=J.UQ(a,J.GL(b))
 return x}}catch(v){x=H.Ru(v)
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.iN(y,C.OV))throw v}else throw v}}}x=$.aT()
-if(x.mL(C.Ab))x.x9("can't get "+H.d(b)+" in "+H.d(a))
-return},"call$2","MT",4,0,null,6,66],
+if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.M6(y,C.OV))throw v}else throw v}}}x=$.aT()
+if(x.Im(C.Ab))x.x9("can't get "+H.d(b)+" in "+H.d(a))
+return},"call$2","MT",4,0,null,6,[],66,[]],
 h6:[function(a,b,c){var z,y,x,w,v
 if(a==null)return!1
 x=b
@@ -19693,19 +20145,19 @@
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$iswv){z=H.vn(a)
 y=H.jO(J.bB(z.gAx()).LU)
-try{if(L.hg(y,b)){z.PU(b,c)
-return!0}if(L.iN(y,C.eC)){J.kW(a,J.GL(b),c)
+try{if(L.dR(y,b)){z.PU(b,c)
+return!0}if(L.M6(y,C.eC)){J.kW(a,J.GL(b),c)
 return!0}}catch(v){x=H.Ru(v)
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.iN(y,C.OV))throw v}else throw v}}}x=$.aT()
-if(x.mL(C.Ab))x.x9("can't set "+H.d(b)+" in "+H.d(a))
-return!1},"call$3","nV",6,0,null,6,66,23],
-My:[function(a,b){var z
+if(typeof x==="object"&&x!==null&&!!w.$ismp){if(!L.M6(y,C.OV))throw v}else throw v}}}x=$.aT()
+if(x.Im(C.Ab))x.x9("can't set "+H.d(b)+" in "+H.d(a))
+return!1},"call$3","nV",6,0,null,6,[],66,[],23,[]],
+TH:[function(a,b){var z
 for(;!J.de(a,$.aA());){z=a.gYK().nb
 if(z.x4(b))return!0
 if(z.x4(C.OV))return!0
-a=L.pY(a)}return!1},"call$2","If",4,0,null,11,12],
-hg:[function(a,b){var z,y,x,w
+a=L.pY(a)}return!1},"call$2","fY",4,0,null,11,[],12,[]],
+dR:[function(a,b){var z,y,x,w
 z=new H.GD(H.le(H.d(b.gfN(b))+"="))
 for(;!J.de(a,$.aA());){y=a.gYK().nb
 x=y.t(0,b)
@@ -19713,23 +20165,23 @@
 if(typeof x==="object"&&x!==null&&!!w.$isRY)return!0
 if(y.x4(z))return!0
 if(y.x4(C.OV))return!0
-a=L.pY(a)}return!1},"call$2","Qd",4,0,null,11,12],
-iN:[function(a,b){var z,y
+a=L.pY(a)}return!1},"call$2","Jh",4,0,null,11,[],12,[]],
+M6:[function(a,b){var z,y
 for(;!J.de(a,$.aA());){z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS&&z.guU())return!0
-a=L.pY(a)}return!1},"call$2","iS",4,0,null,11,12],
+a=L.pY(a)}return!1},"call$2","SU",4,0,null,11,[],12,[]],
 pY:[function(a){var z,y
 try{z=a.gAY()
 return z}catch(y){H.Ru(y)
-return $.aA()}},"call$1","WV",2,0,null,11],
+return $.aA()}},"call$1","WV",2,0,null,11,[]],
 rd:[function(a){a=J.JA(a,$.c3(),"")
 if(a==="")return!0
 if(0>=a.length)return H.e(a,0)
 if(a[0]===".")return!1
-return $.tN().zD(a)},"call$1","QO",2,0,null,86],
+return $.tN().zD(a)},"call$1","KL",2,0,null,86,[]],
 WR:{
-"":"Pi;ay,YB,BK,kN,cs,cT,AP,fn",
+"^":"Pi;ay,YB,BK,kN,cs,cT,AP,fn",
 E4:function(a){return this.cT.call$1(a)},
 gWA:function(){var z=this.kN
 if(0>=z.length)return H.e(z,0)
@@ -19740,8 +20192,8 @@
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)this.ov()
-return C.Nm.grZ(this.kN)},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+return C.Nm.grZ(this.kN)},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:[function(a,b){var z,y,x,w
 z=this.BK
 y=z.length
@@ -19757,7 +20209,7 @@
 if(w>=z.length)return H.e(z,w)
 if(L.h6(x,z[w],b)){z=this.kN
 if(y>=z.length)return H.e(z,y)
-z[y]=b}},null,null,3,0,452,232,"value",359],
+z[y]=b}},null,null,3,0,446,226,[],"value",351],
 k0:[function(a){O.Pi.prototype.k0.call(this,this)
 this.ov()
 this.XI()},"call$0","gqw",0,0,107],
@@ -19782,7 +20234,7 @@
 if(w===y&&x)u=this.E4(u)
 v=this.kN;++w
 if(w>=v.length)return H.e(v,w)
-v[w]=u}},function(){return this.Zy(null)},"ov","call$1$end",null,"gFD",0,3,null,77,116],
+v[w]=u}},function(){return this.Zy(null)},"ov","call$1$end",null,"gFD",0,3,null,77,116,[]],
 hd:[function(a){var z,y,x,w,v,u,t,s,r
 for(z=this.BK,y=z.length-1,x=this.cT!=null,w=a,v=null,u=null;w<=y;w=s){t=this.kN
 s=w+1
@@ -19800,7 +20252,7 @@
 t[s]=u}this.ij(a)
 if(this.gUV(this)&&!J.de(v,u)){z=new T.qI(this,C.ls,v,u)
 z.$builtinTypeInfo=[null]
-this.nq(this,z)}},"call$1$start","gWx",0,3,null,336,115],
+this.nq(this,z)}},"call$1$start","gWx",0,3,null,330,115,[]],
 Rl:[function(a,b){var z,y
 if(b==null)b=this.BK.length
 if(typeof b!=="number")return H.s(b)
@@ -19809,7 +20261,7 @@
 if(z>=y.length)return H.e(y,z)
 y=y[z]
 if(y!=null)y.ed()
-this.Kh(z)}},function(){return this.Rl(0,null)},"XI",function(a){return this.Rl(a,null)},"ij","call$2",null,null,"gmi",0,4,null,336,77,115,116],
+this.Kh(z)}},function(){return this.Rl(0,null)},"XI",function(a){return this.Rl(a,null)},"ij","call$2",null,null,"gmi",0,4,null,330,77,115,[],116,[]],
 Kh:[function(a){var z,y,x,w,v
 z=this.kN
 if(a>=z.length)return H.e(z,a)
@@ -19833,7 +20285,7 @@
 w.o7=P.VH(P.AY(),z)
 w.Bd=z.Al(P.v3())
 if(a>=v.length)return H.e(v,a)
-v[a]=w}}},"call$1","gCf",2,0,null,341],
+v[a]=w}}},"call$1","gCf",2,0,null,383,[]],
 d4:function(a,b,c){var z,y,x,w
 if(this.YB)for(z=J.rr(b).split("."),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]),y=this.BK;z.G();){x=z.lo
 if(J.de(x,""))continue
@@ -19850,26 +20302,26 @@
 z.d4(a,b,c)
 return z}}},
 qL:{
-"":"Tp:229;",
-call$1:[function(a){return},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Px:{
-"":"Tp:557;a,b,c",
+"^":"Tp:558;a,b,c",
 call$1:[function(a){var z,y
 for(z=J.GP(a),y=this.c;z.G();)if(z.gl().ck(y)){this.a.hd(this.b)
-return}},"call$1",null,2,0,null,256,"call"],
+return}},"call$1",null,2,0,null,251,[],"call"],
 $isEH:true},
 C4:{
-"":"Tp:558;d,e,f",
+"^":"Tp:559;d,e,f",
 call$1:[function(a){var z,y
 for(z=J.GP(a),y=this.f;z.G();)if(L.Wa(z.gl(),y)){this.d.hd(this.e)
-return}},"call$1",null,2,0,null,256,"call"],
+return}},"call$1",null,2,0,null,251,[],"call"],
 $isEH:true},
 Md:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return new H.VR(H.v4("^(?:(?:[$_a-zA-Z]+[$_a-zA-Z0-9]*|(?:[0-9]|[1-9]+[0-9]+)))(?:\\.(?:[$_a-zA-Z]+[$_a-zA-Z0-9]*|(?:[0-9]|[1-9]+[0-9]+)))*$",!1,!0,!1),null,null)},"call$0",null,0,0,null,"call"],
 $isEH:true}}],["observe.src.to_observable","package:observe/src/to_observable.dart",,R,{
-"":"",
+"^":"",
 Jk:[function(a){var z,y,x
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isd3)return a
@@ -19878,190 +20330,12 @@
 return y}if(typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)){z=z.ez(a,R.np())
 x=Q.uX(null,null)
 x.FV(0,z)
-return x}return a},"call$1","np",2,0,229,23],
+return x}return a},"call$1","np",2,0,223,23,[]],
 km:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,R.Jk(a),R.Jk(b))},"call$2",null,4,0,null,421,277,"call"],
-$isEH:true}}],["path","package:path/path.dart",,B,{
-"":"",
-ab:function(){var z,y,x,w
-z=P.uo()
-y=$.Ur()
-x=$.wE()
-if(y==null?x==null:y===x)return z.mS(P.r6($.cO().ej("."))).bu(0)
-else{w=z.t4()
-return C.xB.Nj(w,0,w.length-1)}},
-"":"As<"}],["path.context","package:path/src/context.dart",,F,{
-"":"",
-YF:[function(a,b){var z,y,x,w,v,u
-for(z=1;z<8;++z){if(b[z]==null||b[z-1]!=null)continue
-for(y=8;y>=1;y=x){x=y-1
-if(b[x]!=null)break}w=new P.Rn("")
-w.vM=""
-v=a+"("
-v=""+v
-w.vM=v
-u=new H.nH(b,0,y)
-u.$builtinTypeInfo=[null]
-if(y<0)H.vh(new P.bJ("value "+y))
-if(0>y)H.vh(P.TE(0,0,y))
-u=new H.A8(u,new F.No())
-u.$builtinTypeInfo=[null,null]
-u=u.zV(0,", ")
-v+=u
-w.vM=v
-u="): part "+(z-1)+" was null, but part "+z+" was not."
-v+=u
-w.vM=v
-throw H.b(new P.AT(v))}},"call$2","nE",4,0,null,221,258],
-lI:{
-"":"a;S,l",
-tM:[function(a){var z,y,x
-z=Q.lo(a,this.S)
-z.IV()
-y=z.wZ
-x=y.length
-if(x===0){y=z.SF
-return y==null?".":y}if(x===1){y=z.SF
-return y==null?".":y}C.Nm.mv(y)
-y=z.ZB
-if(0>=y.length)return H.e(y,0)
-y.pop()
-z.IV()
-return z.bu(0)},"call$1","gP5",2,0,null,266],
-C8:[function(a,b,c,d,e,f,g,h,i){var z=[b,c,d,e,f,g,h,i]
-F.YF("join",z)
-return this.IP(H.VM(new H.U5(z,new F.u2()),[null]))},function(a,b,c){return this.C8(a,b,c,null,null,null,null,null,null)},"tX","call$8",null,"gnr",2,14,null,77,77,77,77,77,77,77,559,560,561,562,563,564,565,566],
-IP:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o
-z=P.p9("")
-for(y=H.VM(new H.U5(a,new F.q7()),[H.ip(a,"mW",0)]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=this.S,w=y.OI,v=!1,u=!1;y.G();){t=w.gl()
-if(Q.lo(t,x).aA&&u){s=Q.lo(t,x)
-r=Q.lo(z.vM,x).SF
-q=r==null?"":r
-s.SF=q
-if(J.kE(q,x.gnK())===!0){q=s.ZB
-p=x.gmI()
-if(0>=q.length)return H.e(q,0)
-q[0]=p}z.vM=""
-q=s.bu(0)
-z.vM=z.vM+q}else if(Q.lo(t,x).SF!=null){u=!Q.lo(t,x).aA
-z.vM=""
-o=typeof t==="string"?t:H.d(t)
-z.vM=z.vM+o}else{q=J.U6(t)
-if(J.z8(q.gB(t),0)&&J.kE(q.t(t,0),x.gDF())===!0);else if(v===!0){q=x.gmI()
-z.vM=z.vM+q}o=typeof t==="string"?t:H.d(t)
-z.vM=z.vM+o}v=J.kE(t,x.gnK())}return z.vM},"call$1","gl4",2,0,null,182],
-Fr:[function(a,b){var z,y,x
-z=Q.lo(b,this.S)
-y=H.VM(new H.U5(z.wZ,new F.Qt()),[null])
-y=P.F(y,!0,H.ip(y,"mW",0))
-z.wZ=y
-x=z.SF
-if(x!=null)C.Nm.xe(y,0,x)
-return z.wZ},"call$1","gOG",2,0,null,266]},
-u2:{
-"":"Tp:229;",
-call$1:[function(a){return a!=null},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-q7:{
-"":"Tp:229;",
-call$1:[function(a){return!J.de(a,"")},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-Qt:{
-"":"Tp:229;",
-call$1:[function(a){return J.FN(a)!==!0},"call$1",null,2,0,null,446,"call"],
-$isEH:true},
-No:{
-"":"Tp:229;",
-call$1:[function(a){return a==null?"null":"\""+H.d(a)+"\""},"call$1",null,2,0,null,165,"call"],
-$isEH:true}}],["path.parsed_path","package:path/src/parsed_path.dart",,Q,{
-"":"",
-v5:{
-"":"a;S,SF,aA,wZ,ZB",
-IV:[function(){var z,y
-z=this.ZB
-while(!0){y=this.wZ
-if(!(y.length!==0&&J.de(C.Nm.grZ(y),"")))break
-C.Nm.mv(this.wZ)
-if(0>=z.length)return H.e(z,0)
-z.pop()}y=z.length
-if(y>0)z[y-1]=""},"call$0","gio",0,0,null],
-bu:[function(a){var z,y,x,w,v
-z=P.p9("")
-y=this.SF
-if(y!=null)z.KF(y)
-for(y=this.ZB,x=0;x<this.wZ.length;++x){if(x>=y.length)return H.e(y,x)
-w=y[x]
-w=typeof w==="string"?w:H.d(w)
-z.vM=z.vM+w
-v=this.wZ
-if(x>=v.length)return H.e(v,x)
-w=v[x]
-w=typeof w==="string"?w:H.d(w)
-z.vM=z.vM+w}z.KF(C.Nm.grZ(y))
-return z.vM},"call$0","gXo",0,0,null],
-static:{lo:function(a,b){var z,y,x,w,v,u,t,s,r,q
-z=b.xZ(a)
-y=b.uP(a)
-if(z!=null)a=J.ZZ(a,J.q8(z))
-x=[]
-w=[]
-v=b.gDF()
-u=v.R4(0,a)
-if(u!=null){t=u.QK
-if(0>=t.length)return H.e(t,0)
-w.push(t[0])
-if(0>=t.length)return H.e(t,0)
-a=J.ZZ(a,J.q8(t[0]))}else w.push("")
-if(typeof a!=="string")H.vh(new P.AT(a))
-v=new H.Pb(v,a,null)
-t=J.U6(a)
-s=0
-for(;v.G();){r=v.Wh.QK
-x.push(t.Nj(a,s,r.index))
-if(0>=r.length)return H.e(r,0)
-w.push(r[0])
-q=r.index
-if(0>=r.length)return H.e(r,0)
-r=J.q8(r[0])
-if(typeof r!=="number")return H.s(r)
-s=q+r}v=t.gB(a)
-if(typeof v!=="number")return H.s(v)
-if(s<v){x.push(t.yn(a,s))
-w.push("")}return new Q.v5(b,z,y!=null,x,w)}}}}],["path.style","package:path/src/style.dart",,S,{
-"":"",
-Rh:[function(){if(!J.de(P.uo().Fi,"file"))return $.wE()
-if(!J.Eg(P.uo().r0,"/"))return $.wE()
-if(P.R6("","","a/b",null,0,null,null,null,"").t4()==="a\\b")return $.CE()
-return $.KL()},"call$0","RI",0,0,null],
-OO:{
-"":"a;TL<",
-xZ:[function(a){var z,y
-z=this.gEw()
-if(typeof a!=="string")H.vh(new P.AT(a))
-y=new H.KW(z,a)
-if(!y.gl0(y))return J.UQ(y.gtH(y),0)
-return this.uP(a)},"call$1","gye",2,0,null,266],
-uP:[function(a){var z,y
-z=this.gTL()
-if(z==null)return
-z.toString
-if(typeof a!=="string")H.vh(new P.AT(a))
-y=new H.KW(z,a)
-if(!y.gA(y).G())return
-return J.UQ(y.gtH(y),0)},"call$1","gvZ",2,0,null,266],
-bu:[function(a){return this.goc(this)},"call$0","gXo",0,0,null],
-static:{"":"aC<"}}}],["path.style.posix","package:path/src/style/posix.dart",,Z,{
-"":"",
-OF:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"}}],["path.style.url","package:path/src/style/url.dart",,E,{
-"":"",
-rM:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL:ir<,TL"}}],["path.style.windows","package:path/src/style/windows.dart",,T,{
-"":"",
-IV:{
-"":"OO;oc>,mI<,DF<,nK<,Ew<,TL:r9<,TL"}}],["polymer","package:polymer/polymer.dart",,A,{
-"":"",
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,R.Jk(a),R.Jk(b))},"call$2",null,4,0,null,417,[],272,[],"call"],
+$isEH:true}}],["polymer","package:polymer/polymer.dart",,A,{
+"^":"",
 JX:[function(){var z,y
 z=document.createElement("style",null)
 z.textContent=".polymer-veiled { opacity: 0; } \n.polymer-unveil{ -webkit-transition: opacity 0.3s; transition: opacity 0.3s; }\n"
@@ -20074,7 +20348,7 @@
 for(x=W.vD(document.querySelectorAll(y),null),x=x.gA(x);x.G();)J.pP(x.lo).h(0,"polymer-veiled")}},"call$0","r8",0,0,null],
 yV:[function(a){var z,y
 z=$.xY().Rz(0,a)
-if(z!=null)for(y=J.GP(z);y.G();)J.Or(y.gl())},"call$1","Km",2,0,null,12],
+if(z!=null)for(y=J.GP(z);y.G();)J.Or(y.gl())},"call$1","Km",2,0,null,12,[]],
 oF:[function(a,b){var z,y,x,w,v,u
 if(J.de(a,$.Tf()))return b
 b=A.oF(a.gAY(),b)
@@ -20086,18 +20360,18 @@
 if(w)for(w=J.GP(y.gc9());w.G();){v=w.lo.gAx()
 u=J.x(v)
 if(typeof v==="object"&&v!==null&&!!u.$isyL){if(typeof y!=="object"||y===null||!x.$isRS||A.bc(a,y)){if(b==null)b=H.B7([],P.L5(null,null,null,null,null))
-b.u(0,y.gIf(),y)}break}}}return b},"call$2","Sy",4,0,null,259,260],
+b.u(0,y.gIf(),y)}break}}}return b},"call$2","Cd",4,0,null,253,[],254,[]],
 Oy:[function(a,b){var z,y
 do{z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS&&z.glT()&&A.bc(a,z)||typeof z==="object"&&z!==null&&!!y.$isRY)return z
-a=a.gAY()}while(a!=null)
-return},"call$2","il",4,0,null,259,66],
+a=a.gAY()}while(!J.de(a,$.Tf()))
+return},"call$2","il",4,0,null,253,[],66,[]],
 bc:[function(a,b){var z,y
 z=H.le(H.d(b.gIf().fN)+"=")
 y=a.gYK().nb.t(0,new H.GD(z))
 z=J.x(y)
-return typeof y==="object"&&y!==null&&!!z.$isRS&&y.ghB()},"call$2","oS",4,0,null,259,261],
+return typeof y==="object"&&y!==null&&!!z.$isRS&&y.ghB()},"call$2","i8",4,0,null,253,[],255,[]],
 YG:[function(a,b,c){var z,y,x
 z=$.cM()
 if(z==null||a==null)return
@@ -20106,7 +20380,7 @@
 if(y==null)return
 x=J.UQ(y,"ShadowCSS")
 if(x==null)return
-x.V7("shimStyling",[a,b,c])},"call$3","OA",6,0,null,262,12,263],
+x.V7("shimStyling",[a,b,c])},"call$3","OA",6,0,null,256,[],12,[],257,[]],
 Hl:[function(a){var z,y,x,w,v,u,t
 if(a==null)return""
 w=J.RE(a)
@@ -20126,49 +20400,49 @@
 if(typeof w==="object"&&w!==null&&!!t.$isNh){y=w
 x=new H.XO(u,null)
 $.vM().J4("failed to get stylesheet text href=\""+H.d(z)+"\" error: "+H.d(y)+", trace: "+H.d(x))
-return""}else throw u}},"call$1","Js",2,0,null,264],
+return""}else throw u}},"call$1","Js",2,0,null,258,[]],
 Ad:[function(a,b){var z
 if(b==null)b=C.hG
 $.Ej().u(0,a,b)
 z=$.p2().Rz(0,a)
-if(z!=null)J.Or(z)},"call$2","ZK",2,2,null,77,12,11],
-zM:[function(a){A.Vx(a,new A.Mq())},"call$1","on",2,0,null,265],
+if(z!=null)J.Or(z)},"call$2","ZK",2,2,null,77,12,[],11,[]],
+zM:[function(a){A.Vx(a,new A.Mq())},"call$1","mo",2,0,null,259,[]],
 Vx:[function(a,b){var z
 if(a==null)return
 b.call$1(a)
-for(z=a.firstChild;z!=null;z=z.nextSibling)A.Vx(z,b)},"call$2","Dv",4,0,null,265,150],
+for(z=a.firstChild;z!=null;z=z.nextSibling)A.Vx(z,b)},"call$2","Dv",4,0,null,259,[],148,[]],
 lJ:[function(a,b,c,d){if(!J.co(b,"on-"))return d.call$3(a,b,c)
-return new A.L6(a,b)},"call$4","y4",8,0,null,266,12,265,267],
+return new A.L6(a,b)},"call$4","y4",8,0,null,260,[],12,[],259,[],261,[]],
 Hr:[function(a){var z
 for(;z=J.RE(a),z.gKV(a)!=null;)a=z.gKV(a)
-return $.od().t(0,a)},"call$1","Aa",2,0,null,265],
+return $.od().t(0,a)},"call$1","Fd",2,0,null,259,[]],
 HR:[function(a,b,c){var z,y,x
 z=H.vn(a)
 y=A.Rk(H.jO(J.bB(z.Ax).LU),b)
 if(y!=null){x=y.gMP()
 x=x.ev(x,new A.uJ())
-C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},"call$3","SU",6,0,null,41,268,258],
+C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},"call$3","xi",6,0,null,41,[],262,[],263,[]],
 Rk:[function(a,b){var z,y
 do{z=a.gYK().nb.t(0,b)
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isRS)return z
-a=a.gAY()}while(a!=null)},"call$2","Uy",4,0,null,11,12],
+a=a.gAY()}while(a!=null)},"call$2","Uy",4,0,null,11,[],12,[]],
 ZI:[function(a,b){var z,y
 if(a==null)return
 z=document.createElement("style",null)
 z.textContent=a.textContent
 y=a.getAttribute("element")
 if(y!=null)z.setAttribute("element",y)
-b.appendChild(z)},"call$2","tO",4,0,null,269,270],
+b.appendChild(z)},"call$2","tO",4,0,null,264,[],265,[]],
 pX:[function(){var z=window
 C.ol.hr(z)
 C.ol.oB(z,W.aF(new A.hm()))},"call$0","ji",0,0,null],
 al:[function(a,b){var z,y,x
 z=J.RE(b)
 y=typeof b==="object"&&b!==null&&!!z.$isRY?z.gt5(b):H.Go(b,"$isRS").gdw()
-if(J.de(y.gvd(),C.PU)||J.de(y.gvd(),C.nN))if(a!=null){x=A.h5(a)
+if(J.de(y.gUx(),C.PU)||J.de(y.gUx(),C.nN))if(a!=null){x=A.h5(a)
 if(x!=null)return P.re(x)
-return H.jO(J.bB(H.vn(a).Ax).LU)}return y},"call$2","mN",4,0,null,23,66],
+return H.jO(J.bB(H.vn(a).Ax).LU)}return y},"call$2","mN",4,0,null,23,[],66,[]],
 h5:[function(a){var z
 if(a==null)return C.Qf
 if(typeof a==="number"&&Math.floor(a)===a)return C.yw
@@ -20177,7 +20451,7 @@
 if(typeof a==="string")return C.Db
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isiP)return C.Yc
-return},"call$1","V9",2,0,null,23],
+return},"call$1","V9",2,0,null,23,[]],
 Ok:[function(){if($.uP){var z=$.X3.iT(O.Ht())
 z.Gr(A.PB())
 return z}A.ei()
@@ -20216,43 +20490,65 @@
 x=!0}else{z="warning: more than one Dart script tag in "+H.d(b)+". Dartium currently only allows a single Dart script tag per document."
 v=$.oK
 if(v==null)H.qw(z)
-else v.call$1(z)}}return d},"call$4","bX",4,4,null,77,77,271,272,273,274],
-pw:[function(a){var z,y,x,w,v,u,t,s,r,q,p
+else v.call$1(z)}}return d},"call$4","fE",4,4,null,77,77,266,[],267,[],268,[],269,[]],
+pw:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 z=$.RQ()
 z.toString
-y=$.cO()
-x=z.mS(P.r6(y.ej(a)))
-z=$.UG().nb
-w=z.t(0,x)
-v=x.r0
-u=$.rw()
-if(J.co(v,u)&&J.Eg(x.r0,".dart")){t=z.t(0,P.r6(y.ej("package:"+J.ZZ(x.r0,u.length))))
-if(t!=null)w=t}if(w==null){$.M7().To(H.d(x)+" library not found")
-return}z=w.gYK().nb
+y=$.qG()
+x=P.r6(y.ej(a))
+w=x.Fi
+if(!J.de(w,"")){v=x.ku
+u=x.gJf(x)
+t=x.gtp(x)
+s=z.SK(x.r0)
+r=x.tP}else{if(!J.de(x.gJf(x),"")){v=x.ku
+u=x.gJf(x)
+t=x.gtp(x)
+s=z.SK(x.r0)
+r=x.tP}else{if(J.de(x.r0,"")){s=z.r0
+r=x.tP
+r=!J.de(r,"")?r:z.tP}else{q=J.co(x.r0,"/")
+p=x.r0
+s=q?z.SK(p):z.SK(z.Ky(z.r0,p))
+r=x.tP}v=z.ku
+u=z.gJf(z)
+t=z.gtp(z)}w=z.Fi}o=P.R6(x.Ka,u,s,null,t,r,null,w,v)
+x=$.UG().nb
+n=x.t(0,o)
+m=o.r0
+if(J.de(o.Fi,z.Fi))if(o.gWu()===z.gWu()){z=J.rY(m)
+if(z.Tc(m,".dart"))z=z.tg(m,"/packages/")===!0||z.nC(m,"packages/")
+else z=!1}else z=!1
+else z=!1
+if(z){z=o.r0
+q=J.U6(z)
+l=x.t(0,P.r6(y.ej("package:"+q.yn(z,J.WB(q.cn(z,"packages/"),9)))))
+if(l!=null)n=l}if(n==null){$.M7().To(H.d(o)+" library not found")
+return}z=n.gYK().nb
 z=z.gUQ(z)
 y=new A.Fn()
-v=new H.U5(z,y)
-v.$builtinTypeInfo=[H.ip(z,"mW",0)]
+x=new H.U5(z,y)
+x.$builtinTypeInfo=[H.ip(z,"mW",0)]
 z=z.gA(z)
 y=new H.SO(z,y)
-y.$builtinTypeInfo=[H.Kp(v,0)]
-for(;y.G();)A.ZB(w,z.gl())
-z=w.gYK().nb
+y.$builtinTypeInfo=[H.Kp(x,0)]
+for(;y.G();)A.ZB(n,z.gl())
+z=n.gYK().nb
 z=z.gUQ(z)
 y=new A.e3()
-v=new H.U5(z,y)
-v.$builtinTypeInfo=[H.ip(z,"mW",0)]
+x=new H.U5(z,y)
+x.$builtinTypeInfo=[H.ip(z,"mW",0)]
 z=z.gA(z)
 y=new H.SO(z,y)
-y.$builtinTypeInfo=[H.Kp(v,0)]
-for(;y.G();){s=z.gl()
-for(v=J.GP(s.gc9());v.G();){r=v.lo.gAx()
-u=J.x(r)
-if(typeof r==="object"&&r!==null&&!!u.$isV3){u=r.ns
-q=s.gYj()
-$.Ej().u(0,u,q)
-p=$.p2().Rz(0,u)
-if(p!=null)J.Or(p)}}}},"call$1","Xz",2,0,null,275],
+y.$builtinTypeInfo=[H.Kp(x,0)]
+for(;y.G();){k=z.gl()
+for(x=J.GP(k.gc9());x.G();){j=x.lo.gAx()
+q=J.x(j)
+if(typeof j==="object"&&j!==null&&!!q.$isV3){q=j.ns
+p=k.gYj()
+$.Ej().u(0,q,p)
+i=$.p2().Rz(0,q)
+if(i!=null)J.Or(i)}}}},"call$1","Xz",2,0,null,270,[]],
 ZB:[function(a,b){var z,y,x
 for(z=J.GP(b.gc9());y=!1,z.G();)if(z.lo.gAx()===C.za){y=!0
 break}if(!y)return
@@ -20266,13 +20562,13 @@
 z=$.oK
 if(z==null)H.qw(x)
 else z.call$1(x)
-return}a.CI(b.gIf(),C.xD)},"call$2","K0",4,0,null,93,221],
+return}a.CI(b.gIf(),C.xD)},"call$2","K0n",4,0,null,93,[],215,[]],
 Zj:{
-"":"Tp:229;",
-call$1:[function(a){A.pX()},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){A.pX()},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 XP:{
-"":"qE;zx,kw,aa,RT,Q7=,NF=,hf=,xX=,cI,lD,Gd=,Ei",
+"^":"qE;zx,kw,aa,RT,Q7=,NF=,hf=,xX=,cI,lD,Gd=,Ei",
 gt5:function(a){return a.zx},
 gP1:function(a){return a.aa},
 goc:function(a){return a.RT},
@@ -20315,15 +20611,15 @@
 y0:[function(a,b){if($.Ej().t(0,b)!=null)return!1
 $.p2().u(0,b,a)
 if(a.hasAttribute("noscript")===!0)A.Ad(b,null)
-return!0},"call$1","go8",2,0,null,12],
+return!0},"call$1","gLD",2,0,null,12,[]],
 PM:[function(a,b){if(b!=null&&J.UU(b,"-")>=0)if(!$.cd().x4(b)){J.bi($.xY().to(b,new A.q6()),a)
-return!0}return!1},"call$1","gd7",2,0,null,263],
+return!0}return!1},"call$1","gmL",2,0,null,257,[]],
 Ba:[function(a,b){var z,y,x,w
 for(z=a,y=null;z!=null;){x=J.RE(z)
 y=x.gQg(z).MW.getAttribute("extends")
 z=x.gP1(z)}x=document
 w=a.zx
-W.wi(window,x,b,w,y)},"call$1","gr7",2,0,null,12],
+W.wi(window,x,b,w,y)},"call$1","gr7",2,0,null,12,[]],
 YU:[function(a,b,c){var z,y,x,w,v,u,t
 if(c!=null&&J.YP(c)!=null){z=J.YP(c)
 y=P.L5(null,null,null,null,null)
@@ -20345,14 +20641,14 @@
 if(typeof console!="undefined")console.warn(t)
 continue}y=a.Q7
 if(y==null){y=H.B7([],P.L5(null,null,null,null,null))
-a.Q7=y}y.u(0,v,u)}}},"call$2","gvQ",4,0,null,259,567],
+a.Q7=y}y.u(0,v,u)}}},"call$2","gvQ",4,0,null,253,[],560,[]],
 Vk:[function(a){var z,y
 z=P.L5(null,null,null,J.O,P.a)
 a.xX=z
 y=a.aa
 if(y!=null)z.FV(0,J.Ng(y))
 new W.i7(a).aN(0,new A.CK(a))},"call$0","gYi",0,0,null],
-W3:[function(a,b){new W.i7(a).aN(0,new A.LJ(b))},"call$1","gSX",2,0,null,568],
+W3:[function(a,b){new W.i7(a).aN(0,new A.LJ(b))},"call$1","gSX",2,0,null,561,[]],
 Mi:[function(a){var z=this.Hs(a,"[rel=stylesheet]")
 a.cI=z
 for(z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.QC(z.lo)},"call$0","gax",0,0,null],
@@ -20372,13 +20668,13 @@
 w.vM=t+"\n"}if(w.vM.length>0){z=document.createElement("style",null)
 z.textContent=H.d(w)
 v=J.RE(x)
-v.mK(x,z,v.gq6(x))}}},"call$0","gWT",0,0,null],
+v.mK(x,z,v.gq6(x))}}},"call$0","gysu",0,0,null],
 oP:[function(a,b,c){var z,y,x
 z=W.vD(a.querySelectorAll(b),null)
 y=z.br(z)
 x=this.gZf(a)
 if(x!=null)C.Nm.FV(y,J.pe(x,b))
-return y},function(a,b){return this.oP(a,b,null)},"Hs","call$2",null,"gKQ",2,2,null,77,457,569],
+return y},function(a,b){return this.oP(a,b,null)},"Hs","call$2",null,"gKQ",2,2,null,77,452,[],562,[]],
 kO:[function(a,b){var z,y,x,w,v,u
 z=P.p9("")
 y=new A.Oc("[polymer-scope="+b+"]")
@@ -20386,17 +20682,17 @@
 v=typeof v==="string"?v:H.d(v)
 u=z.vM+v
 z.vM=u
-z.vM=u+"\n\n"}for(x=a.lD,x.toString,y=H.VM(new H.U5(x,y),[null]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=y.OI;y.G();){w=x.gl().gTa()
+z.vM=u+"\n\n"}for(x=a.lD,x.toString,y=H.VM(new H.U5(x,y),[null]),y=H.VM(new H.SO(J.GP(y.l6),y.T6),[H.Kp(y,0)]),x=y.OI;y.G();){w=x.gl().ghg()
 w=z.vM+w
 z.vM=w
-z.vM=w+"\n\n"}return z.vM},"call$1","gvf",2,0,null,570],
+z.vM=w+"\n\n"}return z.vM},"call$1","gvf",2,0,null,563,[]],
 J3:[function(a,b,c){var z
 if(b==="")return
 z=document.createElement("style",null)
 z.textContent=b
 z.toString
 z.setAttribute("element",a.RT+"-"+c)
-return z},"call$2","gpR",4,0,null,571,570],
+return z},"call$2","gNG",4,0,null,564,[],563,[]],
 q1:[function(a,b){var z,y,x,w
 if(J.de(b,$.Tf()))return
 this.q1(a,b.gAY())
@@ -20407,89 +20703,89 @@
 x=J.rY(w)
 if(x.Tc(w,"Changed")&&!x.n(w,"attributeChanged")){if(a.hf==null)a.hf=P.L5(null,null,null,null,null)
 w=x.Nj(w,0,J.xH(x.gB(w),7))
-a.hf.u(0,new H.GD(H.le(w)),y.gIf())}}},"call$1","gCB",2,0,null,259],
+a.hf.u(0,new H.GD(H.le(w)),y.gIf())}}},"call$1","gCB",2,0,null,253,[]],
 qC:[function(a,b){var z=P.L5(null,null,null,J.O,null)
 b.aN(0,new A.MX(z))
-return z},"call$1","gql",2,0,null,572],
+return z},"call$1","gir",2,0,null,565,[]],
 du:function(a){a.RT=a.getAttribute("name")
 this.yx(a)},
 $isXP:true,
-static:{"":"Nb",XL:function(a){a.Gd=H.B7([],P.L5(null,null,null,null,null))
+static:{"^":"Rlv",XL:function(a){a.Gd=H.B7([],P.L5(null,null,null,null,null))
 C.xk.ZL(a)
 C.xk.du(a)
 return a}}},
 q6:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){return[]},"call$0",null,0,0,null,"call"],
 $isEH:true},
 CK:{
-"":"Tp:349;a",
-call$2:[function(a,b){if(C.kr.x4(a)!==!0&&!J.co(a,"on-"))this.a.xX.u(0,a,b)},"call$2",null,4,0,null,12,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){if(C.kr.x4(a)!==!0&&!J.co(a,"on-"))this.a.xX.u(0,a,b)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 LJ:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z,y,x
 z=J.rY(a)
 if(z.nC(a,"on-")){y=J.U6(b).u8(b,"{{")
 x=C.xB.cn(b,"}}")
-if(y>=0&&x>=0)this.a.u(0,z.yn(a,3),C.xB.bS(C.xB.Nj(b,y+2,x)))}},"call$2",null,4,0,null,12,23,"call"],
+if(y>=0&&x>=0)this.a.u(0,z.yn(a,3),C.xB.bS(C.xB.Nj(b,y+2,x)))}},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 ZG:{
-"":"Tp:229;",
-call$1:[function(a){return J.Vs(a).MW.hasAttribute("polymer-scope")!==!0},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return J.Vs(a).MW.hasAttribute("polymer-scope")!==!0},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 Oc:{
-"":"Tp:229;a",
-call$1:[function(a){return J.RF(a,this.a)},"call$1",null,2,0,null,86,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.RF(a,this.a)},"call$1",null,2,0,null,86,[],"call"],
 $isEH:true},
 MX:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,J.Mz(J.GL(a)),b)},"call$2",null,4,0,null,12,23,"call"],
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,J.Mz(J.GL(a)),b)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
-w11:{
-"":"Tp:108;",
+w9:{
+"^":"Tp:108;",
 call$0:[function(){var z=P.L5(null,null,null,J.O,J.O)
-C.FS.aN(0,new A.ppY(z))
+C.FS.aN(0,new A.r3y(z))
 return z},"call$0",null,0,0,null,"call"],
 $isEH:true},
-ppY:{
-"":"Tp:349;a",
-call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,573,574,"call"],
+r3y:{
+"^":"Tp:341;a",
+call$2:[function(a,b){this.a.u(0,b,a)},"call$2",null,4,0,null,566,[],567,[],"call"],
 $isEH:true},
 yL:{
-"":"nd;",
+"^":"nd;",
 $isyL:true},
 zs:{
-"":["a;KM:ZQ=-357",function(){return[C.nJ]}],
+"^":["a;KM:X0=-349",function(){return[C.nJ]}],
 gpQ:function(a){return!1},
 Pa:[function(a){if(W.Pv(this.gM0(a).defaultView)!=null||$.Bh>0)this.Ec(a)},"call$0","gu1",0,0,null],
 Ec:[function(a){var z,y
 z=this.gQg(a).MW.getAttribute("is")
 y=z==null||z===""?this.gqn(a):z
-a.wV=$.cd().t(0,y)
+a.dZ=$.cd().t(0,y)
 this.Xl(a)
 this.Z2(a)
 this.fk(a)
 this.Uc(a)
 $.Bh=$.Bh+1
-this.z2(a,a.wV)
+this.z2(a,a.dZ)
 $.Bh=$.Bh-1},"call$0","gLi",0,0,null],
-i4:[function(a){if(a.wV==null)this.Ec(a)
+i4:[function(a){if(a.dZ==null)this.Ec(a)
 this.BT(a,!0)},"call$0","gQd",0,0,null],
 xo:[function(a){this.x3(a)},"call$0","gbt",0,0,null],
 z2:[function(a,b){if(b!=null){this.z2(a,J.lB(b))
-this.d0(a,b)}},"call$1","gtf",2,0,null,575],
+this.d0(a,b)}},"call$1","gET",2,0,null,568,[]],
 d0:[function(a,b){var z,y,x,w,v
 z=J.RE(b)
 y=z.Ja(b,"template")
-if(y!=null)if(J.Vs(a.wV).MW.hasAttribute("lightdom")===!0){this.Se(a,y)
+if(y!=null)if(J.Vs(a.dZ).MW.hasAttribute("lightdom")===!0){this.Se(a,y)
 x=null}else x=this.Tp(a,y)
 else x=null
 w=J.x(x)
 if(typeof x!=="object"||x===null||!w.$isI0)return
 v=z.gQg(b).MW.getAttribute("name")
 if(v==null)return
-a.B7.u(0,v,x)},"call$1","gcY",2,0,null,576],
+a.B7.u(0,v,x)},"call$1","gEB",2,0,null,569,[]],
 Se:[function(a,b){var z,y
 if(b==null)return
 z=J.x(b)
@@ -20497,7 +20793,7 @@
 y=z.ZK(a,a.SO)
 this.jx(a,y)
 this.lj(a,a)
-return y},"call$1","gAt",2,0,null,262],
+return y},"call$1","gAt",2,0,null,256,[]],
 Tp:[function(a,b){var z,y
 if(b==null)return
 this.gKE(a)
@@ -20509,45 +20805,45 @@
 y=typeof b==="object"&&b!==null&&!!y.$ishs?b:M.Ky(b)
 z.appendChild(y.ZK(a,a.SO))
 this.lj(a,z)
-return z},"call$1","gPA",2,0,null,262],
+return z},"call$1","gPA",2,0,null,256,[]],
 lj:[function(a,b){var z,y,x,w
-for(z=J.pe(b,"[id]"),z=z.gA(z),y=a.ZQ,x=J.w1(y);z.G();){w=z.lo
-x.u(y,J.F8(w),w)}},"call$1","gb7",2,0,null,577],
+for(z=J.pe(b,"[id]"),z=z.gA(z),y=a.X0,x=J.w1(y);z.G();){w=z.lo
+x.u(y,J.F8(w),w)}},"call$1","gb7",2,0,null,570,[]],
 aC:[function(a,b,c,d){var z=J.x(b)
-if(!z.n(b,"class")&&!z.n(b,"style"))this.D3(a,b,d)},"call$3","gxR",6,0,null,12,231,232],
-Z2:[function(a){J.Ng(a.wV).aN(0,new A.WC(a))},"call$0","gGN",0,0,null],
-fk:[function(a){if(J.ak(a.wV)==null)return
+if(!z.n(b,"class")&&!z.n(b,"style"))this.D3(a,b,d)},"call$3","gxR",6,0,null,12,[],225,[],226,[]],
+Z2:[function(a){J.Ng(a.dZ).aN(0,new A.WC(a))},"call$0","gGN",0,0,null],
+fk:[function(a){if(J.ak(a.dZ)==null)return
 this.gQg(a).aN(0,this.ghW(a))},"call$0","goQ",0,0,null],
 D3:[function(a,b,c){var z,y,x,w
 z=this.B2(a,b)
 if(z==null)return
 if(c==null||J.kE(c,$.VC())===!0)return
 y=H.vn(a)
-x=y.rN(z.gIf()).Ax
+x=y.rN(z.gIf()).gAx()
 w=Z.Zh(c,x,A.al(x,z))
-if(w==null?x!=null:w!==x)y.PU(z.gIf(),w)},"call$2","ghW",4,0,578,12,23],
-B2:[function(a,b){var z=J.ak(a.wV)
+if(w==null?x!=null:w!==x)y.PU(z.gIf(),w)},"call$2","ghW",4,0,571,12,[],23,[]],
+B2:[function(a,b){var z=J.ak(a.dZ)
 if(z==null)return
-return z.t(0,b)},"call$1","gHf",2,0,null,12],
+return z.t(0,b)},"call$1","gHf",2,0,null,12,[]],
 TW:[function(a,b){if(b==null)return
 if(typeof b==="boolean")return b?"":null
 else if(typeof b==="string"||typeof b==="number"&&Math.floor(b)===b||typeof b==="number")return H.d(b)
-return},"call$1","gk9",2,0,null,23],
+return},"call$1","gt4",2,0,null,23,[]],
 Id:[function(a,b){var z,y
-z=H.vn(a).rN(b).Ax
+z=H.vn(a).rN(b).gAx()
 y=this.TW(a,z)
 if(y!=null)this.gQg(a).MW.setAttribute(J.GL(b),y)
-else if(typeof z==="boolean")this.gQg(a).Rz(0,J.GL(b))},"call$1","gQp",2,0,null,12],
+else if(typeof z==="boolean")this.gQg(a).Rz(0,J.GL(b))},"call$1","gQp",2,0,null,12,[]],
 Z1:[function(a,b,c,d){var z,y,x,w,v,u,t
-if(a.wV==null)this.Ec(a)
+if(a.dZ==null)this.Ec(a)
 z=this.B2(a,b)
 if(z==null)return J.Jj(M.Ky(a),b,c,d)
 else{J.MV(M.Ky(a),b)
 y=z.gIf()
 x=$.ZH()
-if(x.mL(C.R5))x.J4("["+H.d(c)+"]: bindProperties: ["+H.d(d)+"] to ["+this.gqn(a)+"].["+H.d(y)+"]")
+if(x.Im(C.R5))x.J4("["+H.d(c)+"]: bindProperties: ["+H.d(d)+"] to ["+this.gqn(a)+"].["+H.d(y)+"]")
 w=L.ao(c,d,null)
-if(w.gP(w)==null)w.sP(0,H.vn(a).rN(y).Ax)
+if(w.gP(w)==null)w.sP(0,H.vn(a).rN(y).gAx())
 x=H.vn(a)
 v=y.fN
 u=d!=null?d:""
@@ -20556,9 +20852,9 @@
 t.bw(a,y,c,d)
 this.Id(a,z.gIf())
 J.kW(J.QE(M.Ky(a)),b,t)
-return t}},"call$3","gDT",4,2,null,77,12,285,266],
+return t}},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 gCd:function(a){return J.QE(M.Ky(a))},
-Ih:[function(a,b){return J.MV(M.Ky(a),b)},"call$1","gV0",2,0,null,12],
+Ih:[function(a,b){return J.MV(M.Ky(a),b)},"call$1","gC8",2,0,null,12,[]],
 x3:[function(a){var z,y
 if(a.Uk===!0)return
 $.P5().J4("["+this.gqn(a)+"] asyncUnbindAll")
@@ -20567,7 +20863,7 @@
 if(z!=null)z.TP(0)
 else z=new A.S0(null,null)
 z.M3=y
-z.ih=P.rT(C.RT,z.gv6(z))
+z.ih=P.rT(C.ny,z.gv6(z))
 a.oq=z},"call$0","gpj",0,0,null],
 GB:[function(a){var z,y
 if(a.Uk===!0)return
@@ -20584,32 +20880,32 @@
 z=a.oq
 if(z!=null){z.TP(0)
 a.oq=null}if(b===!0)return
-A.Vx(this.gKE(a),new A.TV())},function(a){return this.BT(a,null)},"oW","call$1$preventCascade",null,"gF7",0,3,null,77,579],
+A.Vx(this.gKE(a),new A.TV())},function(a){return this.BT(a,null)},"oW","call$1$preventCascade",null,"gF7",0,3,null,77,572,[]],
 Xl:[function(a){var z,y,x,w,v,u
-z=J.xR(a.wV)
-y=J.YP(a.wV)
+z=J.xR(a.dZ)
+y=J.YP(a.dZ)
 x=z==null
 if(!x)for(z.toString,w=H.VM(new P.i5(z),[H.Kp(z,0)]),v=w.Fb,w=H.VM(new P.N6(v,v.zN,null,null),[H.Kp(w,0)]),w.zq=w.Fb.H9;w.G();){u=w.fD
-this.rJ(a,u,H.vn(a).tu(u,1,J.GL(u),[]),null)}if(!x||y!=null)a.Wz=this.gUj(a).yI(this.gnu(a))},"call$0","gJx",0,0,null],
+this.rJ(a,u,H.vn(a).rN(u),null)}if(!x||y!=null)a.Wz=this.gUj(a).yI(this.gnu(a))},"call$0","gJx",0,0,null],
 Pv:[function(a,b){var z,y,x,w,v,u
-z=J.xR(a.wV)
-y=J.YP(a.wV)
-x=P.L5(null,null,null,P.wv,A.k8)
+z=J.xR(a.dZ)
+y=J.YP(a.dZ)
+x=P.L5(null,null,null,P.wv,A.bS)
 for(w=J.GP(b);w.G();){v=w.gl()
 u=J.x(v)
 if(typeof v!=="object"||v===null||!u.$isqI)continue
-J.Pz(x.to(v.oc,new A.Oa(v)),v.zZ)}x.aN(0,new A.n1(a,b,z,y))},"call$1","gnu",2,0,580,581],
+J.iG(x.to(v.oc,new A.Oa(v)),v.zZ)}x.aN(0,new A.n1(a,b,z,y))},"call$1","gnu",2,0,573,574,[]],
 rJ:[function(a,b,c,d){var z,y,x,w,v
-z=J.xR(a.wV)
+z=J.xR(a.dZ)
 if(z==null)return
 y=z.t(0,b)
 if(y==null)return
 x=J.x(d)
 if(typeof d==="object"&&d!==null&&!!x.$iswn){x=$.a3()
-if(x.mL(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: unregister observer "+H.d(b))
+if(x.Im(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: unregister observer "+H.d(b))
 this.l5(a,H.d(J.GL(b))+"__array")}x=J.x(c)
 if(typeof c==="object"&&c!==null&&!!x.$iswn){x=$.a3()
-if(x.mL(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: register observer "+H.d(b))
+if(x.Im(C.R5))x.J4("["+this.gqn(a)+"] observeArrayValue: register observer "+H.d(b))
 w=c.gvp().w4(!1)
 x=w.Lj
 w.dB=x.cR(new A.xf(a,d,y))
@@ -20618,21 +20914,21 @@
 x=H.d(J.GL(b))+"__array"
 v=a.Sa
 if(v==null){v=P.L5(null,null,null,J.O,P.MO)
-a.Sa=v}v.u(0,x,w)}},"call$3","gDW",6,0,null,12,23,248],
+a.Sa=v}v.u(0,x,w)}},"call$3","gDW",6,0,null,12,[],23,[],243,[]],
 l5:[function(a,b){var z=a.Sa.Rz(0,b)
 if(z==null)return!1
 z.ed()
-return!0},"call$1","gjC",2,0,null,12],
+return!0},"call$1","gjC",2,0,null,12,[]],
 C0:[function(a){var z=a.Sa
 if(z==null)return
 for(z=z.gUQ(z),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)z.lo.ed()
 a.Sa.V1(0)
 a.Sa=null},"call$0","gNX",0,0,null],
 Uc:[function(a){var z,y
-z=J.wX(a.wV)
+z=J.wX(a.dZ)
 if(z.gl0(z))return
 y=$.SS()
-if(y.mL(C.R5))y.J4("["+this.gqn(a)+"] addHostListeners: "+H.d(z))
+if(y.Im(C.R5))y.J4("["+this.gqn(a)+"] addHostListeners: "+H.d(z))
 this.UH(a,a,z.gvc(z),this.gD4(a))},"call$0","ghu",0,0,null],
 UH:[function(a,b,c,d){var z,y,x,w,v,u,t
 for(z=c.Fb,z=H.VM(new P.N6(z,z.zN,null,null),[H.Kp(c,0)]),z.zq=z.Fb.H9,y=J.RE(b);z.G();){x=z.fD
@@ -20642,61 +20938,61 @@
 t=new W.Ov(0,w.uv,v,W.aF(d),u)
 t.$builtinTypeInfo=[H.Kp(w,0)]
 w=t.u7
-if(w!=null&&t.VP<=0)J.cZ(t.uv,v,w,u)}},"call$3","gPm",6,0,null,265,582,298],
+if(w!=null&&t.VP<=0)J.cZ(t.uv,v,w,u)}},"call$3","gPm",6,0,null,259,[],575,[],292,[]],
 iw:[function(a,b){var z,y,x,w,v,u,t
 z=J.RE(b)
 if(z.gXt(b)!==!0)return
 y=$.SS()
-x=y.mL(C.R5)
+x=y.Im(C.R5)
 if(x)y.J4(">>> ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")
-w=J.wX(a.wV)
+w=J.wX(a.dZ)
 v=z.gt5(b)
-u=J.UQ($.pT(),v)
+u=J.UQ($.QX(),v)
 t=w.t(0,u!=null?u:v)
-if(t!=null){if(x)y.J4("["+this.gqn(a)+"] found host handler name ["+H.d(t)+"]")
-this.ea(a,a,t,[b,typeof b==="object"&&b!==null&&!!z.$isDG?z.gey(b):null,a])}if(x)y.J4("<<< ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")},"call$1","gD4",2,0,583,405],
+if(t!=null){if(x)y.J4("["+this.gqn(a)+"] found host handler name ["+t+"]")
+this.ea(a,a,t,[b,typeof b==="object"&&b!==null&&!!z.$isHe?z.gey(b):null,a])}if(x)y.J4("<<< ["+this.gqn(a)+"]: hostEventListener("+H.d(z.gt5(b))+")")},"call$1","gD4",2,0,576,400,[]],
 ea:[function(a,b,c,d){var z,y,x
 z=$.SS()
-y=z.mL(C.R5)
+y=z.Im(C.R5)
 if(y)z.J4(">>> ["+this.gqn(a)+"]: dispatch "+H.d(c))
 x=J.x(c)
 if(typeof c==="object"&&c!==null&&!!x.$isEH)H.Ek(c,d,P.Te(null))
 else if(typeof c==="string")A.HR(b,new H.GD(H.le(c)),d)
 else z.j2("invalid callback")
-if(y)z.To("<<< ["+this.gqn(a)+"]: dispatch "+H.d(c))},"call$3","gtW",6,0,null,6,584,258],
+if(y)z.To("<<< ["+this.gqn(a)+"]: dispatch "+H.d(c))},"call$3","gtW",6,0,null,6,[],577,[],263,[]],
 $iszs:true,
 $ishs:true,
 $isd3:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true},
+$isKV:true},
 WC:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=J.Vs(this.a)
 if(z.x4(a)!==!0)z.u(0,a,new A.Xi(b).call$0())
-z.t(0,a)},"call$2",null,4,0,null,12,23,"call"],
+z.t(0,a)},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 Xi:{
-"":"Tp:108;b",
+"^":"Tp:108;b",
 call$0:[function(){return this.b},"call$0",null,0,0,null,"call"],
 $isEH:true},
 TV:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.RE(a)
-if(typeof a==="object"&&a!==null&&!!z.$iszs)z.oW(a)},"call$1",null,2,0,null,292,"call"],
+if(typeof a==="object"&&a!==null&&!!z.$iszs)z.oW(a)},"call$1",null,2,0,null,287,[],"call"],
 $isEH:true},
 Mq:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return J.AA(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a))},"call$1",null,2,0,null,265,"call"],
+return J.AA(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a))},"call$1",null,2,0,null,259,[],"call"],
 $isEH:true},
 Oa:{
-"":"Tp:108;a",
-call$0:[function(){return new A.k8(this.a.jL,null)},"call$0",null,0,0,null,"call"],
+"^":"Tp:108;a",
+call$0:[function(){return new A.bS(this.a.jL,null)},"call$0",null,0,0,null,"call"],
 $isEH:true},
 n1:{
-"":"Tp:349;b,c,d,e",
+"^":"Tp:341;b,c,d,e",
 call$2:[function(a,b){var z,y,x
 z=this.e
 if(z!=null&&z.x4(a))J.Jr(this.b,a)
@@ -20706,26 +21002,26 @@
 if(y!=null){z=this.b
 x=J.RE(b)
 J.Ut(z,a,x.gzZ(b),x.gjL(b))
-A.HR(z,y,[x.gjL(b),x.gzZ(b),this.c])}},"call$2",null,4,0,null,12,585,"call"],
+A.HR(z,y,[x.gjL(b),x.gzZ(b),this.c])}},"call$2",null,4,0,null,12,[],578,[],"call"],
 $isEH:true},
 xf:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){A.HR(this.a,this.c,[this.b])},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){A.HR(this.a,this.c,[this.b])},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 L6:{
-"":"Tp:349;a,b",
+"^":"Tp:341;a,b",
 call$2:[function(a,b){var z,y,x
 z=$.SS()
-if(z.mL(C.R5))z.J4("event: ["+H.d(b)+"]."+H.d(this.b)+" => ["+H.d(a)+"]."+this.a+"())")
+if(z.Im(C.R5))z.J4("event: ["+H.d(b)+"]."+H.d(this.b)+" => ["+H.d(a)+"]."+this.a+"())")
 y=J.ZZ(this.b,3)
 x=C.FS.t(0,y)
 if(x!=null)y=x
 z=J.f5(b).t(0,y)
 H.VM(new W.Ov(0,z.uv,z.Ph,W.aF(new A.Rs(this.a,a,b)),z.Sg),[H.Kp(z,0)]).Zz()
-return H.VM(new A.xh(null,null,null),[null])},"call$2",null,4,0,null,285,265,"call"],
+return H.VM(new A.xh(null,null,null),[null])},"call$2",null,4,0,null,280,[],259,[],"call"],
 $isEH:true},
 Rs:{
-"":"Tp:229;c,d,e",
+"^":"Tp:223;c,d,e",
 call$1:[function(a){var z,y,x,w,v,u
 z=this.e
 y=A.Hr(z)
@@ -20737,44 +21033,44 @@
 u=L.ao(v,C.xB.yn(w,1),null)
 w=u.gP(u)}else v=y
 u=J.RE(a)
-x.ea(y,v,w,[a,typeof a==="object"&&a!==null&&!!u.$isDG?u.gey(a):null,z])},"call$1",null,2,0,null,405,"call"],
+x.ea(y,v,w,[a,typeof a==="object"&&a!==null&&!!u.$isHe?u.gey(a):null,z])},"call$1",null,2,0,null,400,[],"call"],
 $isEH:true},
 uJ:{
-"":"Tp:229;",
-call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,586,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,579,[],"call"],
 $isEH:true},
 hm:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z,y,x
 z=W.vD(document.querySelectorAll(".polymer-veiled"),null)
 for(y=z.gA(z);y.G();){x=J.pP(y.lo)
 x.h(0,"polymer-unveil")
 x.Rz(x,"polymer-veiled")}if(z.gor(z)){y=C.hi.aM(window)
-y.gtH(y).ml(new A.Ji(z))}},"call$1",null,2,0,null,240,"call"],
+y.gtH(y).ml(new A.Ji(z))}},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Ji:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z
-for(z=this.a,z=z.gA(z);z.G();)J.pP(z.lo).Rz(0,"polymer-unveil")},"call$1",null,2,0,null,240,"call"],
+for(z=this.a,z=z.gA(z);z.G();)J.pP(z.lo).Rz(0,"polymer-unveil")},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Bf:{
-"":"TR;I6,iU,Jq,dY,qP,ZY,xS,PB,eS,ay",
+"^":"TR;I6,iU,Jq,dY,qP,ZY,xS,PB,eS,ay",
 cO:[function(a){if(this.qP==null)return
 this.Jq.ed()
 X.TR.prototype.cO.call(this,this)},"call$0","gJK",0,0,null],
 EC:[function(a){this.dY=a
-this.I6.PU(this.iU,a)},"call$1","gH0",2,0,null,232],
+this.I6.PU(this.iU,a)},"call$1","gH0",2,0,null,226,[]],
 ho:[function(a){var z,y,x,w,v
 for(z=J.GP(a),y=this.iU;z.G();){x=z.gl()
 w=J.x(x)
-if(typeof x==="object"&&x!==null&&!!w.$isqI&&J.de(x.oc,y)){v=this.I6.tu(y,1,y.fN,[]).Ax
+if(typeof x==="object"&&x!==null&&!!w.$isqI&&J.de(x.oc,y)){v=this.I6.rN(y).gAx()
 z=this.dY
 if(z==null?v!=null:z!==v)J.ta(this.xS,v)
-return}}},"call$1","giz",2,0,587,256],
+return}}},"call$1","giz",2,0,580,251,[]],
 bw:function(a,b,c,d){this.Jq=J.xq(a).yI(this.giz())}},
 ir:{
-"":["Ao;AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-oX:function(a){this.Pa(a)},
+"^":["GN;AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+G6:function(a){this.Pa(a)},
 static:{oa:function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -20783,29 +21079,29 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Iv.ZL(a)
-C.Iv.oX(a)
+C.Iv.G6(a)
 return a}}},
-Sa:{
-"":["qE+zs;KM:ZQ=-357",function(){return[C.nJ]}],
+jpR:{
+"^":["qE+zs;KM:X0=-349",function(){return[C.nJ]}],
 $iszs:true,
 $ishs:true,
 $isd3:true,
 $iscv:true,
 $isGv:true,
 $isD0:true,
-$isuH:true},
-Ao:{
-"":"Sa+Pi;",
+$isKV:true},
+GN:{
+"^":"jpR+Pi;",
 $isd3:true},
-k8:{
-"":"a;jL>,zZ*",
-$isk8:true},
+bS:{
+"^":"a;jL>,zZ*",
+$isbS:true},
 HJ:{
-"":"e9;nF"},
+"^":"e9;nF"},
 S0:{
-"":"a;M3,ih",
+"^":"a;M3,ih",
 Ws:function(){return this.M3.call$0()},
 TP:[function(a){var z=this.ih
 if(z!=null){z.ed()
@@ -20813,110 +21109,110 @@
 tZ:[function(a){if(this.ih!=null){this.TP(0)
 this.Ws()}},"call$0","gv6",0,0,107]},
 V3:{
-"":"a;ns",
+"^":"a;ns",
 $isV3:true},
 Bl:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=$.mC().MM
 if(z.Gv!==0)H.vh(new P.lj("Future already completed"))
 z.OH(null)
-return},"call$1",null,2,0,null,240,"call"],
+return},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 Fn:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isRS},"call$1",null,2,0,null,588,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isRS},"call$1",null,2,0,null,581,[],"call"],
 $isEH:true},
 e3:{
-"":"Tp:229;",
+"^":"Tp:223;",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isMs},"call$1",null,2,0,null,588,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isMs},"call$1",null,2,0,null,581,[],"call"],
 $isEH:true},
 pM:{
-"":"Tp:229;",
-call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,586,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return!a.gQ2()},"call$1",null,2,0,null,579,[],"call"],
 $isEH:true},
 jh:{
-"":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{
-"":"",
+"^":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{
+"^":"",
 Zh:[function(a,b,c){var z,y,x
-z=J.UQ($.WJ(),c.gvd())
+z=J.UQ($.CT(),c.gUx())
 if(z!=null)return z.call$2(a,b)
-try{y=C.lM.kV(J.JA(a,"'","\""))
+try{y=C.xr.kV(J.JA(a,"'","\""))
 return y}catch(x){H.Ru(x)
-return a}},"call$3","nn",6,0,null,23,276,11],
+return a}},"call$3","nn",6,0,null,23,[],271,[],11,[]],
 W6:{
-"":"Tp:108;",
+"^":"Tp:108;",
 call$0:[function(){var z=P.L5(null,null,null,null,null)
 z.u(0,C.AZ,new Z.Lf())
 z.u(0,C.ok,new Z.fT())
 z.u(0,C.N4,new Z.pp())
-z.u(0,C.Ts,new Z.Nq())
-z.u(0,C.PC,new Z.nl())
-z.u(0,C.md,new Z.ik())
+z.u(0,C.Ts,new Z.nl())
+z.u(0,C.PC,new Z.ik())
+z.u(0,C.md,new Z.LfS())
 return z},"call$0",null,0,0,null,"call"],
 $isEH:true},
 Lf:{
-"":"Tp:349;",
-call$2:[function(a,b){return a},"call$2",null,4,0,null,21,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 fT:{
-"":"Tp:349;",
-call$2:[function(a,b){return a},"call$2",null,4,0,null,21,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 pp:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){var z,y
 try{z=P.Gl(a)
 return z}catch(y){H.Ru(y)
-return b}},"call$2",null,4,0,null,21,589,"call"],
-$isEH:true},
-Nq:{
-"":"Tp:349;",
-call$2:[function(a,b){return!J.de(a,"false")},"call$2",null,4,0,null,21,240,"call"],
+return b}},"call$2",null,4,0,null,21,[],582,[],"call"],
 $isEH:true},
 nl:{
-"":"Tp:349;",
-call$2:[function(a,b){return H.BU(a,null,new Z.mf(b))},"call$2",null,4,0,null,21,589,"call"],
-$isEH:true},
-mf:{
-"":"Tp:229;a",
-call$1:[function(a){return this.a},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return!J.de(a,"false")},"call$2",null,4,0,null,21,[],235,[],"call"],
 $isEH:true},
 ik:{
-"":"Tp:349;",
-call$2:[function(a,b){return H.IH(a,new Z.HK(b))},"call$2",null,4,0,null,21,589,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return H.BU(a,null,new Z.mf(b))},"call$2",null,4,0,null,21,[],582,[],"call"],
+$isEH:true},
+mf:{
+"^":"Tp:223;a",
+call$1:[function(a){return this.a},"call$1",null,2,0,null,235,[],"call"],
+$isEH:true},
+LfS:{
+"^":"Tp:341;",
+call$2:[function(a,b){return H.IH(a,new Z.HK(b))},"call$2",null,4,0,null,21,[],582,[],"call"],
 $isEH:true},
 HK:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true}}],["polymer_expressions","package:polymer_expressions/polymer_expressions.dart",,T,{
-"":"",
+"^":"",
 ul:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)z=J.vo(z.gvc(a),new T.o8(a)).zV(0," ")
 else z=typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)?z.zV(a," "):a
-return z},"call$1","qP",2,0,187,277],
+return z},"call$1","qP",2,0,187,272,[]],
 PX:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isZ0)z=J.C0(z.gvc(a),new T.ex(a)).zV(0,";")
 else z=typeof a==="object"&&a!==null&&(a.constructor===Array||!!z.$iscX)?z.zV(a,";"):a
-return z},"call$1","Fx",2,0,187,277],
+return z},"call$1","Fx",2,0,187,272,[]],
 o8:{
-"":"Tp:229;a",
-call$1:[function(a){return J.de(this.a.t(0,a),!0)},"call$1",null,2,0,null,421,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return J.de(this.a.t(0,a),!0)},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 ex:{
-"":"Tp:229;a",
-call$1:[function(a){return H.d(a)+": "+H.d(this.a.t(0,a))},"call$1",null,2,0,null,421,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){return H.d(a)+": "+H.d(this.a.t(0,a))},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 e9:{
-"":"T4;",
-yt:[function(a,b,c){var z,y,x
+"^":"T4;",
+cl:[function(a,b,c){var z,y,x
 if(a==null)return
 z=new Y.hc(H.VM([],[Y.Pn]),P.p9(""),new P.WU(a,0,0,null),null)
 y=new U.tc()
 y=new T.FX(y,z,null,null)
 z=z.zl()
-y.ku=z
+y.qM=z
 y.fL=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)])
 y.w5()
 x=y.o9()
@@ -20924,41 +21220,41 @@
 if(z.n(b,"bind")||z.n(b,"repeat")){z=J.x(x)
 z=typeof x==="object"&&x!==null&&!!z.$isEZ}else z=!1}else z=!1
 if(z)return
-return new T.Xy(this,b,x)},"call$3","gca",6,0,590,266,12,265],
-CE:[function(a){return new T.uK(this)},"call$1","gb4",2,0,null,262]},
+return new T.Xy(this,b,x)},"call$3","gca",6,0,583,260,[],12,[],259,[]],
+CE:[function(a){return new T.G0(this)},"call$1","gb4",2,0,null,256,[]]},
 Xy:{
-"":"Tp:349;a,b,c",
+"^":"Tp:341;a,b,c",
 call$2:[function(a,b){var z=J.x(a)
 if(typeof a!=="object"||a===null||!z.$isz6){z=this.a.nF
 a=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}z=J.x(b)
 z=typeof b==="object"&&b!==null&&!!z.$iscv
 if(z&&J.de(this.b,"class"))return T.FL(this.c,a,T.qP())
 if(z&&J.de(this.b,"style"))return T.FL(this.c,a,T.Fx())
-return T.FL(this.c,a,null)},"call$2",null,4,0,null,285,265,"call"],
+return T.FL(this.c,a,null)},"call$2",null,4,0,null,280,[],259,[],"call"],
 $isEH:true},
-uK:{
-"":"Tp:229;a",
+G0:{
+"^":"Tp:223;a",
 call$1:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isz6)z=a
 else{z=this.a.nF
-z=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}return z},"call$1",null,2,0,null,285,"call"],
+z=new K.z6(null,a,V.WF(z==null?H.B7([],P.L5(null,null,null,null,null)):z,null,null),null)}return z},"call$1",null,2,0,null,280,[],"call"],
 $isEH:true},
 mY:{
-"":"Pi;a9,Cu,uI,Y7,AP,fn",
+"^":"Pi;a9,Cu,uI,Y7,AP,fn",
 u0:function(a){return this.uI.call$1(a)},
 KX:[function(a){var z,y
 z=this.Y7
 y=J.x(a)
 if(typeof a==="object"&&a!==null&&!!y.$isfk){y=J.C0(a.bm,new T.mB(this,a)).tt(0,!1)
 this.Y7=y}else{y=this.uI==null?a:this.u0(a)
-this.Y7=y}F.Wi(this,C.ls,z,y)},"call$1","gUG",2,0,229,277],
-gP:[function(a){return this.Y7},null,null,1,0,108,"value",359],
-r6:function(a,b){return this.gP(a).call$1(b)},
+this.Y7=y}F.Wi(this,C.ls,z,y)},"call$1","gUG",2,0,223,272,[]],
+gP:[function(a){return this.Y7},null,null,1,0,108,"value",351],
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:[function(a,b){var z,y,x,w
 try{K.jX(this.Cu,b,this.a9)}catch(y){x=H.Ru(y)
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$isB0){z=x
-$.eH().j2("Error evaluating expression '"+H.d(this.Cu)+"': "+J.yj(z))}else throw y}},null,null,3,0,229,277,"value",359],
+$.eH().j2("Error evaluating expression '"+H.d(this.Cu)+"': "+J.yj(z))}else throw y}},null,null,3,0,223,272,[],"value",351],
 yB:function(a,b,c){var z,y,x,w,v
 y=this.Cu
 y.gju().yI(this.gUG()).fm(0,new T.GX(this))
@@ -20968,51 +21264,45 @@
 v=J.x(w)
 if(typeof w==="object"&&w!==null&&!!v.$isB0){z=w
 $.eH().j2("Error evaluating expression '"+H.d(y)+"': "+J.yj(z))}else throw x}},
-static:{FL:function(a,b,c){var z=H.VM(new P.Sw(null,0,0,0),[null])
-z.Eo(null,null)
-z=new T.mY(b,a.RR(0,new K.G1(b,z)),c,null,null,null)
+static:{FL:function(a,b,c){var z=new T.mY(b,a.RR(0,new K.G1(b,P.NZ(null,null))),c,null,null,null)
 z.yB(a,b,c)
 return z}}},
 GX:{
-"":"Tp:229;a",
-call$1:[function(a){$.eH().j2("Error evaluating expression '"+H.d(this.a.Cu)+"': "+H.d(J.yj(a)))},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){$.eH().j2("Error evaluating expression '"+H.d(this.a.Cu)+"': "+H.d(J.yj(a)))},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 mB:{
-"":"Tp:229;a,b",
+"^":"Tp:223;a,b",
 call$1:[function(a){var z=P.L5(null,null,null,null,null)
 z.u(0,this.b.kF,a)
-return new K.z6(this.a.a9,null,V.WF(z,null,null),null)},"call$1",null,2,0,null,341,"call"],
+return new K.z6(this.a.a9,null,V.WF(z,null,null),null)},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true}}],["polymer_expressions.async","package:polymer_expressions/async.dart",,B,{
-"":"",
+"^":"",
 XF:{
-"":"xh;vq,L1,AP,fn",
-vb:function(a,b){this.vq.yI(new B.iH(b,this))},
+"^":"xh;vq,L1,AP,fn",
+vb:function(a,b){this.vq.yI(new B.bX(b,this))},
 $asxh:function(a){return[null]},
 static:{z4:function(a,b){var z=H.VM(new B.XF(a,null,null,null),[b])
 z.vb(a,b)
 return z}}},
-iH:{
-"":"Tp;a,b",
+bX:{
+"^":"Tp;a,b",
 call$1:[function(a){var z=this.b
-z.L1=F.Wi(z,C.ls,z.L1,a)},"call$1",null,2,0,null,341,"call"],
+z.L1=F.Wi(z,C.ls,z.L1,a)},"call$1",null,2,0,null,383,[],"call"],
 $isEH:true,
 $signature:function(){return H.IG(function(a){return{func:"CJ",args:[a]}},this.b,"XF")}}}],["polymer_expressions.eval","package:polymer_expressions/eval.dart",,K,{
-"":"",
-OH:[function(a,b){var z,y
-z=new P.Sw(null,0,0,0)
-z.$builtinTypeInfo=[null]
-z.Eo(null,null)
-y=J.UK(a,new K.G1(b,z))
-J.UK(y,new K.Ed(b))
-return y.gLv()},"call$2","Gk",4,0,null,278,270],
+"^":"",
+OH:[function(a,b){var z=J.UK(a,new K.G1(b,P.NZ(null,null)))
+J.UK(z,new K.Ed(b))
+return z.gLv()},"call$2","ly",4,0,null,273,[],265,[]],
 jX:[function(a,b,c){var z,y,x,w,v,u,t,s,r,q,p
 z={}
 z.a=a
 y=new K.c4(z)
 x=H.VM([],[U.hw])
 for(;w=z.a,v=J.RE(w),typeof w==="object"&&w!==null&&!!v.$isuk;){if(!J.de(v.gkp(w),"|"))break
-x.push(v.gT8(w))
-z.a=v.gBb(w)}w=z.a
+x.push(w.gT8())
+z.a=w.gBb()}w=z.a
 v=J.RE(w)
 if(typeof w==="object"&&w!==null&&!!v.$isw6){u=v.gP(w)
 t=C.OL
@@ -21022,141 +21312,137 @@
 t=z.a.ghP()
 u=J.Vm(z.a.gJn())
 s=!0}else{if(typeof w==="object"&&w!==null&&!!v.$isx9){t=w.ghP()
-u=J.O6(z.a)}else if(typeof w==="object"&&w!==null&&!!v.$isRW){t=w.ghP()
+u=J.O6(z.a)}else if(typeof w==="object"&&w!==null&&!!v.$isJy){t=w.ghP()
 if(J.vF(z.a)!=null){if(z.a.gre()!=null)y.call$0()
 u=J.vF(z.a)}else{y.call$0()
 u=null}}else{y.call$0()
 t=null
 u=null}s=!1}for(z=H.VM(new H.a7(x,x.length,0,null),[H.Kp(x,0)]);z.G();){r=z.lo
-y=new P.Sw(null,0,0,0)
-y.$builtinTypeInfo=[null]
-y.Eo(null,null)
-q=J.UK(r,new K.G1(c,y))
+q=J.UK(r,new K.G1(c,P.NZ(null,null)))
 J.UK(q,new K.Ed(c))
 q.gLv()
 throw H.b(K.kG("filter must implement Transformer: "+H.d(r)))}p=K.OH(t,c)
 if(p==null)throw H.b(K.kG("Can't assign to null: "+H.d(t)))
 if(s)J.kW(p,u,b)
-else H.vn(p).PU(new H.GD(H.le(u)),b)},"call$3","wA",6,0,null,278,23,270],
+else H.vn(p).PU(new H.GD(H.le(u)),b)},"call$3","wA",6,0,null,273,[],23,[],265,[]],
 ci:[function(a){var z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$isqh)return B.z4(a,null)
-return a},"call$1","Af",2,0,null,277],
+return a},"call$1","Af",2,0,null,272,[]],
+lP:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.WB(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
+Uf:{
+"^":"Tp:341;",
+call$2:[function(a,b){return J.xH(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
+$isEH:true},
 Ra:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.WB(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.p0(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 wJY:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.xH(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.FW(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 zOQ:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.p0(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.de(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 W6o:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.FW(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return!J.de(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 MdQ:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.de(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.z8(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 YJG:{
-"":"Tp:349;",
-call$2:[function(a,b){return!J.de(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.J5(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 DOe:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.z8(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.u6(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 lPa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.J5(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return J.Hb(a,b)},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 Ufa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.u6(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a===!0||b===!0},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 Raa:{
-"":"Tp:349;",
-call$2:[function(a,b){return J.Hb(a,b)},"call$2",null,4,0,null,123,180,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return a===!0&&b===!0},"call$2",null,4,0,null,123,[],180,[],"call"],
 $isEH:true},
 w0:{
-"":"Tp:349;",
-call$2:[function(a,b){return a===!0||b===!0},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-w4:{
-"":"Tp:349;",
-call$2:[function(a,b){return a===!0&&b===!0},"call$2",null,4,0,null,123,180,"call"],
-$isEH:true},
-w5:{
-"":"Tp:349;",
-call$2:[function(a,b){var z=H.Og(P.a)
+"^":"Tp:341;",
+call$2:[function(a,b){var z=H.uK(P.a)
 z=H.KT(z,[z]).BD(b)
 if(z)return b.call$1(a)
-throw H.b(K.kG("Filters must be a one-argument function."))},"call$2",null,4,0,null,123,110,"call"],
+throw H.b(K.kG("Filters must be a one-argument function."))},"call$2",null,4,0,null,123,[],110,[],"call"],
+$isEH:true},
+w4:{
+"^":"Tp:223;",
+call$1:[function(a){return a},"call$1",null,2,0,null,123,[],"call"],
+$isEH:true},
+w5:{
+"^":"Tp:223;",
+call$1:[function(a){return J.Z7(a)},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 w7:{
-"":"Tp:229;",
-call$1:[function(a){return a},"call$1",null,2,0,null,123,"call"],
-$isEH:true},
-w9:{
-"":"Tp:229;",
-call$1:[function(a){return J.Z7(a)},"call$1",null,2,0,null,123,"call"],
-$isEH:true},
-w10:{
-"":"Tp:229;",
-call$1:[function(a){return a!==!0},"call$1",null,2,0,null,123,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a!==!0},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 c4:{
-"":"Tp:108;a",
+"^":"Tp:108;a",
 call$0:[function(){return H.vh(K.kG("Expression is not assignable: "+H.d(this.a.a)))},"call$0",null,0,0,null,"call"],
 $isEH:true},
 z6:{
-"":"a;eT>,k8,bq,G9",
+"^":"a;eT>,k8,bq,G9",
 gCH:function(){var z=this.G9
 if(z!=null)return z
 z=H.vn(this.k8)
 this.G9=z
 return z},
-t:[function(a,b){var z,y,x,w,v
+t:[function(a,b){var z,y,x,w
 if(J.de(b,"this"))return this.k8
 else{z=this.bq.Zp
 if(z.x4(b))return K.ci(z.t(0,b))
-else if(this.k8!=null){z=H.le(b)
-y=new H.GD(z)
+else if(this.k8!=null){y=new H.GD(H.le(b))
 x=Z.y1(H.jO(J.bB(this.gCH().Ax).LU),y)
-w=J.x(x)
-if(typeof x!=="object"||x===null||!w.$isRY)v=typeof x==="object"&&x!==null&&!!w.$isRS&&x.glT()
-else v=!0
-if(v)return K.ci(this.gCH().tu(y,1,z,[]).Ax)
-else if(typeof x==="object"&&x!==null&&!!w.$isRS)return new K.wL(this.gCH(),y)}}z=this.eT
+z=J.x(x)
+if(typeof x!=="object"||x===null||!z.$isRY)w=typeof x==="object"&&x!==null&&!!z.$isRS&&x.glT()
+else w=!0
+if(w)return K.ci(this.gCH().rN(y).gAx())
+else if(typeof x==="object"&&x!==null&&!!z.$isRS)return new K.wL(this.gCH(),y)}}z=this.eT
 if(z!=null)return K.ci(z.t(0,b))
-else throw H.b(K.kG("variable '"+H.d(b)+"' not found"))},"call$1","gIA",2,0,null,12],
+else throw H.b(K.kG("variable '"+H.d(b)+"' not found"))},"call$1","gIA",2,0,null,12,[]],
 tI:[function(a){var z
 if(J.de(a,"this"))return
 else{z=this.bq
 if(z.Zp.x4(a))return z
 else{z=H.le(a)
 if(Z.y1(H.jO(J.bB(this.gCH().Ax).LU),new H.GD(z))!=null)return this.k8}}z=this.eT
-if(z!=null)return z.tI(a)},"call$1","gXe",2,0,null,12],
+if(z!=null)return z.tI(a)},"call$1","gVy",2,0,null,12,[]],
 tg:[function(a,b){var z
 if(this.bq.Zp.x4(b))return!0
 else{z=H.le(b)
 if(Z.y1(H.jO(J.bB(this.gCH().Ax).LU),new H.GD(z))!=null)return!0}z=this.eT
 if(z!=null)return z.tg(0,b)
-return!1},"call$1","gdj",2,0,null,12],
+return!1},"call$1","gdj",2,0,null,12,[]],
 $isz6:true},
-dE:{
-"":"a;bO?,Lv<",
+Mb:{
+"^":"a;bO?,Lv<",
 gju:function(){var z=this.k6
 return H.VM(new P.Ik(z),[H.Kp(z,0)])},
 gLl:function(){return this.Lv},
-Qh:[function(a){},"call$1","gVj",2,0,null,270],
+Qh:[function(a){},"call$1","gVj",2,0,null,265,[]],
 DX:[function(a){var z
 this.yc(0,a)
 z=this.bO
-if(z!=null)z.DX(a)},"call$1","gFO",2,0,null,270],
+if(z!=null)z.DX(a)},"call$1","gFO",2,0,null,265,[]],
 yc:[function(a,b){var z,y,x
 z=this.tj
 if(z!=null){z.ed()
@@ -21165,30 +21451,30 @@
 z=this.Lv
 if(z==null?y!=null:z!==y){x=this.k6
 if(x.Gv>=4)H.vh(x.q7())
-x.Iv(z)}},"call$1","gcz",2,0,null,270],
+x.Iv(z)}},"call$1","gcz",2,0,null,265,[]],
 bu:[function(a){return this.KL.bu(0)},"call$0","gXo",0,0,null],
 $ishw:true},
 Ed:{
-"":"a0;Jd",
-xn:[function(a){a.yc(0,this.Jd)},"call$1","gBe",2,0,null,18],
-ky:[function(a){J.UK(a.gT8(a),this)
-a.yc(0,this.Jd)},"call$1","gXf",2,0,null,283]},
+"^":"cfS;Jd",
+xn:[function(a){a.yc(0,this.Jd)},"call$1","gBe",2,0,null,18,[]],
+ky:[function(a){J.UK(a.gT8(),this)
+a.yc(0,this.Jd)},"call$1","gXf",2,0,null,278,[]]},
 G1:{
-"":"fr;Jd,Le",
-W9:[function(a){return new K.Wh(a,null,null,null,P.bK(null,null,!1,null))},"call$1","glO",2,0,null,18],
-LT:[function(a){return a.wz.RR(0,this)},"call$1","gff",2,0,null,18],
+"^":"fr;Jd,Le",
+W9:[function(a){return new K.Wh(a,null,null,null,P.bK(null,null,!1,null))},"call$1","glO",2,0,null,18,[]],
+LT:[function(a){return a.wz.RR(0,this)},"call$1","gff",2,0,null,18,[]],
 co:[function(a){var z,y
 z=J.UK(a.ghP(),this)
 y=new K.vl(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(y)
-return y},"call$1","gfz",2,0,null,354],
+return y},"call$1","gEW",2,0,null,346,[]],
 CU:[function(a){var z,y,x
 z=J.UK(a.ghP(),this)
 y=J.UK(a.gJn(),this)
 x=new K.iT(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","gA2",2,0,null,341],
+return x},"call$1","gA2",2,0,null,383,[]],
 ZR:[function(a){var z,y,x,w,v
 z=J.UK(a.ghP(),this)
 y=a.gre()
@@ -21198,115 +21484,115 @@
 x=H.VM(new H.A8(y,w),[null,null]).tt(0,!1)}v=new K.fa(z,x,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(v)
 if(x!=null){x.toString
-H.bQ(x,new K.Os(v))}return v},"call$1","gZo",2,0,null,341],
-ti:[function(a){return new K.x5(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gXj",2,0,null,279],
+H.bQ(x,new K.Os(v))}return v},"call$1","gES",2,0,null,383,[]],
+ti:[function(a){return new K.x5(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gXj",2,0,null,274,[]],
 o0:[function(a){var z,y
 z=H.VM(new H.A8(a.gPu(a),this.gnG()),[null,null]).tt(0,!1)
 y=new K.ev(z,a,null,null,null,P.bK(null,null,!1,null))
 H.bQ(z,new K.B8(y))
-return y},"call$1","gX7",2,0,null,279],
+return y},"call$1","gX7",2,0,null,274,[]],
 YV:[function(a){var z,y,x
 z=J.UK(a.gG3(a),this)
 y=J.UK(a.gv4(),this)
-x=new K.jV(z,y,a,null,null,null,P.bK(null,null,!1,null))
+x=new K.qR(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","gbU",2,0,null,18],
-qv:[function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gFs",2,0,null,341],
+return x},"call$1","gbU",2,0,null,18,[]],
+qv:[function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},"call$1","gFs",2,0,null,383,[]],
 im:[function(a){var z,y,x
-z=J.UK(a.gBb(a),this)
-y=J.UK(a.gT8(a),this)
+z=J.UK(a.gBb(),this)
+y=J.UK(a.gT8(),this)
 x=new K.mG(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(x)
 y.sbO(x)
-return x},"call$1","glf",2,0,null,91],
+return x},"call$1","glf",2,0,null,91,[]],
 Hx:[function(a){var z,y
 z=J.UK(a.gwz(),this)
-y=new K.Jy(z,a,null,null,null,P.bK(null,null,!1,null))
+y=new K.mv(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sbO(y)
-return y},"call$1","gKY",2,0,null,91],
+return y},"call$1","gKY",2,0,null,91,[]],
 ky:[function(a){var z,y,x
-z=J.UK(a.gBb(a),this)
-y=J.UK(a.gT8(a),this)
+z=J.UK(a.gBb(),this)
+y=J.UK(a.gT8(),this)
 x=new K.VA(z,y,a,null,null,null,P.bK(null,null,!1,null))
 y.sbO(x)
-return x},"call$1","gXf",2,0,null,341]},
+return x},"call$1","gXf",2,0,null,383,[]]},
 Os:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 a.sbO(z)
-return z},"call$1",null,2,0,null,123,"call"],
+return z},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 B8:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
 a.sbO(z)
-return z},"call$1",null,2,0,null,18,"call"],
+return z},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 Wh:{
-"":"dE;KL,bO,tj,Lv,k6",
-Qh:[function(a){this.Lv=a.k8},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.EZ]},
+"^":"Mb;KL,bO,tj,Lv,k6",
+Qh:[function(a){this.Lv=a.k8},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.EZ]},
 $isEZ:true,
 $ishw:true},
 x5:{
-"":"dE;KL,bO,tj,Lv,k6",
+"^":"Mb;KL,bO,tj,Lv,k6",
 gP:function(a){var z=this.KL
 return z.gP(z)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 Qh:[function(a){var z=this.KL
-this.Lv=z.gP(z)},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.no]},
+this.Lv=z.gP(z)},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.no]},
 $asno:function(){return[null]},
 $isno:true,
 $ishw:true},
 ev:{
-"":"dE;Pu>,KL,bO,tj,Lv,k6",
-Qh:[function(a){this.Lv=H.n3(this.Pu,P.L5(null,null,null,null,null),new K.ID())},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.kB]},
+"^":"Mb;Pu>,KL,bO,tj,Lv,k6",
+Qh:[function(a){this.Lv=H.n3(this.Pu,P.L5(null,null,null,null,null),new K.ID())},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.kB]},
 $iskB:true,
 $ishw:true},
 ID:{
-"":"Tp:349;",
+"^":"Tp:341;",
 call$2:[function(a,b){J.kW(a,J.WI(b).gLv(),b.gv4().gLv())
-return a},"call$2",null,4,0,null,183,18,"call"],
+return a},"call$2",null,4,0,null,183,[],18,[],"call"],
 $isEH:true},
-jV:{
-"":"dE;G3>,v4<,KL,bO,tj,Lv,k6",
-RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.ae]},
+qR:{
+"^":"Mb;G3>,v4<,KL,bO,tj,Lv,k6",
+RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.ae]},
 $isae:true,
 $ishw:true},
 ek:{
-"":"dE;KL,bO,tj,Lv,k6",
+"^":"Mb;KL,bO,tj,Lv,k6",
 gP:function(a){var z=this.KL
 return z.gP(z)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 Qh:[function(a){var z,y,x
 z=this.KL
 this.Lv=a.t(0,z.gP(z))
 y=a.tI(z.gP(z))
 x=J.RE(y)
 if(typeof y==="object"&&y!==null&&!!x.$isd3){z=H.le(z.gP(z))
-this.tj=x.gUj(y).yI(new K.Qv(this,a,new H.GD(z)))}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.w6]},
+this.tj=x.gUj(y).yI(new K.Qv(this,a,new H.GD(z)))}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.w6]},
 $isw6:true,
 $ishw:true},
 Qv:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.Xm(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.Xm(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 Xm:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
-Jy:{
-"":"dE;wz<,KL,bO,tj,Lv,k6",
+mv:{
+"^":"Mb;wz<,KL,bO,tj,Lv,k6",
 gkp:function(a){var z=this.KL
 return z.gkp(z)},
 Qh:[function(a){var z,y
@@ -21314,13 +21600,13 @@
 y=$.ww().t(0,z.gkp(z))
 if(J.de(z.gkp(z),"!")){z=this.wz.gLv()
 this.Lv=y.call$1(z==null?!1:z)}else{z=this.wz
-this.Lv=z.gLv()==null?null:y.call$1(z.gLv())}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.jK]},
+this.Lv=z.gLv()==null?null:y.call$1(z.gLv())}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.jK]},
 $isjK:true,
 $ishw:true},
 mG:{
-"":"dE;Bb>,T8>,KL,bO,tj,Lv,k6",
+"^":"Mb;Bb<,T8<,KL,bO,tj,Lv,k6",
 gkp:function(a){var z=this.KL
 return z.gkp(z)},
 Qh:[function(a){var z,y,x,w
@@ -21337,17 +21623,17 @@
 w=typeof z==="object"&&z!==null&&!!w.$iswn
 z=w}else z=!1
 if(z)this.tj=H.Go(x.gLv(),"$iswn").gvp().yI(new K.uA(this,a))
-this.Lv=y.call$2(x.gLv(),this.T8.gLv())}}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.uk]},
+this.Lv=y.call$2(x.gLv(),this.T8.gLv())}}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.uk]},
 $isuk:true,
 $ishw:true},
 uA:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 vl:{
-"":"dE;hP<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,KL,bO,tj,Lv,k6",
 goc:function(a){var z=this.KL
 return z.goc(z)},
 Qh:[function(a){var z,y,x
@@ -21355,46 +21641,46 @@
 if(z==null){this.Lv=null
 return}y=this.KL
 x=new H.GD(H.le(y.goc(y)))
-this.Lv=H.vn(z).rN(x).Ax
+this.Lv=H.vn(z).rN(x).gAx()
 y=J.RE(z)
-if(typeof z==="object"&&z!==null&&!!y.$isd3)this.tj=y.gUj(z).yI(new K.Li(this,a,x))},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.x9]},
+if(typeof z==="object"&&z!==null&&!!y.$isd3)this.tj=y.gUj(z).yI(new K.Li(this,a,x))},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.x9]},
 $isx9:true,
 $ishw:true},
 Li:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.WK(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.WK(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 WK:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 iT:{
-"":"dE;hP<,Jn<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,Jn<,KL,bO,tj,Lv,k6",
 Qh:[function(a){var z,y,x
 z=this.hP.gLv()
 if(z==null){this.Lv=null
 return}y=this.Jn.gLv()
 x=J.U6(z)
 this.Lv=x.t(z,y)
-if(typeof z==="object"&&z!==null&&!!x.$isd3)this.tj=x.gUj(z).yI(new K.ja(this,a,y))},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.zX]},
+if(typeof z==="object"&&z!==null&&!!x.$isd3)this.tj=x.gUj(z).yI(new K.ja(this,a,y))},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.zX]},
 $iszX:true,
 $ishw:true},
 ja:{
-"":"Tp:229;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.zw(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:223;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.zw(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 zw:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isHA&&J.de(a.G3,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isHA&&J.de(a.G3,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 fa:{
-"":"dE;hP<,re<,KL,bO,tj,Lv,k6",
+"^":"Mb;hP<,re<,KL,bO,tj,Lv,k6",
 gbP:function(a){var z=this.KL
 return z.gbP(z)},
 Qh:[function(a){var z,y,x,w
@@ -21408,26 +21694,26 @@
 this.Lv=K.ci(typeof x==="object"&&x!==null&&!!z.$iswL?x.lR.F2(x.ex,y,null).Ax:H.Ek(x,y,P.Te(null)))}else{w=new H.GD(H.le(z.gbP(z)))
 this.Lv=H.vn(x).F2(w,y,null).Ax
 z=J.RE(x)
-if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gUj(x).yI(new K.vQ(this,a,w))}},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.RW]},
-$isRW:true,
+if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gUj(x).yI(new K.vQ(this,a,w))}},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.Jy]},
+$isJy:true,
 $ishw:true},
 WW:{
-"":"Tp:229;",
-call$1:[function(a){return a.gLv()},"call$1",null,2,0,null,123,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return a.gLv()},"call$1",null,2,0,null,123,[],"call"],
 $isEH:true},
 vQ:{
-"":"Tp:558;a,b,c",
-call$1:[function(a){if(J.pb(a,new K.a9(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,581,"call"],
+"^":"Tp:559;a,b,c",
+call$1:[function(a){if(J.pb(a,new K.a9(this.c))===!0)this.a.DX(this.b)},"call$1",null,2,0,null,574,[],"call"],
 $isEH:true},
 a9:{
-"":"Tp:229;d",
+"^":"Tp:223;d",
 call$1:[function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,283,"call"],
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.de(a.oc,this.d)},"call$1",null,2,0,null,278,[],"call"],
 $isEH:true},
 VA:{
-"":"dE;Bb>,T8>,KL,bO,tj,Lv,k6",
+"^":"Mb;Bb<,T8<,KL,bO,tj,Lv,k6",
 Qh:[function(a){var z,y,x,w
 z=this.Bb
 y=this.T8.gLv()
@@ -21436,30 +21722,30 @@
 if(typeof y==="object"&&y!==null&&!!x.$iswn)this.tj=y.gvp().yI(new K.J1(this,a))
 x=J.Vm(z)
 w=y!=null?y:C.xD
-this.Lv=new K.fk(x,w)},"call$1","gVj",2,0,null,270],
-RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,277],
-$asdE:function(){return[U.K9]},
+this.Lv=new K.fk(x,w)},"call$1","gVj",2,0,null,265,[]],
+RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,272,[]],
+$asMb:function(){return[U.K9]},
 $isK9:true,
 $ishw:true},
 J1:{
-"":"Tp:229;a,b",
-call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;a,b",
+call$1:[function(a){return this.a.DX(this.b)},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 fk:{
-"":"a;kF,bm",
+"^":"a;kF,bm",
 $isfk:true},
 wL:{
-"":"a:229;lR,ex",
-call$1:[function(a){return this.lR.F2(this.ex,[a],null).Ax},"call$1","gQl",2,0,null,591],
+"^":"a:223;lR,ex",
+call$1:[function(a){return this.lR.F2(this.ex,[a],null).Ax},"call$1","gtm",2,0,null,584,[]],
 $iswL:true,
 $isEH:true},
 B0:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"EvalException: "+this.G1},"call$0","gXo",0,0,null],
 $isB0:true,
 static:{kG:function(a){return new K.B0(a)}}}}],["polymer_expressions.expression","package:polymer_expressions/expression.dart",,U,{
-"":"",
-Om:[function(a,b){var z,y,x
+"^":"",
+Pu:[function(a,b){var z,y,x
 z=J.x(a)
 if(z.n(a,b))return!0
 if(a==null||b==null)return!1
@@ -21470,106 +21756,106 @@
 if(!(y<x))break
 x=z.t(a,y)
 if(y>=b.length)return H.e(b,y)
-if(!J.de(x,b[y]))return!1;++y}return!0},"call$2","Cb",4,0,null,123,180],
+if(!J.de(x,b[y]))return!1;++y}return!0},"call$2","OE",4,0,null,123,[],180,[]],
 au:[function(a){a.toString
-return U.Up(H.n3(a,0,new U.xs()))},"call$1","bT",2,0,null,279],
+return U.Up(H.n3(a,0,new U.xs()))},"call$1","bT",2,0,null,274,[]],
 Zm:[function(a,b){var z=J.WB(a,b)
 if(typeof z!=="number")return H.s(z)
 a=536870911&z
 a=536870911&a+((524287&a)<<10>>>0)
-return a^a>>>6},"call$2","uN",4,0,null,280,23],
+return a^a>>>6},"call$2","uN",4,0,null,275,[],23,[]],
 Up:[function(a){if(typeof a!=="number")return H.s(a)
 a=536870911&a+((67108863&a)<<3>>>0)
 a=(a^a>>>11)>>>0
-return 536870911&a+((16383&a)<<15>>>0)},"call$1","fM",2,0,null,280],
+return 536870911&a+((16383&a)<<15>>>0)},"call$1","fM",2,0,null,275,[]],
 tc:{
-"":"a;",
-Bf:[function(a,b,c){return new U.zX(b,c)},"call$2","gvH",4,0,592,18,123],
-F2:[function(a,b,c){return new U.RW(a,b,c)},"call$3","gb2",6,0,null,18,183,123]},
+"^":"a;",
+Bf:[function(a,b,c){return new U.zX(b,c)},"call$2","gvH",4,0,585,18,[],123,[]],
+F2:[function(a,b,c){return new U.Jy(a,b,c)},"call$3","gb2",6,0,null,18,[],183,[],123,[]]},
 hw:{
-"":"a;",
+"^":"a;",
 $ishw:true},
 EZ:{
-"":"hw;",
-RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;",
+RR:[function(a,b){return b.W9(this)},"call$1","gBu",2,0,null,272,[]],
 $isEZ:true},
 no:{
-"":"hw;P>",
+"^":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
-RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,277],
+RR:[function(a,b){return b.ti(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){var z=this.P
 return typeof z==="string"?"\""+H.d(z)+"\"":H.d(z)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=H.RB(b,"$isno",[H.Kp(this,0)],"$asno")
-return z&&J.de(J.Vm(b),this.P)},"call$1","gUJ",2,0,null,91],
+return z&&J.de(J.Vm(b),this.P)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.P)},
 $isno:true},
 kB:{
-"":"hw;Pu>",
-RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;Pu>",
+RR:[function(a,b){return b.o0(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"{"+H.d(this.Pu)+"}"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$iskB&&U.Om(z.gPu(b),this.Pu)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$iskB&&U.Pu(z.gPu(b),this.Pu)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return U.au(this.Pu)},
 $iskB:true},
 ae:{
-"":"hw;G3>,v4<",
-RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;G3>,v4<",
+RR:[function(a,b){return b.YV(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.G3)+": "+H.d(this.v4)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isae&&J.de(z.gG3(b),this.G3)&&J.de(b.gv4(),this.v4)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isae&&J.de(z.gG3(b),this.G3)&&J.de(b.gv4(),this.v4)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.G3.P)
 y=J.v1(this.v4)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isae:true},
 XC:{
-"":"hw;wz",
-RR:[function(a,b){return b.LT(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;wz",
+RR:[function(a,b){return b.LT(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.wz)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isXC&&J.de(b.wz,this.wz)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isXC&&J.de(b.wz,this.wz)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.wz)},
 $isXC:true},
 w6:{
-"":"hw;P>",
+"^":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
-RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,277],
+RR:[function(a,b){return b.qv(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return this.P},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isw6&&J.de(z.gP(b),this.P)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isw6&&J.de(z.gP(b),this.P)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){return J.v1(this.P)},
 $isw6:true},
 jK:{
-"":"hw;kp>,wz<",
-RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;kp>,wz<",
+RR:[function(a,b){return b.Hx(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.kp)+" "+H.d(this.wz)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isjK&&J.de(z.gkp(b),this.kp)&&J.de(b.gwz(),this.wz)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isjK&&J.de(z.gkp(b),this.kp)&&J.de(b.gwz(),this.wz)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.kp)
 y=J.v1(this.wz)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isjK:true},
 uk:{
-"":"hw;kp>,Bb>,T8>",
-RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;kp>,Bb<,T8<",
+RR:[function(a,b){return b.im(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.Bb)+" "+H.d(this.kp)+" "+H.d(this.T8)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isuk&&J.de(z.gkp(b),this.kp)&&J.de(z.gBb(b),this.Bb)&&J.de(z.gT8(b),this.T8)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isuk&&J.de(z.gkp(b),this.kp)&&J.de(b.gBb(),this.Bb)&&J.de(b.gT8(),this.T8)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y,x
 z=J.v1(this.kp)
 y=J.v1(this.Bb)
@@ -21577,13 +21863,13 @@
 return U.Up(U.Zm(U.Zm(U.Zm(0,z),y),x))},
 $isuk:true},
 K9:{
-"":"hw;Bb>,T8>",
-RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;Bb<,T8<",
+RR:[function(a,b){return b.ky(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return"("+H.d(this.Bb)+" in "+H.d(this.T8)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
-z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isK9&&J.de(z.gBb(b),this.Bb)&&J.de(z.gT8(b),this.T8)},"call$1","gUJ",2,0,null,91],
+z=J.x(b)
+return typeof b==="object"&&b!==null&&!!z.$isK9&&J.de(b.gBb(),this.Bb)&&J.de(b.gT8(),this.T8)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=this.Bb
 z=z.giO(z)
@@ -21591,64 +21877,64 @@
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isK9:true},
 zX:{
-"":"hw;hP<,Jn<",
-RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;hP<,Jn<",
+RR:[function(a,b){return b.CU(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"["+H.d(this.Jn)+"]"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$iszX&&J.de(b.ghP(),this.hP)&&J.de(b.gJn(),this.Jn)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$iszX&&J.de(b.ghP(),this.hP)&&J.de(b.gJn(),this.Jn)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.hP)
 y=J.v1(this.Jn)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $iszX:true},
 x9:{
-"":"hw;hP<,oc>",
-RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,277],
+"^":"hw;hP<,oc>",
+RR:[function(a,b){return b.co(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"."+H.d(this.oc)},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isx9&&J.de(b.ghP(),this.hP)&&J.de(z.goc(b),this.oc)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isx9&&J.de(b.ghP(),this.hP)&&J.de(z.goc(b),this.oc)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y
 z=J.v1(this.hP)
 y=J.v1(this.oc)
 return U.Up(U.Zm(U.Zm(0,z),y))},
 $isx9:true},
-RW:{
-"":"hw;hP<,bP>,re<",
-RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,277],
+Jy:{
+"^":"hw;hP<,bP>,re<",
+RR:[function(a,b){return b.ZR(this)},"call$1","gBu",2,0,null,272,[]],
 bu:[function(a){return H.d(this.hP)+"."+H.d(this.bP)+"("+H.d(this.re)+")"},"call$0","gXo",0,0,null],
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
-return typeof b==="object"&&b!==null&&!!z.$isRW&&J.de(b.ghP(),this.hP)&&J.de(z.gbP(b),this.bP)&&U.Om(b.gre(),this.re)},"call$1","gUJ",2,0,null,91],
+return typeof b==="object"&&b!==null&&!!z.$isJy&&J.de(b.ghP(),this.hP)&&J.de(z.gbP(b),this.bP)&&U.Pu(b.gre(),this.re)},"call$1","gUJ",2,0,null,91,[]],
 giO:function(a){var z,y,x
 z=J.v1(this.hP)
 y=J.v1(this.bP)
 x=U.au(this.re)
 return U.Up(U.Zm(U.Zm(U.Zm(0,z),y),x))},
-$isRW:true},
+$isJy:true},
 xs:{
-"":"Tp:349;",
-call$2:[function(a,b){return U.Zm(a,J.v1(b))},"call$2",null,4,0,null,593,594,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){return U.Zm(a,J.v1(b))},"call$2",null,4,0,null,586,[],587,[],"call"],
 $isEH:true}}],["polymer_expressions.parser","package:polymer_expressions/parser.dart",,T,{
-"":"",
+"^":"",
 FX:{
-"":"a;Sk,ks,ku,fL",
+"^":"a;Sk,GP,qM,fL",
 XJ:[function(a,b){var z
 if(!(a!=null&&!J.de(J.Iz(this.fL.lo),a)))z=b!=null&&!J.de(J.Vm(this.fL.lo),b)
 else z=!0
 if(z)throw H.b(Y.RV("Expected "+b+": "+H.d(this.fL.lo)))
-this.fL.G()},function(){return this.XJ(null,null)},"w5","call$2",null,"gnp",0,4,null,77,77,530,23],
+this.fL.G()},function(){return this.XJ(null,null)},"w5","call$2",null,"gXO",0,4,null,77,77,588,[],23,[]],
 o9:[function(){if(this.fL.lo==null){this.Sk.toString
 return C.OL}var z=this.Dl()
 return z==null?null:this.BH(z,0)},"call$0","gKx",0,0,null],
 BH:[function(a,b){var z,y,x,w,v
 for(z=this.Sk;y=this.fL.lo,y!=null;)if(J.de(J.Iz(y),9))if(J.de(J.Vm(this.fL.lo),"(")){x=this.qj()
 z.toString
-a=new U.RW(a,null,x)}else if(J.de(J.Vm(this.fL.lo),"[")){w=this.eY()
+a=new U.Jy(a,null,x)}else if(J.de(J.Vm(this.fL.lo),"[")){w=this.eY()
 z.toString
 a=new U.zX(a,w)}else break
 else if(J.de(J.Iz(this.fL.lo),3)){this.w5()
@@ -21659,18 +21945,18 @@
 z.toString
 a=new U.K9(a,v)}else if(J.de(J.Iz(this.fL.lo),8)&&J.J5(this.fL.lo.gG8(),b))a=this.Tw(a)
 else break
-return a},"call$2","gHr",4,0,null,126,595],
+return a},"call$2","gHr",4,0,null,126,[],589,[]],
 qL:[function(a,b){var z,y
 if(typeof b==="object"&&b!==null&&!!b.$isw6){z=b.gP(b)
 this.Sk.toString
-return new U.x9(a,z)}else{if(typeof b==="object"&&b!==null&&!!b.$isRW){z=b.ghP()
+return new U.x9(a,z)}else{if(typeof b==="object"&&b!==null&&!!b.$isJy){z=b.ghP()
 y=J.x(z)
 y=typeof z==="object"&&z!==null&&!!y.$isw6
 z=y}else z=!1
 if(z){z=J.Vm(b.ghP())
 y=b.gre()
 this.Sk.toString
-return new U.RW(a,z,y)}else throw H.b(Y.RV("expected identifier: "+H.d(b)))}},"call$2","gE5",4,0,null,126,127],
+return new U.Jy(a,z,y)}else throw H.b(Y.RV("expected identifier: "+H.d(b)))}},"call$2","gE5",4,0,null,126,[],127,[]],
 Tw:[function(a){var z,y,x
 z=this.fL.lo
 this.w5()
@@ -21681,7 +21967,7 @@
 if(!x)break
 y=this.BH(y,this.fL.lo.gG8())}x=J.Vm(z)
 this.Sk.toString
-return new U.uk(x,a,y)},"call$1","gvB",2,0,null,126],
+return new U.uk(x,a,y)},"call$1","gvB",2,0,null,126,[]],
 Dl:[function(){var z,y,x,w
 if(J.de(J.Iz(this.fL.lo),8)){z=J.Vm(this.fL.lo)
 y=J.x(z)
@@ -21750,7 +22036,7 @@
 y=new U.w6(z)
 x=this.qj()
 if(x==null)return y
-else return new U.RW(y,null,x)},"call$0","gbc",0,0,null],
+else return new U.Jy(y,null,x)},"call$0","gbc",0,0,null],
 qj:[function(){var z,y
 z=this.fL.lo
 if(z!=null&&J.de(J.Iz(z),9)&&J.de(J.Vm(this.fL.lo),"(")){y=[]
@@ -21759,7 +22045,7 @@
 y.push(this.o9())
 z=this.fL.lo}while(z!=null&&J.de(J.Vm(z),","))
 this.XJ(9,")")
-return y}return},"call$0","gwm",0,0,null],
+return y}return},"call$0","gxZ",0,0,null],
 eY:[function(){var z,y
 z=this.fL.lo
 if(z!=null&&J.de(J.Iz(z),9)&&J.de(J.Vm(this.fL.lo),"[")){this.w5()
@@ -21777,31 +22063,31 @@
 this.Sk.toString
 y=H.VM(new U.no(z),[null])
 this.w5()
-return y},function(){return this.pT("")},"Ud","call$1",null,"gwo",0,2,null,334,596],
-yj:[function(a){var z,y
+return y},function(){return this.pT("")},"Ud","call$1",null,"gwo",0,2,null,328,590,[]],
+Fj:[function(a){var z,y
 z=H.IH(H.d(a)+H.d(J.Vm(this.fL.lo)),null)
 this.Sk.toString
 y=H.VM(new U.no(z),[null])
 this.w5()
-return y},function(){return this.yj("")},"tw","call$1",null,"gSE",0,2,null,334,596]}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{
-"":"",
-Dc:[function(a){return H.VM(new K.Bt(a),[null])},"call$1","UM",2,0,281,109],
+return y},function(){return this.Fj("")},"tw","call$1",null,"gSE",0,2,null,328,590,[]]}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{
+"^":"",
+Dc:[function(a){return H.VM(new K.Bt(a),[null])},"call$1","UM",2,0,276,109,[]],
 Ae:{
-"":"a;vH>-476,P>-597",
+"^":"a;vH>-475,P>-591",
 r6:function(a,b){return this.P.call$1(b)},
 n:[function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
-return typeof b==="object"&&b!==null&&!!z.$isAe&&J.de(b.vH,this.vH)&&J.de(b.P,this.P)},"call$1","gUJ",2,0,229,91,"=="],
-giO:[function(a){return J.v1(this.P)},null,null,1,0,478,"hashCode"],
-bu:[function(a){return"("+H.d(this.vH)+", "+H.d(this.P)+")"},"call$0","gXo",0,0,369,"toString"],
+return typeof b==="object"&&b!==null&&!!z.$isAe&&J.de(b.vH,this.vH)&&J.de(b.P,this.P)},"call$1","gUJ",2,0,223,91,[],"=="],
+giO:[function(a){return J.v1(this.P)},null,null,1,0,482,"hashCode"],
+bu:[function(a){return"("+H.d(this.vH)+", "+H.d(this.P)+")"},"call$0","gXo",0,0,362,"toString"],
 $isAe:true,
 "@":function(){return[C.nJ]},
 "<>":[3],
-static:{i0:[function(a,b,c){return H.VM(new K.Ae(a,b),[c])},null,null,4,0,function(){return H.IG(function(a){return{func:"GR",args:[J.im,a]}},this.$receiver,"Ae")},47,23,"new IndexedValue" /* new IndexedValue:2:0 */]}},
+static:{i0:[function(a,b,c){return H.VM(new K.Ae(a,b),[c])},null,null,4,0,function(){return H.IG(function(a){return{func:"GR",args:[J.im,a]}},this.$receiver,"Ae")},47,[],23,[],"new IndexedValue"]}},
 "+IndexedValue":[0],
 Bt:{
-"":"mW;YR",
+"^":"mW;YR",
 gA:function(a){var z=new K.vR(J.GP(this.YR),0,null)
 z.$builtinTypeInfo=this.$builtinTypeInfo
 return z},
@@ -21815,11 +22101,11 @@
 return z},
 Zv:[function(a,b){var z=new K.Ae(b,J.i4(this.YR,b))
 z.$builtinTypeInfo=this.$builtinTypeInfo
-return z},"call$1","goY",2,0,null,47],
+return z},"call$1","goY",2,0,null,47,[]],
 $asmW:function(a){return[[K.Ae,a]]},
 $ascX:function(a){return[[K.Ae,a]]}},
 vR:{
-"":"Yl;WS,wX,CD",
+"^":"Yl;WS,wX,CD",
 gl:function(){return this.CD},
 G:[function(){var z,y
 z=this.WS
@@ -21827,33 +22113,33 @@
 this.wX=y+1
 this.CD=H.VM(new K.Ae(y,z.gl()),[null])
 return!0}this.CD=null
-return!1},"call$0","guK",0,0,null],
+return!1},"call$0","gqy",0,0,null],
 $asYl:function(a){return[[K.Ae,a]]}}}],["polymer_expressions.src.mirrors","package:polymer_expressions/src/mirrors.dart",,Z,{
-"":"",
+"^":"",
 y1:[function(a,b){var z,y,x
 if(a.gYK().nb.x4(b))return a.gYK().nb.t(0,b)
 z=a.gAY()
-if(z!=null&&!J.de(z.gvd(),C.PU)){y=Z.y1(a.gAY(),b)
+if(z!=null&&!J.de(z.gUx(),C.PU)){y=Z.y1(a.gAY(),b)
 if(y!=null)return y}for(x=J.GP(a.gkZ());x.G();){y=Z.y1(x.lo,b)
-if(y!=null)return y}return},"call$2","tm",4,0,null,282,12]}],["polymer_expressions.tokenizer","package:polymer_expressions/tokenizer.dart",,Y,{
-"":"",
+if(y!=null)return y}return},"call$2","tm",4,0,null,277,[],12,[]]}],["polymer_expressions.tokenizer","package:polymer_expressions/tokenizer.dart",,Y,{
+"^":"",
 aK:[function(a){switch(a){case 102:return 12
 case 110:return 10
 case 114:return 13
 case 116:return 9
 case 118:return 11
-default:return a}},"call$1","aN",2,0,null,283],
+default:return a}},"call$1","aN",2,0,null,278,[]],
 Pn:{
-"":"a;fY>,P>,G8<",
+"^":"a;fY>,P>,G8<",
 r6:function(a,b){return this.P.call$1(b)},
 bu:[function(a){return"("+this.fY+", '"+this.P+"')"},"call$0","gXo",0,0,null],
 $isPn:true},
 hc:{
-"":"a;MV,zy,jI,x0",
+"^":"a;MV,zy,jI,VQ",
 zl:[function(){var z,y,x,w,v,u,t,s,r
 z=this.jI
-this.x0=z.G()?z.Wn:null
-for(y=this.MV;x=this.x0,x!=null;)if(x===32||x===9||x===160)this.x0=z.G()?z.Wn:null
+this.VQ=z.G()?z.Wn:null
+for(y=this.MV;x=this.VQ,x!=null;)if(x===32||x===9||x===160)this.VQ=z.G()?z.Wn:null
 else if(x===34||x===39)this.DS()
 else{if(typeof x!=="number")return H.s(x)
 if(!(97<=x&&x<=122))w=65<=x&&x<=90||x===95||x===36||x>127
@@ -21861,44 +22147,44 @@
 if(w)this.zI()
 else if(48<=x&&x<=57)this.jj()
 else if(x===46){x=z.G()?z.Wn:null
-this.x0=x
+this.VQ=x
 if(typeof x!=="number")return H.s(x)
 if(48<=x&&x<=57)this.e1()
-else y.push(new Y.Pn(3,".",11))}else if(x===44){this.x0=z.G()?z.Wn:null
-y.push(new Y.Pn(4,",",0))}else if(x===58){this.x0=z.G()?z.Wn:null
-y.push(new Y.Pn(5,":",0))}else if(C.Nm.tg(C.xu,x)){v=this.x0
+else y.push(new Y.Pn(3,".",11))}else if(x===44){this.VQ=z.G()?z.Wn:null
+y.push(new Y.Pn(4,",",0))}else if(x===58){this.VQ=z.G()?z.Wn:null
+y.push(new Y.Pn(5,":",0))}else if(C.Nm.tg(C.xu,x)){v=this.VQ
 x=z.G()?z.Wn:null
-this.x0=x
-if(C.Nm.tg(C.xu,x)){x=this.x0
+this.VQ=x
+if(C.Nm.tg(C.xu,x)){x=this.VQ
 u=H.eT([v,x])
-if(C.Nm.tg(C.u0,u)){this.x0=z.G()?z.Wn:null
+if(C.Nm.tg(C.u0,u)){this.VQ=z.G()?z.Wn:null
 t=u}else{s=P.O8(1,v,J.im)
 t=H.eT(s)}}else{s=P.O8(1,v,J.im)
-t=H.eT(s)}y.push(new Y.Pn(8,t,C.dj.t(0,t)))}else if(C.Nm.tg(C.iq,this.x0)){s=P.O8(1,this.x0,J.im)
+t=H.eT(s)}y.push(new Y.Pn(8,t,C.dj.t(0,t)))}else if(C.Nm.tg(C.iq,this.VQ)){s=P.O8(1,this.VQ,J.im)
 r=H.eT(s)
 y.push(new Y.Pn(9,r,C.dj.t(0,r)))
-this.x0=z.G()?z.Wn:null}else this.x0=z.G()?z.Wn:null}return y},"call$0","gty",0,0,null],
+this.VQ=z.G()?z.Wn:null}else this.VQ=z.G()?z.Wn:null}return y},"call$0","gty",0,0,null],
 DS:[function(){var z,y,x,w,v
-z=this.x0
+z=this.VQ
 y=this.jI
 x=y.G()?y.Wn:null
-this.x0=x
+this.VQ=x
 for(w=this.zy;x==null?z!=null:x!==z;){if(x==null)throw H.b(Y.RV("unterminated string"))
 if(x===92){x=y.G()?y.Wn:null
-this.x0=x
+this.VQ=x
 if(x==null)throw H.b(Y.RV("unterminated string"))
 v=P.O8(1,Y.aK(x),J.im)
 x=H.eT(v)
 w.vM=w.vM+x}else{v=P.O8(1,x,J.im)
 x=H.eT(v)
 w.vM=w.vM+x}x=y.G()?y.Wn:null
-this.x0=x}this.MV.push(new Y.Pn(1,w.vM,0))
+this.VQ=x}this.MV.push(new Y.Pn(1,w.vM,0))
 w.vM=""
-this.x0=y.G()?y.Wn:null},"call$0","gxs",0,0,null],
+this.VQ=y.G()?y.Wn:null},"call$0","gxs",0,0,null],
 zI:[function(){var z,y,x,w,v,u
 z=this.jI
 y=this.zy
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 if(!(97<=x&&x<=122))if(!(65<=x&&x<=90))w=48<=x&&x<=57||x===95||x===36||x>127
 else w=!0
@@ -21907,7 +22193,7 @@
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 y.vM=y.vM+x
-this.x0=z.G()?z.Wn:null}u=y.vM
+this.VQ=z.G()?z.Wn:null}u=y.vM
 z=this.MV
 if(C.Nm.tg(C.Qy,u))z.push(new Y.Pn(10,u,0))
 else z.push(new Y.Pn(2,u,0))
@@ -21915,15 +22201,15 @@
 jj:[function(){var z,y,x,w,v
 z=this.jI
 y=this.zy
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 w=48<=x&&x<=57}else w=!1
 if(!w)break
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 y.vM=y.vM+x
-this.x0=z.G()?z.Wn:null}if(x===46){z=z.G()?z.Wn:null
-this.x0=z
+this.VQ=z.G()?z.Wn:null}if(x===46){z=z.G()?z.Wn:null
+this.VQ=z
 if(typeof z!=="number")return H.s(z)
 if(48<=z&&z<=57)this.e1()
 else this.MV.push(new Y.Pn(3,".",11))}else{this.MV.push(new Y.Pn(6,y.vM,0))
@@ -21932,57 +22218,57 @@
 z=this.zy
 z.KF(P.fc(46))
 y=this.jI
-while(!0){x=this.x0
+while(!0){x=this.VQ
 if(x!=null){if(typeof x!=="number")return H.s(x)
 w=48<=x&&x<=57}else w=!1
 if(!w)break
 v=P.O8(1,x,J.im)
 x=H.eT(v)
 z.vM=z.vM+x
-this.x0=y.G()?y.Wn:null}this.MV.push(new Y.Pn(7,z.vM,0))
+this.VQ=y.G()?y.Wn:null}this.MV.push(new Y.Pn(7,z.vM,0))
 z.vM=""},"call$0","gba",0,0,null]},
 hA:{
-"":"a;G1>",
+"^":"a;G1>",
 bu:[function(a){return"ParseException: "+this.G1},"call$0","gXo",0,0,null],
 static:{RV:function(a){return new Y.hA(a)}}}}],["polymer_expressions.visitor","package:polymer_expressions/visitor.dart",,S,{
-"":"",
+"^":"",
 fr:{
-"":"a;",
-DV:[function(a){return J.UK(a,this)},"call$1","gnG",2,0,598,86]},
-a0:{
-"":"fr;",
-W9:[function(a){return this.xn(a)},"call$1","glO",2,0,null,18],
+"^":"a;",
+DV:[function(a){return J.UK(a,this)},"call$1","gnG",2,0,592,86,[]]},
+cfS:{
+"^":"fr;",
+W9:[function(a){return this.xn(a)},"call$1","glO",2,0,null,18,[]],
 LT:[function(a){a.wz.RR(0,this)
-this.xn(a)},"call$1","gff",2,0,null,18],
+this.xn(a)},"call$1","gff",2,0,null,18,[]],
 co:[function(a){J.UK(a.ghP(),this)
-this.xn(a)},"call$1","gfz",2,0,null,341],
+this.xn(a)},"call$1","gEW",2,0,null,383,[]],
 CU:[function(a){J.UK(a.ghP(),this)
 J.UK(a.gJn(),this)
-this.xn(a)},"call$1","gA2",2,0,null,341],
+this.xn(a)},"call$1","gA2",2,0,null,383,[]],
 ZR:[function(a){var z
 J.UK(a.ghP(),this)
 z=a.gre()
 if(z!=null)for(z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.UK(z.lo,this)
-this.xn(a)},"call$1","gZo",2,0,null,341],
-ti:[function(a){return this.xn(a)},"call$1","gXj",2,0,null,279],
+this.xn(a)},"call$1","gES",2,0,null,383,[]],
+ti:[function(a){return this.xn(a)},"call$1","gXj",2,0,null,274,[]],
 o0:[function(a){var z
 for(z=a.gPu(a),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.UK(z.lo,this)
-this.xn(a)},"call$1","gX7",2,0,null,279],
+this.xn(a)},"call$1","gX7",2,0,null,274,[]],
 YV:[function(a){J.UK(a.gG3(a),this)
 J.UK(a.gv4(),this)
-this.xn(a)},"call$1","gbU",2,0,null,18],
-qv:[function(a){return this.xn(a)},"call$1","gFs",2,0,null,341],
-im:[function(a){J.UK(a.gBb(a),this)
-J.UK(a.gT8(a),this)
-this.xn(a)},"call$1","glf",2,0,null,91],
+this.xn(a)},"call$1","gbU",2,0,null,18,[]],
+qv:[function(a){return this.xn(a)},"call$1","gFs",2,0,null,383,[]],
+im:[function(a){J.UK(a.gBb(),this)
+J.UK(a.gT8(),this)
+this.xn(a)},"call$1","glf",2,0,null,91,[]],
 Hx:[function(a){J.UK(a.gwz(),this)
-this.xn(a)},"call$1","gKY",2,0,null,91],
-ky:[function(a){J.UK(a.gBb(a),this)
-J.UK(a.gT8(a),this)
-this.xn(a)},"call$1","gXf",2,0,null,283]}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{
-"":"",
-NQ:{
-"":["uL;hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+this.xn(a)},"call$1","gKY",2,0,null,91,[]],
+ky:[function(a){J.UK(a.gBb(),this)
+J.UK(a.gT8(),this)
+this.xn(a)},"call$1","gXf",2,0,null,278,[]]}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{
+"^":"",
+JG:{
+"^":["uL;hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.Is]},
 static:{Zo:[function(a){var z,y,x,w
 z=$.Nd()
@@ -21992,44 +22278,69 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.Cc.ZL(a)
-C.Cc.oX(a)
-return a},null,null,0,0,108,"new ResponseViewerElement$created" /* new ResponseViewerElement$created:0:0 */]}},
-"+ResponseViewerElement":[475]}],["script_ref_element","package:observatory/src/observatory_elements/script_ref.dart",,A,{
-"":"",
+C.Cc.G6(a)
+return a},null,null,0,0,108,"new ResponseViewerElement$created"]}},
+"+ResponseViewerElement":[474]}],["script_ref_element","package:observatory/src/observatory_elements/script_ref.dart",,A,{
+"^":"",
 knI:{
-"":["xI;tY-355,Pe-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-"@":function(){return[C.h9]},
+"^":["qe;zw%-475,AP,fn,tY-347,Pe-355,m0-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gRd:[function(a){return a.zw},null,null,1,0,482,"line",351,352],
+sRd:[function(a,b){a.zw=this.ct(a,C.Cv,a.zw,b)},null,null,3,0,385,23,[],"line",351],
+gO3:[function(a){var z
+if(a.hm!=null&&a.tY!=null){z=this.Mq(a,J.UQ(a.tY,"id"))
+if(J.u6(a.zw,0))return z
+else return z+"?line="+H.d(a.zw)}return""},null,null,1,0,362,"url"],
+gJp:[function(a){var z,y
+if(a.tY==null)return""
+z=J.u6(a.zw,0)
+y=a.tY
+if(z)return J.UQ(y,"user_name")
+else return H.d(J.UQ(y,"user_name"))+":"+H.d(a.zw)},null,null,1,0,362,"hoverText"],
+goc:[function(a){var z,y,x
+z=a.tY
+if(z==null)return""
+y=J.UQ(z,"user_name")
+z=J.U6(y)
+x=z.yn(y,J.WB(z.cn(y,"/"),1))
+if(J.u6(a.zw,0))return x
+else return x+":"+H.d(a.zw)},null,null,1,0,362,"name"],
+"@":function(){return[C.Ur]},
 static:{Th:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
 x=J.O
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
+a.zw=-1
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.c0.ZL(a)
-C.c0.oX(a)
-return a},null,null,0,0,108,"new ScriptRefElement$created" /* new ScriptRefElement$created:0:0 */]}},
-"+ScriptRefElement":[364]}],["script_view_element","package:observatory/src/observatory_elements/script_view.dart",,U,{
-"":"",
+C.c0.G6(a)
+return a},null,null,0,0,108,"new ScriptRefElement$created"]}},
+"+ScriptRefElement":[593],
+qe:{
+"^":"xI+Pi;",
+$isd3:true}}],["script_view_element","package:observatory/src/observatory_elements/script_view.dart",,U,{
+"^":"",
 fI:{
-"":["V12;Uz%-599,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gMU:[function(a){return a.Uz},null,null,1,0,600,"script",359,360],
-sMU:[function(a,b){a.Uz=this.ct(a,C.fX,a.Uz,b)},null,null,3,0,601,23,"script",359],
+"^":["V13;Uz%-594,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gNl:[function(a){return a.Uz},null,null,1,0,595,"script",351,352],
+sNl:[function(a,b){a.Uz=this.ct(a,C.fX,a.Uz,b)},null,null,3,0,596,23,[],"script",351],
 PQ:[function(a,b){if(J.de(b.gu9(),-1))return"min-width:32px;"
 else if(J.de(b.gu9(),0))return"min-width:32px;background-color:red"
-return"min-width:32px;background-color:green"},"call$1","gXa",2,0,602,173,"hitsStyle"],
+return"min-width:32px;background-color:green"},"call$1","gXa",2,0,597,173,[],"hitsStyle"],
 wH:[function(a,b,c,d){var z,y,x
 z=a.hm.gZ6().R6()
 y=a.hm.gnI().AQ(z)
 if(y==null){N.Jx("").To("No isolate found.")
 return}x="/"+z+"/coverage"
-a.hm.glw().fB(x).ml(new U.qq(a,y)).OA(new U.FC())},"call$3","gWp",6,0,376,18,307,74,"refreshCoverage"],
-"@":function(){return[C.Er]},
+a.hm.gDF().fB(x).ml(new U.qq(a,y)).OA(new U.FC())},"call$3","gWp",6,0,369,18,[],301,[],74,[],"refreshCoverage"],
+"@":function(){return[C.I3]},
 static:{Ry:[function(a){var z,y,x,w
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -22038,53 +22349,60 @@
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.SO=z
 a.B7=y
-a.ZQ=w
+a.X0=w
 C.cJ.ZL(a)
-C.cJ.oX(a)
-return a},null,null,0,0,108,"new ScriptViewElement$created" /* new ScriptViewElement$created:0:0 */]}},
-"+ScriptViewElement":[603],
-V12:{
-"":"uL+Pi;",
+C.cJ.G6(a)
+return a},null,null,0,0,108,"new ScriptViewElement$created"]}},
+"+ScriptViewElement":[598],
+V13:{
+"^":"uL+Pi;",
 $isd3:true},
 qq:{
-"":"Tp:361;a-77,b-77",
+"^":"Tp:353;a-77,b-77",
 call$1:[function(a){var z,y
 this.b.oe(J.UQ(a,"coverage"))
 z=this.a
 y=J.RE(z)
-y.ct(z,C.YH,"",y.gXa(z))},"call$1",null,2,0,361,604,"call"],
+y.ct(z,C.YH,"",y.gXa(z))},"call$1",null,2,0,353,599,[],"call"],
 $isEH:true},
-"+ScriptViewElement_refreshCoverage_closure":[471],
+"+ScriptViewElement_refreshCoverage_closure":[467],
 FC:{
-"":"Tp:349;",
-call$2:[function(a,b){P.JS("refreshCoverage "+H.d(a)+" "+H.d(b))},"call$2",null,4,0,349,18,472,"call"],
+"^":"Tp:341;",
+call$2:[function(a,b){P.JS("refreshCoverage "+H.d(a)+" "+H.d(b))},"call$2",null,4,0,341,18,[],468,[],"call"],
 $isEH:true},
-"+ScriptViewElement_refreshCoverage_closure":[471]}],["service_ref_element","package:observatory/src/observatory_elements/service_ref.dart",,Q,{
-"":"",
+"+ScriptViewElement_refreshCoverage_closure":[467]}],["service_ref_element","package:observatory/src/observatory_elements/service_ref.dart",,Q,{
+"^":"",
 xI:{
-"":["Ds;tY%-355,Pe%-363,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gnv:[function(a){return a.tY},null,null,1,0,358,"ref",359,360],
-snv:[function(a,b){a.tY=this.ct(a,C.kY,a.tY,b)},null,null,3,0,361,23,"ref",359],
-gtb:[function(a){return a.Pe},null,null,1,0,373,"internal",359,360],
-stb:[function(a,b){a.Pe=this.ct(a,C.zD,a.Pe,b)},null,null,3,0,374,23,"internal",359],
+"^":["Ds;tY%-347,Pe%-355,m0%-356,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gnv:[function(a){return a.tY},null,null,1,0,350,"ref",351,352],
+snv:[function(a,b){a.tY=this.ct(a,C.kY,a.tY,b)},null,null,3,0,353,23,[],"ref",351],
+gjT:[function(a){return a.Pe},null,null,1,0,366,"internal",351,352],
+sjT:[function(a,b){a.Pe=this.ct(a,C.zD,a.Pe,b)},null,null,3,0,367,23,[],"internal",351],
+gAq:[function(a){return a.m0},null,null,1,0,493,"isolate",351,352],
+sAq:[function(a,b){a.m0=this.ct(a,C.Z8,a.m0,b)},null,null,3,0,494,23,[],"isolate",351],
 aZ:[function(a,b){this.ct(a,C.Fh,"",this.gO3(a))
 this.ct(a,C.YS,[],this.goc(a))
-this.ct(a,C.bA,"",this.gJp(a))},"call$1","gma",2,0,152,231,"refChanged"],
-gO3:[function(a){var z=a.hm
-if(z!=null&&a.tY!=null)return z.gZ6().kP(J.UQ(a.tY,"id"))
-return""},null,null,1,0,369,"url"],
+this.ct(a,C.bA,"",this.gJp(a))},"call$1","gma",2,0,150,225,[],"refChanged"],
+gO3:[function(a){var z=a.tY
+if(z!=null)return this.Mq(a,J.UQ(z,"id"))
+return""},null,null,1,0,362,"url"],
 gJp:[function(a){var z,y
 z=a.tY
 if(z==null)return""
 y=J.UQ(z,"name")
-return y!=null?y:""},null,null,1,0,369,"hoverText"],
+return y!=null?y:""},null,null,1,0,362,"hoverText"],
 goc:[function(a){var z,y
 z=a.tY
 if(z==null)return""
 y=a.Pe===!0?"name":"user_name"
 if(J.UQ(z,y)!=null)return J.UQ(a.tY,y)
 else if(J.UQ(a.tY,"name")!=null)return J.UQ(a.tY,"name")
-return""},null,null,1,0,369,"name"],
+return""},null,null,1,0,362,"name"],
+tx:[function(a,b){this.ct(a,C.bD,0,1)},"call$1","gQ1",2,0,150,225,[],"isolateChanged"],
+Mq:[function(a,b){var z=a.hm
+if(z==null)return""
+else if(a.m0==null)return z.gZ6().kP(b)
+else return J.uY(z.gZ6(),J.F8(a.m0),b)},"call$1","gLc",2,0,504,505,[],"relativeLink",365],
 "@":function(){return[C.JD]},
 static:{lK:[function(a){var z,y,x,w
 z=$.Nd()
@@ -22093,22 +22411,27 @@
 w=W.cv
 w=H.VM(new V.qC(P.Py(null,null,null,x,w),null,null),[x,w])
 a.Pe=!1
+a.m0=null
 a.SO=z
 a.B7=y
-a.ZQ=w
-C.ep.ZL(a)
-C.ep.oX(a)
-return a},null,null,0,0,108,"new ServiceRefElement$created" /* new ServiceRefElement$created:0:0 */]}},
-"+ServiceRefElement":[605],
+a.X0=w
+C.wU.ZL(a)
+C.wU.G6(a)
+return a},null,null,0,0,108,"new ServiceRefElement$created"]}},
+"+ServiceRefElement":[600],
 Ds:{
-"":"uL+Pi;",
+"^":"uL+Pi;",
 $isd3:true}}],["stack_frame_element","package:observatory/src/observatory_elements/stack_frame.dart",,K,{
-"":"",
+"^":"",
 nm:{
-"":["V13;Va%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gz1:[function(a){return a.Va},null,null,1,0,358,"frame",359,360],
-sz1:[function(a,b){a.Va=this.ct(a,C.rE,a.Va,b)},null,null,3,0,361,23,"frame",359],
-"@":function(){return[C.Xv]},
+"^":["V14;Va%-347,Mt%-355,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gz1:[function(a){return a.Va},null,null,1,0,350,"frame",351,352],
+sz1:[function(a,b){a.Va=this.ct(a,C.rE,a.Va,b)},null,null,3,0,353,23,[],"frame",351],
+goE:[function(a){return a.Mt},null,null,1,0,366,"expanded",351,352],
+soE:[function(a,b){a.Mt=this.ct(a,C.mr,a.Mt,b)},null,null,3,0,367,23,[],"expanded",351],
+AZ:[function(a,b,c,d){var z=a.Mt
+a.Mt=this.ct(a,C.mr,z,z!==!0)},"call$3","ghM",6,0,470,123,[],180,[],278,[],"toggleExpand"],
+"@":function(){return[C.pE]},
 static:{an:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -22118,23 +22441,26 @@
 v=W.cv
 v=H.VM(new V.qC(P.Py(null,null,null,w,v),null,null),[w,v])
 a.Va=z
+a.Mt=!1
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.dX.ZL(a)
-C.dX.oX(a)
-return a},null,null,0,0,108,"new StackFrameElement$created" /* new StackFrameElement$created:0:0 */]}},
-"+StackFrameElement":[606],
-V13:{
-"":"uL+Pi;",
+C.dX.G6(a)
+return a},null,null,0,0,108,"new StackFrameElement$created"]}},
+"+StackFrameElement":[601],
+V14:{
+"^":"uL+Pi;",
 $isd3:true}}],["stack_trace_element","package:observatory/src/observatory_elements/stack_trace.dart",,X,{
-"":"",
+"^":"",
 Vu:{
-"":["V14;V4%-355,AP,fn,hm-356,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ-357",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gtN:[function(a){return a.V4},null,null,1,0,358,"trace",359,360],
-stN:[function(a,b){a.V4=this.ct(a,C.kw,a.V4,b)},null,null,3,0,361,23,"trace",359],
+"^":["V15;V4%-347,AP,fn,hm-348,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0-349",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gtN:[function(a){return a.V4},null,null,1,0,350,"trace",351,352],
+stN:[function(a,b){a.V4=this.ct(a,C.kw,a.V4,b)},null,null,3,0,353,23,[],"trace",351],
+Ak:[function(a,b,c,d){var z=a.hm.gZ6().kP("stacktrace")
+a.hm.gDF().fB(z).ml(new X.At(a)).OA(new X.Sb())},"call$3","gBq",6,0,369,18,[],301,[],74,[],"refresh"],
 "@":function(){return[C.js]},
-static:{bV:[function(a){var z,y,x,w,v
+static:{B4:[function(a){var z,y,x,w,v
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
 y=$.Nd()
@@ -22145,20 +22471,33 @@
 a.V4=z
 a.SO=y
 a.B7=x
-a.ZQ=v
+a.X0=v
 C.bg.ZL(a)
-C.bg.oX(a)
-return a},null,null,0,0,108,"new StackTraceElement$created" /* new StackTraceElement$created:0:0 */]}},
-"+StackTraceElement":[607],
-V14:{
-"":"uL+Pi;",
-$isd3:true}}],["template_binding","package:template_binding/template_binding.dart",,M,{
-"":"",
+C.bg.G6(a)
+return a},null,null,0,0,108,"new StackTraceElement$created"]}},
+"+StackTraceElement":[602],
+V15:{
+"^":"uL+Pi;",
+$isd3:true},
+At:{
+"^":"Tp:223;a-77",
+call$1:[function(a){var z,y
+z=this.a
+y=J.RE(z)
+y.sV4(z,y.ct(z,C.kw,y.gV4(z),a))},"call$1",null,2,0,223,144,[],"call"],
+$isEH:true},
+"+StackTraceElement_refresh_closure":[467],
+Sb:{
+"^":"Tp:341;",
+call$2:[function(a,b){N.Jx("").hh("Error while reloading stack trace: "+H.d(a)+"\n"+H.d(b))},"call$2",null,4,0,341,18,[],472,[],"call"],
+$isEH:true},
+"+StackTraceElement_refresh_closure":[467]}],["template_binding","package:template_binding/template_binding.dart",,M,{
+"^":"",
 IP:[function(a){var z=J.RE(a)
 if(typeof a==="object"&&a!==null&&!!z.$isQl)return C.i3.f0(a)
 switch(z.gt5(a)){case"checkbox":return $.FF().aM(a)
 case"radio":case"select-multiple":case"select-one":return z.gi9(a)
-default:return z.gLm(a)}},"call$1","IU",2,0,null,124],
+default:return z.gLm(a)}},"call$1","nc",2,0,null,124,[]],
 iX:[function(a,b){var z,y,x,w,v,u,t,s
 z=M.pN(a,b)
 y=J.x(a)
@@ -22170,7 +22509,7 @@
 if(s==null)continue
 if(u==null)u=P.Py(null,null,null,null,null)
 u.u(0,t,s)}if(z==null&&u==null&&w==null)return
-return new M.XI(z,u,w,t)},"call$2","Nc",4,0,null,265,284],
+return new M.XI(z,u,w,t)},"call$2","Nc",4,0,null,259,[],279,[]],
 HP:[function(a,b,c,d,e){var z,y,x
 if(b==null)return
 if(b.gN2()!=null){z=b.gN2()
@@ -22180,16 +22519,16 @@
 if(z.gwd(b)==null)return
 y=b.gTe()-a.childNodes.length
 for(x=a.firstChild;x!=null;x=x.nextSibling,++y){if(y<0)continue
-M.HP(x,J.UQ(z.gwd(b),y),c,d,e)}},"call$5","Yy",10,0,null,265,144,285,284,286],
+M.HP(x,J.UQ(z.gwd(b),y),c,d,e)}},"call$5","Yy",10,0,null,259,[],144,[],280,[],279,[],281,[]],
 bM:[function(a){var z
 for(;z=J.RE(a),z.gKV(a)!=null;)a=z.gKV(a)
 if(typeof a==="object"&&a!==null&&!!z.$isQF||typeof a==="object"&&a!==null&&!!z.$isI0||typeof a==="object"&&a!==null&&!!z.$ishy)return a
-return},"call$1","ay",2,0,null,265],
+return},"call$1","ay",2,0,null,259,[]],
 pN:[function(a,b){var z,y
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$iscv)return M.F5(a,b)
 if(typeof a==="object"&&a!==null&&!!z.$iskJ){y=M.F4(a.textContent,"text",a,b)
-if(y!=null)return["text",y]}return},"call$2","vw",4,0,null,265,284],
+if(y!=null)return["text",y]}return},"call$2","SG",4,0,null,259,[],279,[]],
 F5:[function(a,b){var z,y,x
 z={}
 z.a=null
@@ -22200,7 +22539,7 @@
 if(y==null){x=[]
 z.a=x
 y=x}y.push("bind")
-y.push(M.F4("{{}}","bind",a,b))}return z.a},"call$2","OT",4,0,null,124,284],
+y.push(M.F4("{{}}","bind",a,b))}return z.a},"call$2","OT",4,0,null,124,[],279,[]],
 Iu:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i
 for(z=J.U6(a),y=d!=null,x=J.x(b),x=typeof b==="object"&&b!==null&&!!x.$ishs,w=0;w<z.gB(a);w+=2){v=z.t(a,w)
 u=z.t(a,w+1)
@@ -22230,7 +22569,7 @@
 t.push(L.ao(j,l,null))}o.wE(0)
 p=o
 s="value"}i=J.Jj(x?b:M.Ky(b),v,p,s)
-if(y)d.push(i)}},"call$4","S5",6,2,null,77,291,265,285,286],
+if(y)d.push(i)}},"call$4","S5",6,2,null,77,286,[],259,[],280,[],281,[]],
 F4:[function(a,b,c,d){var z,y,x,w,v,u,t,s,r
 z=a.length
 if(z===0)return
@@ -22248,15 +22587,15 @@
 v=t+2}if(v===z)w.push("")
 z=new M.HS(w,null)
 z.Yn(w)
-return z},"call$4","nG",8,0,null,86,12,265,284],
+return z},"call$4","jF",8,0,null,86,[],12,[],259,[],279,[]],
 SH:[function(a,b){var z,y
 z=a.firstChild
 if(z==null)return
 y=new M.yp(z,a.lastChild,b)
 for(;z!=null;){M.Ky(z).sCk(y)
-z=z.nextSibling}},"call$2","KQ",4,0,null,201,285],
+z=z.nextSibling}},"call$2","KQ",4,0,null,199,[],280,[]],
 Ky:[function(a){var z,y,x,w
-z=$.cm()
+z=$.rw()
 z.toString
 y=H.of(a,"expando$values")
 x=y==null?null:H.of(y,z.Qz())
@@ -22269,14 +22608,14 @@
 else w=!0
 x=w?new M.DT(null,null,null,!1,null,null,null,null,null,a,null,null):new M.V2(a,null,null)}else x=typeof a==="object"&&a!==null&&!!w.$iskJ?new M.XT(a,null,null):new M.hs(a,null,null)
 z.u(0,a,x)
-return x},"call$1","La",2,0,null,265],
+return x},"call$1","La",2,0,null,259,[]],
 wR:[function(a){var z=J.RE(a)
 if(typeof a==="object"&&a!==null&&!!z.$iscv)if(z.gqn(a)!=="template")z=z.gQg(a).MW.hasAttribute("template")===!0&&C.uE.x4(z.gqn(a))===!0
 else z=!0
 else z=!1
-return z},"call$1","xS",2,0,null,292],
+return z},"call$1","xS",2,0,null,287,[]],
 V2:{
-"":"hs;N1,mD,Ck",
+"^":"hs;N1,mD,Ck",
 Z1:[function(a,b,c,d){var z,y,x,w,v
 J.MV(this.glN(),b)
 z=this.gN1()
@@ -22297,21 +22636,21 @@
 z=d!=null?d:""
 x=new M.D8(w,y,c,null,null,v,z)
 x.Og(y,v,c,d)}this.gCd(this).u(0,b,x)
-return x},"call$3","gDT",4,2,null,77,12,285,266]},
+return x},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 D8:{
-"":"TR;Y0,qP,ZY,xS,PB,eS,ay",
+"^":"TR;Y0,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z,y
 if(this.Y0){z=null!=a&&!1!==a
 y=this.eS
 if(z)J.Vs(X.TR.prototype.gH.call(this)).MW.setAttribute(y,"")
 else J.Vs(X.TR.prototype.gH.call(this)).Rz(0,y)}else{z=J.Vs(X.TR.prototype.gH.call(this))
 y=a==null?"":H.d(a)
-z.MW.setAttribute(this.eS,y)}},"call$1","gH0",2,0,null,23]},
+z.MW.setAttribute(this.eS,y)}},"call$1","gH0",2,0,null,23,[]]},
 jY:{
-"":"NP;Ca,qP,ZY,xS,PB,eS,ay",
+"^":"NP;Ca,qP,ZY,xS,PB,eS,ay",
 gH:function(){return M.NP.prototype.gH.call(this)},
 EC:[function(a){var z,y,x,w,v,u
-z=J.Lp(M.NP.prototype.gH.call(this))
+z=J.u3(M.NP.prototype.gH.call(this))
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$islp){x=J.UQ(J.QE(M.Ky(z)),"value")
 w=J.x(x)
@@ -22319,49 +22658,49 @@
 u=x}else{v=null
 u=null}}else{v=null
 u=null}M.NP.prototype.EC.call(this,a)
-if(u!=null&&u.gqP()!=null&&!J.de(y.gP(z),v))u.FC(null)},"call$1","gH0",2,0,null,232]},
+if(u!=null&&u.gqP()!=null&&!J.de(y.gP(z),v))u.FC(null)},"call$1","gH0",2,0,null,226,[]]},
 H2:{
-"":"TR;",
+"^":"TR;",
 cO:[function(a){if(this.qP==null)return
 this.Ca.ed()
 X.TR.prototype.cO.call(this,this)},"call$0","gJK",0,0,null]},
-lP:{
-"":"Tp:108;",
+YJ:{
+"^":"Tp:108;",
 call$0:[function(){var z,y,x,w,v
 z=document.createElement("div",null).appendChild(W.ED(null))
 y=J.RE(z)
 y.st5(z,"checkbox")
 x=[]
 w=y.gVl(z)
-H.VM(new W.Ov(0,w.uv,w.Ph,W.aF(new M.LfS(x)),w.Sg),[H.Kp(w,0)]).Zz()
+H.VM(new W.Ov(0,w.uv,w.Ph,W.aF(new M.fTP(x)),w.Sg),[H.Kp(w,0)]).Zz()
 y=y.gi9(z)
-H.VM(new W.Ov(0,y.uv,y.Ph,W.aF(new M.fTP(x)),y.Sg),[H.Kp(y,0)]).Zz()
+H.VM(new W.Ov(0,y.uv,y.Ph,W.aF(new M.ppY(x)),y.Sg),[H.Kp(y,0)]).Zz()
 y=window
 v=document.createEvent("MouseEvent")
 J.e2(v,"click",!0,!0,y,0,0,0,0,0,!1,!1,!1,!1,0,null)
 z.dispatchEvent(v)
 return x.length===1?C.mt:C.Nm.gtH(x)},"call$0",null,0,0,null,"call"],
 $isEH:true},
-LfS:{
-"":"Tp:229;a",
-call$1:[function(a){this.a.push(C.T1)},"call$1",null,2,0,null,18,"call"],
-$isEH:true},
 fTP:{
-"":"Tp:229;b",
-call$1:[function(a){this.b.push(C.mt)},"call$1",null,2,0,null,18,"call"],
+"^":"Tp:223;a",
+call$1:[function(a){this.a.push(C.pi)},"call$1",null,2,0,null,18,[],"call"],
+$isEH:true},
+ppY:{
+"^":"Tp:223;b",
+call$1:[function(a){this.b.push(C.mt)},"call$1",null,2,0,null,18,[],"call"],
 $isEH:true},
 NP:{
-"":"H2;Ca,qP,ZY,xS,PB,eS,ay",
+"^":"H2;Ca,qP,ZY,xS,PB,eS,ay",
 gH:function(){return X.TR.prototype.gH.call(this)},
 EC:[function(a){var z=this.gH()
-J.ta(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,232],
+J.ta(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,226,[]],
 FC:[function(a){var z=J.Vm(this.gH())
 J.ta(this.xS,z)
-O.Y3()},"call$1","gqf",2,0,152,18]},
-Vh:{
-"":"H2;Ca,qP,ZY,xS,PB,eS,ay",
+O.Y3()},"call$1","gqf",2,0,150,18,[]]},
+jt:{
+"^":"H2;Ca,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z=X.TR.prototype.gH.call(this)
-J.rP(z,null!=a&&!1!==a)},"call$1","gH0",2,0,null,232],
+J.rP(z,null!=a&&!1!==a)},"call$1","gH0",2,0,null,226,[]],
 FC:[function(a){var z,y,x,w
 z=J.Hf(X.TR.prototype.gH.call(this))
 J.ta(this.xS,z)
@@ -22370,7 +22709,7 @@
 if(typeof z==="object"&&z!==null&&!!y.$isMi&&J.de(J.zH(X.TR.prototype.gH.call(this)),"radio"))for(z=J.GP(M.kv(X.TR.prototype.gH.call(this)));z.G();){x=z.gl()
 y=J.x(x)
 w=J.UQ(J.QE(typeof x==="object"&&x!==null&&!!y.$ishs?x:M.Ky(x)),"checked")
-if(w!=null)J.ta(w,!1)}O.Y3()},"call$1","gqf",2,0,152,18],
+if(w!=null)J.ta(w,!1)}O.Y3()},"call$1","gqf",2,0,150,18,[]],
 static:{kv:[function(a){var z,y,x
 z=J.RE(a)
 if(z.gMB(a)!=null){z=z.gMB(a)
@@ -22379,9 +22718,9 @@
 return z.ev(z,new M.r0(a))}else{y=M.bM(a)
 if(y==null)return C.xD
 x=J.MK(y,"input[type=\"radio\"][name=\""+H.d(z.goc(a))+"\"]")
-return x.ev(x,new M.jz(a))}},"call$1","VE",2,0,null,124]}},
+return x.ev(x,new M.jz(a))}},"call$1","VE",2,0,null,124,[]]}},
 r0:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z,y
 z=this.a
 y=J.x(a)
@@ -22390,21 +22729,21 @@
 z=y==null?z==null:y===z}else z=!1
 else z=!1
 else z=!1
-return z},"call$1",null,2,0,null,288,"call"],
+return z},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true},
 jz:{
-"":"Tp:229;b",
+"^":"Tp:223;b",
 call$1:[function(a){var z=J.x(a)
-return!z.n(a,this.b)&&z.gMB(a)==null},"call$1",null,2,0,null,288,"call"],
+return!z.n(a,this.b)&&z.gMB(a)==null},"call$1",null,2,0,null,283,[],"call"],
 $isEH:true},
 SA:{
-"":"H2;Dh,Ca,qP,ZY,xS,PB,eS,ay",
+"^":"H2;Dh,Ca,qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z
 this.C7()
 if(this.Gh(a)===!0)return
-z=new (window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver)(H.tR(W.Iq(new M.hB(this)),2))
+z=new (window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver)(H.tR(W.K2(new M.hB(this)),2))
 C.S2.yN(z,X.TR.prototype.gH.call(this),!0,!0)
-this.Dh=z},"call$1","gH0",2,0,null,232],
+this.Dh=z},"call$1","gH0",2,0,null,226,[]],
 Gh:[function(a){var z,y,x
 z=this.eS
 y=J.x(z)
@@ -22413,7 +22752,7 @@
 z=J.m4(X.TR.prototype.gH.call(this))
 return z==null?x==null:z===x}else if(y.n(z,"value")){z=X.TR.prototype.gH.call(this)
 J.ta(z,a==null?"":H.d(a))
-return J.de(J.Vm(X.TR.prototype.gH.call(this)),a)}},"call$1","gdZ",2,0,null,232],
+return J.de(J.Vm(X.TR.prototype.gH.call(this)),a)}},"call$1","goz",2,0,null,226,[]],
 C7:[function(){var z=this.Dh
 if(z!=null){z.disconnect()
 this.Dh=null}},"call$0","gln",0,0,null],
@@ -22423,21 +22762,21 @@
 y=J.x(z)
 if(y.n(z,"selectedIndex")){z=J.m4(X.TR.prototype.gH.call(this))
 J.ta(this.xS,z)}else if(y.n(z,"value")){z=J.Vm(X.TR.prototype.gH.call(this))
-J.ta(this.xS,z)}},"call$1","gqf",2,0,152,18],
+J.ta(this.xS,z)}},"call$1","gqf",2,0,150,18,[]],
 $isSA:true,
 static:{qb:[function(a){if(typeof a==="string")return H.BU(a,null,new M.nv())
-return typeof a==="number"&&Math.floor(a)===a?a:0},"call$1","v7",2,0,null,23]}},
+return typeof a==="number"&&Math.floor(a)===a?a:0},"call$1","v7",2,0,null,23,[]]}},
 hB:{
-"":"Tp:349;a",
+"^":"Tp:341;a",
 call$2:[function(a,b){var z=this.a
-if(z.Gh(J.Vm(z.xS))===!0)z.C7()},"call$2",null,4,0,null,21,608,"call"],
+if(z.Gh(J.Vm(z.xS))===!0)z.C7()},"call$2",null,4,0,null,21,[],603,[],"call"],
 $isEH:true},
 nv:{
-"":"Tp:229;",
-call$1:[function(a){return 0},"call$1",null,2,0,null,240,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return 0},"call$1",null,2,0,null,235,[],"call"],
 $isEH:true},
 ee:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 z=J.x(b)
@@ -22454,25 +22793,25 @@
 x.Ca=M.IP(z).yI(x.gqf())
 z=x}else{z=this.N1
 x=d!=null?d:""
-x=new M.Vh(null,z,c,null,null,"checked",x)
+x=new M.jt(null,z,c,null,null,"checked",x)
 x.Og(z,"checked",c,d)
 x.Ca=M.IP(z).yI(x.gqf())
 z=x}y.u(0,b,z)
-return z},"call$3","gDT",4,2,null,77,12,285,266]},
+return z},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 XI:{
-"":"a;Cd>,wd>,N2<,Te<"},
+"^":"a;Cd>,wd>,N2<,Te<"},
 hs:{
-"":"a;N1<,mD,Ck?",
+"^":"a;N1<,mD,Ck?",
 Z1:[function(a,b,c,d){var z,y
 window
 z=$.pl()
 y="Unhandled binding to Node: "+H.d(this)+" "+H.d(b)+" "+H.d(c)+" "+H.d(d)
 z.toString
-if(typeof console!="undefined")console.error(y)},"call$3","gDT",4,2,null,77,12,285,266],
+if(typeof console!="undefined")console.error(y)},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 Ih:[function(a,b){var z
 if(this.mD==null)return
 z=this.gCd(this).Rz(0,b)
-if(z!=null)J.wC(z)},"call$1","gV0",2,0,null,12],
+if(z!=null)J.wC(z)},"call$1","gC8",2,0,null,12,[]],
 GB:[function(a){var z,y
 if(this.mD==null)return
 for(z=this.gCd(this),z=z.gUQ(z),z=P.F(z,!0,H.ip(z,"mW",0)),z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();){y=z.lo
@@ -22486,9 +22825,9 @@
 return typeof z==="object"&&z!==null&&!!y.$ishs?z:this},
 $ishs:true},
 yp:{
-"":"a;KO,qW,k8"},
+"^":"a;KO,qW,k8"},
 ug:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 if(J.de(b,"selectedindex"))b="selectedIndex"
@@ -22505,9 +22844,9 @@
 y.Og(x,b,c,d)
 y.Ca=M.IP(x).yI(y.gqf())
 z.u(0,b,y)
-return y},"call$3","gDT",4,2,null,77,12,285,266]},
+return y},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 DT:{
-"":"V2;lr,xT?,kr<,Ds,QO?,jH?,mj?,IT,dv@,N1,mD,Ck",
+"^":"V2;lr,xT?,kr<,Mf,QO?,jH?,mj?,IT,dv@,N1,mD,Ck",
 gN1:function(){return this.N1},
 glN:function(){var z,y
 z=this.N1
@@ -22538,7 +22877,7 @@
 z=new M.p8(this,c,b,d)
 this.gCd(this).u(0,b,z)
 return z
-default:return M.V2.prototype.Z1.call(this,this,b,c,d)}},"call$3","gDT",4,2,null,77,12,285,266],
+default:return M.V2.prototype.Z1.call(this,this,b,c,d)}},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]],
 Ih:[function(a,b){var z
 switch(b){case"bind":z=this.kr
 if(z==null)return
@@ -22565,10 +22904,10 @@
 this.gCd(this).Rz(0,b)
 return
 default:M.hs.prototype.Ih.call(this,this,b)
-return}},"call$1","gV0",2,0,null,12],
+return}},"call$1","gC8",2,0,null,12,[]],
 jq:[function(){var z=this.kr
 if(!z.t9){z.t9=!0
-P.rb(z.gjM())}},"call$0","goz",0,0,null],
+P.rb(z.gjM())}},"call$0","gvj",0,0,null],
 a5:[function(a,b,c){var z,y,x,w,v,u,t
 z=this.gnv(this)
 y=J.x(z)
@@ -22585,7 +22924,7 @@
 y=u}t=M.Fz(x,y)
 M.HP(t,w,a,b,c)
 M.SH(t,a)
-return t},function(a,b){return this.a5(a,b,null)},"ZK","call$3",null,"gmJ",0,6,null,77,77,77,285,284,286],
+return t},function(a,b){return this.a5(a,b,null)},"ZK","call$3",null,"gmJ",0,6,null,77,77,77,280,[],279,[],281,[]],
 gzH:function(){return this.xT},
 gnv:function(a){var z,y,x,w,v
 this.Sy()
@@ -22612,7 +22951,7 @@
 y=J.RE(z)
 z=y.gQg(z).MW.hasAttribute("template")===!0&&C.uE.x4(y.gqn(z))===!0}else z=!1
 if(z){if(a!=null)throw H.b(new P.AT("instanceRef should not be supplied for attribute templates."))
-v=M.eX(this.N1)
+v=M.pZ(this.N1)
 z=J.x(v)
 v=typeof v==="object"&&v!==null&&!!z.$ishs?v:M.Ky(v)
 v.smj(!0)
@@ -22624,23 +22963,23 @@
 if(a!=null)v.sQO(a)
 else if(w)M.KE(v,this.N1,u)
 else M.GM(J.nX(v))
-return!0},function(){return this.wh(null)},"Sy","call$1",null,"gv8",0,2,null,77,609],
+return!0},function(){return this.wh(null)},"Sy","call$1",null,"ga6",0,2,null,77,604,[]],
 $isDT:true,
-static:{"":"mn,EW,Sf,To",Fz:[function(a,b){var z,y,x
+static:{"^":"mn,EW,Sf,To",Fz:[function(a,b){var z,y,x
 z=J.Lh(b,a,!1)
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$iscv)if(y.gqn(z)!=="template")y=y.gQg(z).MW.hasAttribute("template")===!0&&C.uE.x4(y.gqn(z))===!0
 else y=!0
 else y=!1
 if(y)return z
-for(x=J.vi(a);x!=null;x=x.nextSibling)z.appendChild(M.Fz(x,b))
-return z},"call$2","G0",4,0,null,265,287],TA:[function(a){var z,y,x,w
+for(x=J.cO(a);x!=null;x=x.nextSibling)z.appendChild(M.Fz(x,b))
+return z},"call$2","Tkw",4,0,null,259,[],282,[]],TA:[function(a){var z,y,x,w
 z=J.VN(a)
 if(W.Pv(z.defaultView)==null)return z
 y=$.LQ().t(0,z)
 if(y==null){y=z.implementation.createHTMLDocument("")
 for(;x=y.lastChild,x!=null;){w=x.parentNode
-if(w!=null)w.removeChild(x)}$.LQ().u(0,z,y)}return y},"call$1","nt",2,0,null,262],eX:[function(a){var z,y,x,w,v,u
+if(w!=null)w.removeChild(x)}$.LQ().u(0,z,y)}return y},"call$1","nt",2,0,null,256,[]],pZ:[function(a){var z,y,x,w,v,u
 z=J.RE(a)
 y=z.gM0(a).createElement("template",null)
 z.gKV(a).insertBefore(y,a)
@@ -22655,32 +22994,32 @@
 v.removeAttribute(w)
 y.setAttribute(w,u)
 break
-default:}}return y},"call$1","LH",2,0,null,288],KE:[function(a,b,c){var z,y,x,w
+default:}}return y},"call$1","fo",2,0,null,283,[]],KE:[function(a,b,c){var z,y,x,w
 z=J.nX(a)
 if(c){J.Kv(z,b)
-return}for(y=J.RE(b),x=J.RE(z);w=y.gq6(b),w!=null;)x.jx(z,w)},"call$3","BZ",6,0,null,262,288,289],GM:[function(a){var z,y
+return}for(y=J.RE(b),x=J.RE(z);w=y.gq6(b),w!=null;)x.jx(z,w)},"call$3","BZ",6,0,null,256,[],283,[],284,[]],GM:[function(a){var z,y
 z=new M.OB()
 y=J.MK(a,$.cz())
 if(M.wR(a))z.call$1(a)
-y.aN(y,z)},"call$1","DR",2,0,null,290],oR:[function(){if($.To===!0)return
+y.aN(y,z)},"call$1","DR",2,0,null,285,[]],oR:[function(){if($.To===!0)return
 $.To=!0
 var z=document.createElement("style",null)
 z.textContent=$.cz()+" { display: none; }"
 document.head.appendChild(z)},"call$0","Lv",0,0,null]}},
 OB:{
-"":"Tp:152;",
+"^":"Tp:150;",
 call$1:[function(a){var z
 if(!M.Ky(a).wh(null)){z=J.x(a)
-M.GM(J.nX(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a)))}},"call$1",null,2,0,null,262,"call"],
+M.GM(J.nX(typeof a==="object"&&a!==null&&!!z.$ishs?a:M.Ky(a)))}},"call$1",null,2,0,null,256,[],"call"],
 $isEH:true},
-Uf:{
-"":"Tp:229;",
-call$1:[function(a){return H.d(a)+"[template]"},"call$1",null,2,0,null,421,"call"],
+DO:{
+"^":"Tp:223;",
+call$1:[function(a){return H.d(a)+"[template]"},"call$1",null,2,0,null,417,[],"call"],
 $isEH:true},
 p8:{
-"":"a;ud,lr,eS,ay",
+"^":"a;ud,lr,eS,ay",
 gP:function(a){return J.Vm(this.gND())},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:function(a,b){J.ta(this.gND(),b)},
 gND:function(){var z,y
 z=this.lr
@@ -22694,7 +23033,7 @@
 this.ud=null},"call$0","gJK",0,0,null],
 $isTR:true},
 NW:{
-"":"Tp:349;a,b,c,d",
+"^":"Tp:341;a,b,c,d",
 call$2:[function(a,b){var z,y,x,w
 for(;z=J.U6(a),J.de(z.t(a,0),"_");)a=z.yn(a,1)
 if(this.d)if(z.n(a,"if")){this.a.b=!0
@@ -22706,10 +23045,10 @@
 z.a=w
 z=w}else z=x
 z.push(a)
-z.push(y)}},"call$2",null,4,0,null,12,23,"call"],
+z.push(y)}},"call$2",null,4,0,null,12,[],23,[],"call"],
 $isEH:true},
 HS:{
-"":"a;EJ<,bX",
+"^":"a;EJ<,bX",
 gqz:function(){return this.EJ.length===4},
 gaW:function(){var z,y
 z=this.EJ
@@ -22725,7 +23064,7 @@
 if(0>=z.length)return H.e(z,0)
 y=H.d(z[0])+H.d(a)
 if(3>=z.length)return H.e(z,3)
-return y+H.d(z[3])},"call$1","gBg",2,0,610,23],
+return y+H.d(z[3])},"call$1","gBg",2,0,605,23,[]],
 DJ:[function(a){var z,y,x,w,v,u,t
 z=this.EJ
 if(0>=z.length)return H.e(z,0)
@@ -22736,10 +23075,10 @@
 if(t>=z.length)return H.e(z,t)
 u=z[t]
 u=typeof u==="string"?u:H.d(u)
-y.vM=y.vM+u}return y.vM},"call$1","gqD",2,0,611,612],
+y.vM=y.vM+u}return y.vM},"call$1","gqD",2,0,606,607,[]],
 Yn:function(a){this.bX=this.EJ.length===4?this.gBg():this.gqD()}},
 TG:{
-"":"a;e9,YC,xG,pq,t9,A7,js,Q3,JM,d6,rV,yO,XV,eD,FS,IY,U9,DO,Fy",
+"^":"a;e9,YC,xG,pq,t9,A7,js,Q3,JM,d6,rV,yO,XV,eD,FS,IY,U9,DO,Fy",
 Mv:function(a){return this.DO.call$1(a)},
 XS:[function(){var z,y,x,w,v,u
 this.t9=!1
@@ -22770,7 +23109,7 @@
 x=this.xG
 x=x!=null?x:[]
 w=G.jj(x,0,J.q8(x),y,0,J.q8(y))
-if(w.length!==0)this.El(w)},"call$1","ghC",2,0,null,232],
+if(w.length!==0)this.El(w)},"call$1","ghC",2,0,null,226,[]],
 wx:[function(a){var z,y,x,w
 z=J.x(a)
 if(z.n(a,-1))return this.e9.N1
@@ -22783,7 +23122,7 @@
 if(z)return x
 w=M.Ky(x).gkr()
 if(w==null)return x
-return w.wx(C.jn.cU(w.YC.length,2)-1)},"call$1","gzm",2,0,null,47],
+return w.wx(C.jn.cU(w.YC.length,2)-1)},"call$1","gzm",2,0,null,47,[]],
 lP:[function(a,b,c,d){var z,y,x,w,v,u
 z=J.Wx(a)
 y=this.wx(z.W(a,1))
@@ -22796,10 +23135,10 @@
 v=J.TZ(this.e9.N1)
 u=J.tx(y)
 if(x)v.insertBefore(b,u)
-else if(c!=null)for(z=J.GP(c);z.G();)v.insertBefore(z.gl(),u)},"call$4","gaF",8,0,null,47,201,613,286],
+else if(c!=null)for(z=J.GP(c);z.G();)v.insertBefore(z.gl(),u)},"call$4","gaF",8,0,null,47,[],199,[],608,[],281,[]],
 MC:[function(a){var z,y,x,w,v,u,t,s
 z=[]
-z.$builtinTypeInfo=[W.uH]
+z.$builtinTypeInfo=[W.KV]
 y=J.Wx(a)
 x=this.wx(y.W(a,1))
 w=this.wx(a)
@@ -22813,7 +23152,7 @@
 if(s==null?w==null:s===w)w=x
 v=s.parentNode
 if(v!=null)v.removeChild(s)
-z.push(s)}return new M.Ya(z,t)},"call$1","gtx",2,0,null,47],
+z.push(s)}return new M.Ya(z,t)},"call$1","gLu",2,0,null,47,[]],
 El:[function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
 if(this.pq)return
 z=this.e9
@@ -22839,9 +23178,9 @@
 k=null}else{m=[]
 if(this.DO!=null)o=this.Mv(o)
 k=o!=null?z.a5(o,v,m):null
-l=null}this.lP(p,k,l,m)}}for(z=u.gUQ(u),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)this.uS(J.AB(z.lo))},"call$1","gZX",2,0,614,255],
+l=null}this.lP(p,k,l,m)}}for(z=u.gUQ(u),z=H.VM(new H.MH(null,J.GP(z.l6),z.T6),[H.Kp(z,0),H.Kp(z,1)]);z.G();)this.uS(J.AB(z.lo))},"call$1","gZX",2,0,609,250,[]],
 uS:[function(a){var z
-for(z=J.GP(a);z.G();)J.wC(z.gl())},"call$1","gZC",2,0,null,286],
+for(z=J.GP(a);z.G();)J.wC(z.gl())},"call$1","gZC",2,0,null,281,[]],
 Gb:[function(){var z=this.IY
 if(z==null)return
 z.ed()
@@ -22856,27 +23195,27 @@
 this.FS=null}this.e9.kr=null
 this.pq=!0},"call$0","gJK",0,0,null]},
 ts:{
-"":"Tp:229;",
-call$1:[function(a){return[a]},"call$1",null,2,0,null,21,"call"],
+"^":"Tp:223;",
+call$1:[function(a){return[a]},"call$1",null,2,0,null,21,[],"call"],
 $isEH:true},
 Kj:{
-"":"Tp:480;a",
+"^":"Tp:484;a",
 call$1:[function(a){var z,y,x
 z=J.U6(a)
 y=z.t(a,0)
 x=z.t(a,1)
 if(!(null!=x&&!1!==x))return
-return this.a?y:[y]},"call$1",null,2,0,null,612,"call"],
+return this.a?y:[y]},"call$1",null,2,0,null,607,[],"call"],
 $isEH:true},
 VU:{
-"":"Tp:229;b",
-call$1:[function(a){return this.b.Az(J.iZ(J.MQ(a)))},"call$1",null,2,0,null,375,"call"],
+"^":"Tp:223;b",
+call$1:[function(a){return this.b.Az(J.iZ(J.MQ(a)))},"call$1",null,2,0,null,368,[],"call"],
 $isEH:true},
 Ya:{
-"":"a;yT>,kU>",
+"^":"a;yT>,kU>",
 $isYa:true},
 XT:{
-"":"hs;N1,mD,Ck",
+"^":"hs;N1,mD,Ck",
 Z1:[function(a,b,c,d){var z,y,x
 if(!J.de(b,"text"))return M.hs.prototype.Z1.call(this,this,b,c,d)
 this.Ih(0,b)
@@ -22886,13 +23225,13 @@
 x=new M.ic(y,c,null,null,"text",x)
 x.Og(y,"text",c,d)
 z.u(0,b,x)
-return x},"call$3","gDT",4,2,null,77,12,285,266]},
+return x},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]},
 ic:{
-"":"TR;qP,ZY,xS,PB,eS,ay",
+"^":"TR;qP,ZY,xS,PB,eS,ay",
 EC:[function(a){var z=this.qP
-J.c9(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,232]},
+J.c9(z,a==null?"":H.d(a))},"call$1","gH0",2,0,null,226,[]]},
 wl:{
-"":"V2;N1,mD,Ck",
+"^":"V2;N1,mD,Ck",
 gN1:function(){return this.N1},
 Z1:[function(a,b,c,d){var z,y,x
 if(!J.de(b,"value"))return M.V2.prototype.Z1.call(this,this,b,c,d)
@@ -22907,16 +23246,16 @@
 y.Og(x,"value",c,d)
 y.Ca=M.IP(x).yI(y.gqf())
 z.u(0,b,y)
-return y},"call$3","gDT",4,2,null,77,12,285,266]}}],["template_binding.src.binding_delegate","package:template_binding/src/binding_delegate.dart",,O,{
-"":"",
+return y},"call$3","gxfG",4,2,null,77,12,[],280,[],260,[]]}}],["template_binding.src.binding_delegate","package:template_binding/src/binding_delegate.dart",,O,{
+"^":"",
 T4:{
-"":"a;"}}],["template_binding.src.node_binding","package:template_binding/src/node_binding.dart",,X,{
-"":"",
+"^":"a;"}}],["template_binding.src.node_binding","package:template_binding/src/node_binding.dart",,X,{
+"^":"",
 TR:{
-"":"a;qP<",
+"^":"a;qP<",
 gH:function(){return this.qP},
 gP:function(a){return J.Vm(this.xS)},
-r6:function(a,b){return this.gP(a).call$1(b)},
+r6:function(a,b){return this.gP(this).call$1(b)},
 sP:function(a,b){J.ta(this.xS,b)},
 cO:[function(a){var z
 if(this.qP==null)return
@@ -22937,9 +23276,9 @@
 this.EC(J.Vm(this.xS))},
 $isTR:true},
 VD:{
-"":"Tp:229;a",
+"^":"Tp:223;a",
 call$1:[function(a){var z=this.a
-return z.EC(J.Vm(z.xS))},"call$1",null,2,0,null,375,"call"],
+return z.EC(J.Vm(z.xS))},"call$1",null,2,0,null,368,[],"call"],
 $isEH:true}}],])
 I.$finishClasses($$,$,null)
 $$=null
@@ -22964,9 +23303,9 @@
 J.GW.$isfR=true
 J.GW.$asfR=[J.P]
 J.GW.$isa=true
-W.uH.$isuH=true
-W.uH.$isD0=true
-W.uH.$isa=true
+W.KV.$isKV=true
+W.KV.$isD0=true
+W.KV.$isa=true
 W.M5.$isa=true
 N.qV.$isfR=true
 N.qV.$asfR=[N.qV]
@@ -22981,15 +23320,15 @@
 J.Q.$isa=true
 P.a.$isa=true
 W.cv.$iscv=true
-W.cv.$isuH=true
+W.cv.$isKV=true
 W.cv.$isD0=true
 W.cv.$isD0=true
 W.cv.$isa=true
 P.qv.$isa=true
 U.EZ.$ishw=true
 U.EZ.$isa=true
-U.RW.$ishw=true
-U.RW.$isa=true
+U.Jy.$ishw=true
+U.Jy.$isa=true
 U.zX.$iszX=true
 U.zX.$ishw=true
 U.zX.$isa=true
@@ -23021,7 +23360,7 @@
 W.OJ.$isa=true
 A.XP.$isXP=true
 A.XP.$iscv=true
-A.XP.$isuH=true
+A.XP.$isKV=true
 A.XP.$isD0=true
 A.XP.$isD0=true
 A.XP.$isa=true
@@ -23044,11 +23383,14 @@
 P.ej.$isa=true
 P.RY.$isej=true
 P.RY.$isa=true
-P.tg.$isej=true
-P.tg.$isa=true
+P.ac.$isX9=true
+P.ac.$isej=true
+P.ac.$isa=true
+P.X9.$isX9=true
 P.X9.$isej=true
 P.X9.$isa=true
 P.Ms.$isMs=true
+P.Ms.$isX9=true
 P.Ms.$isej=true
 P.Ms.$isej=true
 P.Ms.$isa=true
@@ -23064,8 +23406,8 @@
 W.ea.$isa=true
 P.qh.$isqh=true
 P.qh.$isa=true
-W.Aj.$isea=true
-W.Aj.$isa=true
+W.Oq.$isea=true
+W.Oq.$isa=true
 G.DA.$isDA=true
 G.DA.$isa=true
 M.Ya.$isa=true
@@ -23073,15 +23415,16 @@
 U.hw.$ishw=true
 U.hw.$isa=true
 A.zs.$iscv=true
-A.zs.$isuH=true
+A.zs.$isKV=true
 A.zs.$isD0=true
 A.zs.$isD0=true
 A.zs.$isa=true
-A.k8.$isa=true
+A.bS.$isa=true
+L.Y2.$isa=true
 P.uq.$isa=true
 P.iD.$isiD=true
 P.iD.$isa=true
-W.QF.$isuH=true
+W.QF.$isKV=true
 W.QF.$isD0=true
 W.QF.$isa=true
 N.HV.$isHV=true
@@ -23089,7 +23432,7 @@
 H.yo.$isa=true
 H.IY.$isa=true
 H.aX.$isa=true
-W.I0.$isuH=true
+W.I0.$isKV=true
 W.I0.$isD0=true
 W.I0.$isa=true
 W.DD.$isea=true
@@ -23104,6 +23447,11 @@
 L.kx.$iskx=true
 L.kx.$isa=true
 L.rj.$isa=true
+W.tV.$iscv=true
+W.tV.$isKV=true
+W.tV.$isD0=true
+W.tV.$isD0=true
+W.tV.$isa=true
 P.MN.$isMN=true
 P.MN.$isa=true
 P.KA.$isKA=true
@@ -23127,10 +23475,10 @@
 P.e4.$isa=true
 P.JB.$isJB=true
 P.JB.$isa=true
-L.N8.$isN8=true
-L.N8.$isa=true
 P.Z0.$isZ0=true
 P.Z0.$isa=true
+L.Vi.$isVi=true
+L.Vi.$isa=true
 P.jp.$isjp=true
 P.jp.$isa=true
 W.D0.$isD0=true
@@ -23139,23 +23487,22 @@
 P.fR.$isa=true
 P.aY.$isaY=true
 P.aY.$isa=true
-P.tU.$istU=true
-P.tU.$isa=true
+P.lO.$islO=true
+P.lO.$isa=true
 P.cX.$iscX=true
 P.cX.$isa=true
-P.b8.$isb8=true
-P.b8.$isa=true
-P.lx.$islx=true
-P.lx.$isa=true
 P.nP.$isnP=true
 P.nP.$isa=true
 P.iP.$isiP=true
 P.iP.$isfR=true
 P.iP.$asfR=[null]
 P.iP.$isa=true
+P.lx.$islx=true
+P.lx.$isa=true
+P.b8.$isb8=true
+P.b8.$isa=true
 P.EH.$isEH=true
 P.EH.$isa=true
-$.$signature_X0={func:"X0",void:true}
 $.$signature_bh={func:"bh",args:[null,null]}
 $.$signature_HB={func:"HB",ret:P.a,args:[P.a]}
 $.$signature_Dv={func:"Dv",args:[null]}
@@ -23189,7 +23536,7 @@
 return J.ks(a)}
 J.x=function(a){if(typeof a=="number"){if(Math.floor(a)==a)return J.im.prototype
 return J.GW.prototype}if(typeof a=="string")return J.O.prototype
-if(a==null)return J.PE.prototype
+if(a==null)return J.ht.prototype
 if(typeof a=="boolean")return J.kn.prototype
 if(a.constructor==Array)return J.Q.prototype
 if(typeof a!="object")return a
@@ -23201,6 +23548,7 @@
 J.C0=function(a,b){return J.w1(a).ez(a,b)}
 J.CC=function(a){return J.RE(a).gmH(a)}
 J.CJ=function(a,b){return J.RE(a).sB1(a,b)}
+J.Co=function(a){return J.RE(a).gcC(a)}
 J.EC=function(a){return J.RE(a).giC(a)}
 J.EY=function(a,b){return J.RE(a).od(a,b)}
 J.Eg=function(a,b){return J.rY(a).Tc(a,b)}
@@ -23212,7 +23560,6 @@
 J.GJ=function(a,b,c,d){return J.RE(a).Y9(a,b,c,d)}
 J.GL=function(a){return J.RE(a).gfN(a)}
 J.GP=function(a){return J.w1(a).gA(a)}
-J.Gn=function(a,b){return J.rY(a).Fr(a,b)}
 J.H4=function(a,b){return J.RE(a).wR(a,b)}
 J.Hb=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<=b
 return J.Wx(a).E(a,b)}
@@ -23229,27 +23576,26 @@
 J.Jr=function(a,b){return J.RE(a).Id(a,b)}
 J.K3=function(a,b){return J.RE(a).Kb(a,b)}
 J.KM=function(a){return J.RE(a).zr(a)}
-J.KV=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a&b)>>>0
-return J.Wx(a).i(a,b)}
 J.Kv=function(a,b){return J.RE(a).jx(a,b)}
+J.LH=function(a,b){return J.w1(a).GT(a,b)}
 J.LL=function(a){return J.Wx(a).HG(a)}
 J.Lh=function(a,b,c){return J.RE(a).ek(a,b,c)}
-J.Lp=function(a){return J.RE(a).geT(a)}
+J.Lp=function(a,b){return J.RE(a).st5(a,b)}
 J.MK=function(a,b){return J.RE(a).Md(a,b)}
 J.MQ=function(a){return J.w1(a).grZ(a)}
 J.MV=function(a,b){return J.RE(a).Ih(a,b)}
 J.Mu=function(a,b){return J.RE(a).sig(a,b)}
 J.Mz=function(a){return J.rY(a).hc(a)}
 J.N5=function(a,b){return J.RE(a).RP(a,b)}
+J.NQ=function(a,b){return J.RE(a).bA(a,b)}
 J.Ng=function(a){return J.RE(a).gxX(a)}
 J.Nj=function(a,b,c){return J.rY(a).Nj(a,b,c)}
+J.Nv=function(a,b,c){return J.w1(a).xe(a,b,c)}
 J.O2=function(a,b){return J.RE(a).Ch(a,b)}
 J.O6=function(a){return J.RE(a).goc(a)}
-J.ON=function(a){return J.RE(a).gcC(a)}
 J.Or=function(a){return J.RE(a).yx(a)}
 J.Pr=function(a,b){return J.w1(a).eR(a,b)}
 J.Pw=function(a,b){return J.RE(a).sxr(a,b)}
-J.Pz=function(a,b){return J.RE(a).szZ(a,b)}
 J.QC=function(a){return J.w1(a).wg(a)}
 J.QE=function(a){return J.RE(a).gCd(a)}
 J.QM=function(a,b){return J.RE(a).Rg(a,b)}
@@ -23260,12 +23606,15 @@
 J.Tv=function(a){return J.RE(a).gB1(a)}
 J.U2=function(a){return J.w1(a).V1(a)}
 J.UK=function(a,b){return J.RE(a).RR(a,b)}
+J.UN=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a^b)>>>0
+return J.Wx(a).w(a,b)}
 J.UQ=function(a,b){if(a.constructor==Array||typeof a=="string"||H.wV(a,a[init.dispatchPropertyName]))if(b>>>0===b&&b<a.length)return a[b]
 return J.U6(a).t(a,b)}
 J.UU=function(a,b){return J.U6(a).u8(a,b)}
 J.Ut=function(a,b,c,d){return J.RE(a).rJ(a,b,c,d)}
 J.V1=function(a,b){return J.w1(a).Rz(a,b)}
 J.VN=function(a){return J.RE(a).gM0(a)}
+J.VZ=function(a,b,c,d,e){return J.w1(a).YW(a,b,c,d,e)}
 J.Vm=function(a){return J.RE(a).gP(a)}
 J.Vq=function(a){return J.RE(a).xo(a)}
 J.Vs=function(a){return J.RE(a).gQg(a)}
@@ -23274,33 +23623,36 @@
 return J.Qc(a).g(a,b)}
 J.WI=function(a){return J.RE(a).gG3(a)}
 J.We=function(a,b){return J.RE(a).scC(a,b)}
-J.Wy=function(a){return J.RE(a).gbG(a)}
 J.XS=function(a,b){return J.w1(a).zV(a,b)}
 J.Xf=function(a,b){return J.RE(a).oo(a,b)}
 J.Y5=function(a){return J.RE(a).gyT(a)}
 J.YP=function(a){return J.RE(a).gQ7(a)}
+J.YV=function(a){return J.RE(a).goE(a)}
 J.Z7=function(a){if(typeof a=="number")return-a
 return J.Wx(a).J(a)}
 J.ZP=function(a,b){return J.RE(a).Tk(a,b)}
 J.ZZ=function(a,b){return J.rY(a).yn(a,b)}
 J.ak=function(a){return J.RE(a).gNF(a)}
 J.bB=function(a){return J.x(a).gbx(a)}
+J.bY=function(a,b){return J.Wx(a).Y(a,b)}
 J.bi=function(a,b){return J.w1(a).h(a,b)}
 J.bj=function(a,b){return J.w1(a).FV(a,b)}
 J.bs=function(a){return J.RE(a).JP(a)}
 J.c1=function(a,b){return J.Wx(a).O(a,b)}
 J.c9=function(a,b){return J.RE(a).sa4(a,b)}
-J.cW=function(a,b){return J.RE(a).st5(a,b)}
+J.cO=function(a){return J.RE(a).gq6(a)}
 J.cZ=function(a,b,c,d){return J.RE(a).On(a,b,c,d)}
 J.co=function(a,b){return J.rY(a).nC(a,b)}
 J.de=function(a,b){if(a==null)return b==null
 if(typeof a!="object")return b!=null&&a===b
 return J.x(a).n(a,b)}
 J.e2=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){return J.RE(a).nH(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)}
-J.eI=function(a,b){return J.RE(a).bA(a,b)}
+J.eh=function(a,b){return J.RE(a).Ne(a,b)}
 J.f5=function(a){return J.RE(a).gI(a)}
-J.fo=function(a,b){return J.RE(a).oC(a,b)}
+J.ff=function(a,b,c){return J.U6(a).Pk(a,b,c)}
+J.hf=function(a,b,c){return J.U6(a).XU(a,b,c)}
 J.i4=function(a,b){return J.w1(a).Zv(a,b)}
+J.iG=function(a,b){return J.RE(a).szZ(a,b)}
 J.iZ=function(a){return J.RE(a).gzZ(a)}
 J.jf=function(a,b){return J.x(a).T(a,b)}
 J.kE=function(a,b){return J.U6(a).tg(a,b)}
@@ -23312,9 +23664,12 @@
 J.lB=function(a){return J.RE(a).gP1(a)}
 J.lE=function(a,b){return J.rY(a).j(a,b)}
 J.m4=function(a){return J.RE(a).gig(a)}
+J.mQ=function(a,b){if(typeof a=="number"&&typeof b=="number")return(a&b)>>>0
+return J.Wx(a).i(a,b)}
 J.nX=function(a){return J.RE(a).gjb(a)}
 J.oE=function(a,b){return J.Qc(a).iM(a,b)}
 J.og=function(a,b){return J.RE(a).sIt(a,b)}
+J.on=function(a){return J.RE(a).gtT(a)}
 J.p0=function(a,b){if(typeof a=="number"&&typeof b=="number")return a*b
 return J.Wx(a).U(a,b)}
 J.pO=function(a){return J.U6(a).gor(a)}
@@ -23327,19 +23682,24 @@
 J.rP=function(a,b){return J.RE(a).sTq(a,b)}
 J.rr=function(a){return J.rY(a).bS(a)}
 J.t8=function(a,b){return J.RE(a).FL(a,b)}
+J.tH=function(a,b){return J.w1(a).KI(a,b)}
 J.ta=function(a,b){return J.RE(a).sP(a,b)}
+J.td=function(a){return J.RE(a).gng(a)}
 J.tx=function(a){return J.RE(a).guD(a)}
 J.u1=function(a,b){return J.Wx(a).WZ(a,b)}
+J.u3=function(a){return J.RE(a).geT(a)}
 J.u6=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<b
 return J.Wx(a).C(a,b)}
+J.uH=function(a,b){return J.rY(a).Fr(a,b)}
+J.uY=function(a,b,c){return J.RE(a).r4(a,b,c)}
 J.uf=function(a){return J.RE(a).gxr(a)}
 J.v1=function(a){return J.x(a).giO(a)}
 J.vF=function(a){return J.RE(a).gbP(a)}
-J.vi=function(a){return J.RE(a).gq6(a)}
 J.vo=function(a,b){return J.w1(a).ev(a,b)}
 J.w8=function(a){return J.RE(a).gkc(a)}
 J.wC=function(a){return J.RE(a).cO(a)}
 J.wX=function(a){return J.RE(a).gGd(a)}
+J.wc=function(a){return J.RE(a).gbG(a)}
 J.wg=function(a,b){return J.U6(a).sB(a,b)}
 J.xH=function(a,b){if(typeof a=="number"&&typeof b=="number")return a-b
 return J.Wx(a).W(a,b)}
@@ -23358,17 +23718,17 @@
 C.Fm=new J.kn()
 C.yX=new J.GW()
 C.wq=new J.im()
+C.x0=new J.ht()
 C.oD=new J.P()
 C.Kn=new J.O()
-C.lM=new P.by()
 C.mI=new K.nd()
 C.Us=new A.yL()
 C.nJ=new K.vly()
 C.Wj=new P.JF()
 C.za=new A.jh()
 C.NU=new P.R8()
-C.v8=new P.W5()
-C.YZ=Q.kf.prototype
+C.v8=new P.nU()
+C.YZ=Q.Tg.prototype
 C.kk=Z.Ps.prototype
 C.WA=new L.WAE("Collected")
 C.l8=new L.WAE("Dart")
@@ -23380,59 +23740,59 @@
 C.Vy=new A.V3("disassembly-entry")
 C.Br=new A.V3("observatory-element")
 C.dA=new A.V3("heap-profile")
-C.Er=new A.V3("script-view")
+C.I3=new A.V3("script-view")
 C.E6=new A.V3("field-ref")
 C.aM=new A.V3("isolate-summary")
 C.Is=new A.V3("response-viewer")
 C.nu=new A.V3("function-view")
-C.bp=new A.V3("isolate-profile")
+C.jR=new A.V3("isolate-profile")
 C.xW=new A.V3("code-view")
 C.aQ=new A.V3("class-view")
-C.Ob=new A.V3("library-view")
+C.Gg=new A.V3("library-view")
 C.U8=new A.V3("code-ref")
 C.rc=new A.V3("message-viewer")
 C.js=new A.V3("stack-trace")
-C.h9=new A.V3("script-ref")
+C.Ur=new A.V3("script-ref")
 C.OS=new A.V3("class-ref")
-C.jF=new A.V3("isolate-list")
-C.PT=new A.V3("breakpoint-list")
+C.jFV=new A.V3("isolate-list")
+C.lT=new A.V3("breakpoint-list")
 C.KG=new A.V3("navigation-bar")
 C.VW=new A.V3("instance-ref")
 C.Gu=new A.V3("collapsible-content")
-C.Xv=new A.V3("stack-frame")
+C.pE=new A.V3("stack-frame")
 C.y2=new A.V3("observatory-application")
 C.uW=new A.V3("error-view")
 C.KH=new A.V3("json-view")
 C.YQ=new A.V3("function-ref")
-C.uy=new A.V3("library-ref")
+C.QU=new A.V3("library-ref")
 C.Tq=new A.V3("field-view")
 C.JD=new A.V3("service-ref")
 C.be=new A.V3("instance-view")
-C.Tl=E.FvP.prototype
-C.RT=new P.a6(0)
-C.OD=F.Ir.prototype
+C.er=E.Fv.prototype
+C.ny=new P.a6(0)
+C.OD=F.E9.prototype
 C.mt=H.VM(new W.e0("change"),[W.ea])
-C.T1=H.VM(new W.e0("click"),[W.Aj])
+C.pi=H.VM(new W.e0("click"),[W.Oq])
 C.MD=H.VM(new W.e0("error"),[W.ew])
 C.PP=H.VM(new W.e0("hashchange"),[W.ea])
 C.i3=H.VM(new W.e0("input"),[W.ea])
 C.fK=H.VM(new W.e0("load"),[W.ew])
 C.ph=H.VM(new W.e0("message"),[W.DD])
 C.MC=D.m8.prototype
-C.LT=A.jM.prototype
-C.Xo=U.DKl.prototype
-C.PJ=N.mk.prototype
+C.LT=A.Gk.prototype
+C.Xo=U.GG.prototype
+C.Yu=N.yb.prototype
 C.Vc=K.NM.prototype
 C.W3=W.zU.prototype
 C.cp=B.pR.prototype
 C.yK=Z.hx.prototype
 C.b9=L.u7.prototype
 C.XH=X.E7.prototype
-C.nM=D.St.prototype
+C.Qt=D.St.prototype
 C.Nm=J.Q.prototype
-C.YI=J.GW.prototype
+C.ON=J.GW.prototype
 C.jn=J.im.prototype
-C.jN=J.PE.prototype
+C.jN=J.ht.prototype
 C.CD=J.P.prototype
 C.xB=J.O.prototype
 C.Mc=function(hooks) {
@@ -23565,42 +23925,43 @@
   hooks.getTag = getTagFixed;
   hooks.prototypeForTag = prototypeForTagFixed;
 }
+C.xr=new P.by(null,null)
 C.A3=new P.Cf(null)
-C.Ap=new P.pD(null)
+C.Ap=new P.dI(null)
 C.GB=Z.vj.prototype
 C.Ab=new N.qV("FINER",400)
 C.R5=new N.qV("FINE",500)
 C.IF=new N.qV("INFO",800)
-C.xl=new N.qV("SEVERE",1000)
+C.cV=new N.qV("SEVERE",1000)
 C.UP=new N.qV("WARNING",900)
 C.Z3=R.LU.prototype
-C.MG=M.CX.prototype
+C.MG=M.T2.prototype
 I.makeConstantList = function(list) {
   list.immutable$list = init;
   list.fixed$length = init;
   return list;
 };
-C.Gb=H.VM(I.makeConstantList([127,2047,65535,1114111]),[J.im])
 C.HE=I.makeConstantList([0,0,26624,1023,0,0,65534,2047])
 C.mK=I.makeConstantList([0,0,26624,1023,65534,2047,65534,2047])
 C.yD=I.makeConstantList([0,0,26498,1023,65534,34815,65534,18431])
+C.PQ=I.makeConstantList(["active","success","warning","danger","info"])
 C.xu=I.makeConstantList([43,45,42,47,33,38,60,61,62,63,94,124])
 C.u0=I.makeConstantList(["==","!=","<=",">=","||","&&"])
-C.Fv=H.VM(I.makeConstantList([]),[J.O])
 C.Me=H.VM(I.makeConstantList([]),[P.Ms])
-C.dn=H.VM(I.makeConstantList([]),[P.tg])
+C.dn=H.VM(I.makeConstantList([]),[P.ac])
 C.hU=H.VM(I.makeConstantList([]),[P.X9])
+C.iH=H.VM(I.makeConstantList([]),[J.im])
 C.xD=I.makeConstantList([])
 C.Qy=I.makeConstantList(["in","this"])
 C.kg=I.makeConstantList([0,0,24576,1023,65534,34815,65534,18431])
 C.Wd=I.makeConstantList([0,0,32722,12287,65535,34815,65534,18431])
 C.iq=I.makeConstantList([40,41,91,93,123,125])
-C.jH=I.makeConstantList(["caption","col","colgroup","option","optgroup","tbody","td","tfoot","th","thead","tr"])
-C.uE=new H.LPe(11,{caption:null,col:null,colgroup:null,option:null,optgroup:null,tbody:null,td:null,tfoot:null,th:null,thead:null,tr:null},C.jH)
+C.zJ=I.makeConstantList(["caption","col","colgroup","option","optgroup","tbody","td","tfoot","th","thead","tr"])
+C.uE=new H.LPe(11,{caption:null,col:null,colgroup:null,option:null,optgroup:null,tbody:null,td:null,tfoot:null,th:null,thead:null,tr:null},C.zJ)
 C.uS=I.makeConstantList(["webkitanimationstart","webkitanimationend","webkittransitionend","domfocusout","domfocusin","animationend","animationiteration","animationstart","doubleclick","fullscreenchange","fullscreenerror","keyadded","keyerror","keymessage","needkey","speechchange"])
 C.FS=new H.LPe(16,{webkitanimationstart:"webkitAnimationStart",webkitanimationend:"webkitAnimationEnd",webkittransitionend:"webkitTransitionEnd",domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn",animationend:"webkitAnimationEnd",animationiteration:"webkitAnimationIteration",animationstart:"webkitAnimationStart",doubleclick:"dblclick",fullscreenchange:"webkitfullscreenchange",fullscreenerror:"webkitfullscreenerror",keyadded:"webkitkeyadded",keyerror:"webkitkeyerror",keymessage:"webkitkeymessage",needkey:"webkitneedkey",speechchange:"webkitSpeechChange"},C.uS)
-C.NI=I.makeConstantList(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
-C.dj=new H.LPe(27,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.NI)
+C.p5=I.makeConstantList(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
+C.dj=new H.LPe(27,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.p5)
 C.paX=I.makeConstantList(["name","extends","constructor","noscript","attributes"])
 C.kr=new H.LPe(5,{name:1,extends:1,constructor:1,noscript:1,attributes:1},C.paX)
 C.MEG=I.makeConstantList(["enumerate"])
@@ -23614,10 +23975,10 @@
 C.Pf=Z.uL.prototype
 C.xk=A.XP.prototype
 C.Iv=A.ir.prototype
-C.Cc=Q.NQ.prototype
+C.Cc=Q.JG.prototype
 C.c0=A.knI.prototype
 C.cJ=U.fI.prototype
-C.ep=Q.xI.prototype
+C.wU=Q.xI.prototype
 C.dX=K.nm.prototype
 C.bg=X.Vu.prototype
 C.PU=new H.GD("dart.core.Object")
@@ -23638,6 +23999,7 @@
 C.nN=new H.GD("dynamic")
 C.tP=new H.GD("entry")
 C.YU=new H.GD("error")
+C.mr=new H.GD("expanded")
 C.WQ=new H.GD("field")
 C.SK=new H.GD("fileAndLine")
 C.Aq=new H.GD("formattedAverage")
@@ -23658,15 +24020,16 @@
 C.zD=new H.GD("internal")
 C.ai=new H.GD("isEmpty")
 C.nZ=new H.GD("isNotEmpty")
-C.Y2=new H.GD("isolate")
+C.Z8=new H.GD("isolate")
 C.Gd=new H.GD("json")
 C.fy=new H.GD("kind")
 C.Wn=new H.GD("length")
 C.EV=new H.GD("library")
 C.cg=new H.GD("libraryRef")
+C.Cv=new H.GD("line")
 C.AX=new H.GD("links")
 C.PC=new H.GD("dart.core.int")
-C.wt=new H.GD("members")
+C.zu=new H.GD("members")
 C.US=new H.GD("messageType")
 C.fQ=new H.GD("methodCountSelected")
 C.UX=new H.GD("msg")
@@ -23675,12 +24038,13 @@
 C.OV=new H.GD("noSuchMethod")
 C.ap=new H.GD("oldHeapUsed")
 C.tI=new H.GD("percent")
-C.NA=new H.GD("prefix")
+C.qb3=new H.GD("prefix")
 C.vb=new H.GD("profile")
 C.kY=new H.GD("ref")
 C.c8=new H.GD("registerCallback")
+C.bD=new H.GD("relativeLink")
 C.wH=new H.GD("responses")
-C.iG=new H.GD("rootLib")
+C.iF=new H.GD("rootLib")
 C.ok=new H.GD("dart.core.Null")
 C.md=new H.GD("dart.core.double")
 C.fX=new H.GD("script")
@@ -23690,85 +24054,92 @@
 C.p1=new H.GD("ticks")
 C.jI=new H.GD("topExclusiveCodes")
 C.ch=new H.GD("topFrame")
-C.Yn=new H.GD("topInclusiveCodes")
 C.kw=new H.GD("trace")
+C.ep=new H.GD("tree")
 C.Fh=new H.GD("url")
-C.wj=new H.GD("user_name")
+C.ct=new H.GD("userName")
 C.ls=new H.GD("value")
 C.eR=new H.GD("valueType")
 C.z9=new H.GD("void")
 C.SX=H.mm('qC')
 C.WP=new H.Lm(C.SX,"K",0)
-C.brK=H.mm('Ae')
-C.xC=new H.Lm(C.brK,"V",0)
+C.SL=H.mm('Ae')
+C.xC=new H.Lm(C.SL,"V",0)
 C.QJ=H.mm('xh')
 C.wW=new H.Lm(C.QJ,"T",0)
 C.Gsc=H.mm('wn')
 C.io=new H.Lm(C.Gsc,"E",0)
 C.nz=new H.Lm(C.SX,"V",0)
 C.Ye=H.mm('hx')
+C.q0=H.mm('Dg')
+C.z6Y=H.mm('Tg')
 C.Dl=H.mm('F1')
-C.MZ=H.mm('ue')
-C.XoM=H.mm('DKl')
+C.eY=H.mm('n6')
+C.Vh=H.mm('Pz')
+C.RJ=H.mm('JG')
 C.z7=H.mm('G6')
 C.nY=H.mm('a')
 C.Yc=H.mm('iP')
 C.Qa=H.mm('u7')
-C.KI=H.mm('CX')
-C.Op=H.mm('G8')
-C.q4=H.mm('NQ')
+C.PT=H.mm('I2')
+C.Wup=H.mm('LZ')
+C.T1=H.mm('Wy')
 C.hG=H.mm('ir')
 C.aj=H.mm('fI')
+C.Qw=H.mm('Fv')
+C.la=H.mm('ZX')
 C.G4=H.mm('CN')
 C.O4=H.mm('double')
-C.nx=H.mm('fbd')
 C.yw=H.mm('int')
-C.KJ=H.mm('mk')
-C.pa=H.mm('jM')
-C.yiu=H.mm('knI')
-C.CO=H.mm('iY')
-C.eh=H.mm('xI')
-C.nA=H.mm('LU')
-C.uue=H.mm('kf')
+C.nW=H.mm('knI')
+C.iN=H.mm('yc')
+C.HI=H.mm('Pg')
+C.ila=H.mm('xI')
+C.lk=H.mm('mJ')
+C.KI=H.mm('LU')
+C.jV=H.mm('rF')
 C.JZ=H.mm('E7')
 C.wd=H.mm('vj')
 C.Oi=H.mm('Xd')
-C.CT=H.mm('St')
+C.Pa=H.mm('St')
+C.Rg=H.mm('yb')
 C.cx5=H.mm('m8')
-C.YV=H.mm('uL')
-C.nW=H.mm('GG')
+C.l49=H.mm('uL')
 C.yQ=H.mm('EH')
+C.Im=H.mm('X6')
 C.vW6=H.mm('PF')
-C.HMu=H.mm('vc')
+C.nG=H.mm('zt')
+C.Xb=H.mm('vc')
 C.yG=H.mm('nm')
+C.ow=H.mm('E9')
 C.Db=H.mm('String')
-C.Rg=H.mm('NM')
+C.EP=H.mm('NM')
 C.bh=H.mm('i6')
 C.Bm=H.mm('XP')
-C.MY=H.mm('hd')
+C.Tn=H.mm('T2')
+C.hg=H.mm('hd')
 C.dd=H.mm('pR')
 C.Ud8=H.mm('Ps')
+C.zy=H.mm('GG')
 C.pn=H.mm('qT')
 C.HL=H.mm('bool')
-C.Qf=H.mm('PE')
+C.Qf=H.mm('Null')
 C.HH=H.mm('dynamic')
 C.Gp=H.mm('cw')
 C.ri=H.mm('yy')
-C.X0=H.mm('Ir')
 C.CS=H.mm('vm')
-C.Rt=H.mm('Vu')
-C.SM=H.mm('FvP')
+C.Hk=H.mm('Gk')
+C.hN=H.mm('oI')
+C.IWi=H.mm('Vu')
 C.vB=J.is.prototype
 C.xM=new P.z0(!1)
 C.ol=W.u9.prototype
-C.hi=H.VM(new W.hP(W.pq()),[W.OJ])
+C.hi=H.VM(new W.bO(W.pq()),[W.OJ])
 $.libraries_to_load = {}
-$.D5=null
-$.ty=1
 $.te="$cachedFunction"
 $.eb="$cachedInvocation"
 $.OK=0
-$.mJ=null
+$.bf=null
 $.P4=null
 $.Ot=!1
 $.NF=null
@@ -23779,7 +24150,8 @@
 $.Bv=null
 $.oK=null
 $.tY=null
-$.TH=!1
+$.S6=null
+$.k8=null
 $.X3=C.NU
 $.Ss=0
 $.L4=null
@@ -23795,8 +24167,8 @@
 $.Bh=0
 $.uP=!0
 $.To=null
-$.Dq=["A8","Ak","B2","BN","BT","BX","Ba","Bf","C","C0","C8","Ch","D","D3","D6","Dd","De","E","Ec","F","FL","FV","Fr","GB","GG","HG","Hn","Hs","IW","Id","Ih","Im","Is","J","J3","JP","JV","Ja","Jk","Kb","KdI","M8","Md","Mi","Mu","NC","NZ","Nj","O","Om","On","PM","PQ","Pa","Pk","Pv","Pz","Q0","Qi","R3","R4","RB","RP","RR","Rg","Rz","SS","Se","So","T","T2","TP","TW","Tc","Tk","Tp","U","UD","UH","UZ","Ub","Uc","V","V1","Vk","Vr","W","W3","W4","WL","WO","WZ","Wt","X6","XG","XU","Xl","Y","Y9","YU","YW","Z","Z1","Z2","ZL","Ze","Zv","aC","aN","aZ","aq","bA","bS","bj","br","bu","cO","cU","cn","cp","ct","d0","dR","dd","du","eR","ea","ek","eo","er","es","ev","ez","f6","fk","fm","g","gA","gAq","gAy","gB","gB1","gBA","gBb","gCO","gCd","gCj","gDD","gF0","gG0","gG1","gG3","gGQ","gGd","gGj","gHX","gHu","gI","gJ0","gJS","gJf","gJp","gKE","gKM","gKV","gLA","gLm","gM0","gMB","gMU","gMj","gN","gN7","gNF","gNI","gNa","gNh","gO3","gOc","gOl","gP","gP1","gPe","gPu","gPw","gPy","gQ7","gQW","gQg","gQr","gRA","gRn","gRu","gT8","gTq","gUQ","gUV","gUj","gUy","gUz","gV4","gVa","gVl","gW0","gX3","gXc","gXh","gXt","gZ8","gZf","gZm","ga4","gaK","gai","gan","gbG","gbP","gbx","gcC","ge6","geE","geJ","geT","geb","gey","gfN","gfY","gfb","ghf","ghm","gi9","giC","giO","giZ","gig","gjL","gjO","gjb","gk5","gkG","gkU","gkc","gkf","gkp","gl0","gl7","glc","gm0","gmH","gmW","gmm","gnv","goc","gor","gpQ","gpo","gq6","gqY","gqn","grK","grZ","grs","gt0","gt5","gtD","gtH","gtK","gtN","gtT","gtY","gtb","gtgn","gtp","guD","guw","gvH","gvL","gvc","gvt","gwd","gx8","gxX","gxj","gxr","gyP","gyT","gys","gz1","gzP","gzZ","gzh","gzj","h","h8","hZ","hc","hr","i","i4","iA","iM","iw","j","jT","jh","jp","jx","k0","kO","l5","lJ","lj","m","mK","mv","n","n8","nB","nC","nH","nN","ni","nq","oB","oC","oP","oW","oX","od","oo","pM","pZ","pr","ps","q1","qA","qC","qZ","r6","rJ","sAq","sB","sB1","sBA","sCO","sF0","sG1","sGQ","sGj","sHX","sHu","sIt","sJ0","sMU","sMj","sN7","sNI","sNa","sNh","sOc","sOl","sP","sPe","sPw","sPy","sQr","sRu","sTq","sUy","sUz","sV4","sVa","sX3","sXc","sXh","sZ8","sa4","sai","san","scC","se6","seE","seJ","seb","sfY","shm","siZ","sig","sjO","sk5","skc","skf","sl7","sm0","snv","soc","sqY","srK","srs","st0","st5","stD","stK","stN","stT","stY","stb","suw","svL","svt","sxj","sxr","sz1","szZ","szh","szj","t","tX","tZ","te","tg","tt","u","u8","uB","uq","wE","wH","wL","wR","wW","wY","wg","x3","xc","xe","xo","y0","yC","yG","yM","yN","yc","ym","yn","yq","yu","yx","yy","z2","zV","zr"]
-$.Au=[C.Ye,Z.hx,{created:Z.Co},C.Dl,V.F1,{created:V.fv},C.MZ,P.ue,{"":P.q3},C.XoM,U.DKl,{created:U.v9},C.z7,B.G6,{created:B.Dw},C.Qa,L.u7,{created:L.Cu},C.KI,M.CX,{created:M.SP},C.Op,P.G8,{},C.q4,Q.NQ,{created:Q.Zo},C.hG,A.ir,{created:A.oa},C.aj,U.fI,{created:U.Ry},C.G4,O.CN,{created:O.On},C.nx,P.fbd,{},C.KJ,N.mk,{created:N.N0},C.pa,A.jM,{created:A.cY},C.yiu,A.knI,{created:A.Th},C.CO,P.iY,{"":P.am},C.eh,Q.xI,{created:Q.lK},C.nA,R.LU,{created:R.rA},C.uue,Q.kf,{created:Q.rt},C.JZ,X.E7,{created:X.jD},C.wd,Z.vj,{created:Z.mA},C.Oi,F.Xd,{created:F.L1},C.CT,D.St,{created:D.JR},C.cx5,D.m8,{created:D.Tt},C.YV,Z.uL,{created:Z.Hx},C.nW,P.GG,{"":P.l6},C.vW6,L.PF,{created:L.A5},C.HMu,F.vc,{created:F.Fe},C.yG,K.nm,{created:K.an},C.Rg,K.NM,{created:K.op},C.bh,R.i6,{created:R.Hv},C.Bm,A.XP,{created:A.XL},C.MY,W.hd,{},C.dd,B.pR,{created:B.lu},C.Ud8,Z.Ps,{created:Z.zg},C.pn,Q.qT,{created:Q.BW},C.ri,W.yy,{},C.X0,F.Ir,{created:F.TW},C.Rt,X.Vu,{created:X.bV},C.SM,E.FvP,{created:E.AH}]
+$.Dq=["AZ","Ak","B2","BN","BT","BX","Ba","Bf","Bk","C","C0","C4","CL","Ch","D","D3","D6","Dd","De","E","Ec","F","FL","FV","Fr","G6","GB","GG","GT","HG","Hn","Hs","IW","Id","Ih","Is","J","J2","J3","JG","JP","JV","Ja","Jk","KI","Kb","LV","LZ","M8","Md","Mi","Mq","Mu","NC","NZ","Ne","Nj","O","Om","On","PM","PQ","PZ","Pa","Pk","Pv","Pz","Q0","Qi","Qq","R3","R4","RB","RP","RR","Rg","Rz","SS","Se","T","TJ","TP","TW","Ta","Tc","Tk","Tp","U","UD","UH","UZ","Ub","Uc","V","V1","VR","Vk","Vr","W","W3","W4","WL","WO","WZ","Wt","X6","XG","XL","XU","Xl","Y","Y9","YF","YU","YW","Z","Z1","Z2","ZB","ZL","Zc","Ze","Zv","aC","aN","aZ","bA","bS","bj","br","bu","cO","cU","cn","cp","ct","d0","dR","dd","du","eR","ea","ek","eo","er","es","ev","ez","f6","f9","fk","fm","fz","g","gA","gAq","gAy","gB","gB1","gBA","gBW","gCO","gCY","gCd","gCj","gDD","gEh","gF0","gF8","gG0","gG1","gG3","gGQ","gGd","gGj","gHX","gHm","gHu","gI","gIF","gIt","gJ0","gJS","gJf","gJp","gKE","gKM","gKV","gLA","gLm","gLx","gM0","gMB","gMj","gMt","gN","gN7","gNF","gNI","gNa","gNh","gNl","gO3","gOc","gOl","gP","gP1","gPe","gPu","gPw","gPy","gQ7","gQW","gQg","gQr","gRA","gRd","gRn","gRu","gTq","gUQ","gUV","gUj","gUy","gUz","gV4","gVa","gVl","gW0","gWT","gX3","gXc","gXh","gXt","gZ8","gZf","ga4","gaK","gai","gan","gbG","gbP","gbx","gcC","ge6","geJ","geT","geb","gey","gfN","gfY","gfb","gfc","ghU","ghf","ghm","gi9","giC","giO","gig","gjL","gjO","gjT","gjb","gk5","gkG","gkU","gkc","gkf","gkp","gl0","gl7","glc","gm0","gm2","gmH","gmW","gmm","gng","gnv","goE","goc","gor","gpQ","gpo","gq6","gqO","gqX","gqY","gqn","grK","grZ","grj","grs","gt0","gt5","gtD","gtH","gtN","gtT","gtY","gtp","guD","guw","gvH","gvL","gvc","gvt","gwd","gx8","gxX","gxj","gxr","gyH","gyT","gys","gz1","gzP","gzZ","gzh","gzj","gzw","h","h8","hZ","hc","hr","i","i4","iM","iw","j","jh","jp","jx","k0","kO","ka","l5","lj","m","mK","n","nB","nC","nH","ni","nq","nt","oB","oC","oP","oW","oZ","od","oo","pM","pZ","pr","ps","q1","qA","qC","qH","qZ","r4","r6","rJ","sAq","sAy","sB","sB1","sBA","sBW","sCO","sCY","sCd","sCj","sEh","sF0","sF8","sG1","sG3","sGQ","sGd","sGj","sHX","sHm","sHu","sIF","sIt","sJ0","sJS","sKM","sKV","sLA","sLx","sM0","sMB","sMj","sMt","sN","sN7","sNF","sNI","sNa","sNh","sNl","sO3","sOc","sOl","sP","sPe","sPu","sPw","sPy","sQ7","sQr","sRA","sRd","sRn","sRu","sTq","sUQ","sUy","sUz","sV4","sVa","sWT","sX3","sXc","sXh","sXt","sZ8","sa4","saK","sai","san","sbG","sbP","scC","se6","seJ","seT","seb","sfN","sfY","sfb","sfc","shU","shf","shm","siC","sig","sjL","sjO","sjT","sjb","sk5","skG","skU","skc","skf","skp","sl7","sm0","sm2","smH","sng","snv","soE","soc","spQ","spo","sq6","sqO","sqX","sqY","srK","srs","st0","st5","stD","stN","stT","stY","suD","suw","svH","svL","svt","swd","sxX","sxj","sxr","syH","syT","sys","sz1","szZ","szh","szj","szw","t","tZ","tg","tt","tx","u","u8","uB","w","wE","wH","wL","wR","wW","wg","x3","xc","xe","xo","y0","yC","yF","yG","yM","yN","yc","ym","yn","yq","yu","yx","yy","z2","zV","zr"]
+$.Au=[C.Ye,Z.hx,{created:Z.HC},C.q0,H.Dg,{"":H.bu},C.z6Y,Q.Tg,{created:Q.rt},C.Dl,V.F1,{created:V.fv},C.RJ,Q.JG,{created:Q.Zo},C.z7,B.G6,{created:B.Dw},C.Qa,L.u7,{created:L.Cu},C.Wup,H.LZ,{"":H.UI},C.hG,A.ir,{created:A.oa},C.aj,U.fI,{created:U.Ry},C.Qw,E.Fv,{created:E.AH},C.G4,O.CN,{created:O.On},C.nW,A.knI,{created:A.Th},C.HI,H.Pg,{"":H.aR},C.ila,Q.xI,{created:Q.lK},C.KI,R.LU,{created:R.rA},C.JZ,X.E7,{created:X.jD},C.wd,Z.vj,{created:Z.mA},C.Oi,F.Xd,{created:F.L1},C.Pa,D.St,{created:D.JR},C.Rg,N.yb,{created:N.N0},C.cx5,D.m8,{created:D.Tt},C.l49,Z.uL,{created:Z.Hx},C.vW6,L.PF,{created:L.A5},C.Xb,F.vc,{created:F.Fe},C.yG,K.nm,{created:K.an},C.ow,F.E9,{created:F.TW},C.EP,K.NM,{created:K.op},C.bh,R.i6,{created:R.Hv},C.Bm,A.XP,{created:A.XL},C.Tn,M.T2,{created:M.SP},C.hg,W.hd,{},C.dd,B.pR,{created:B.b4},C.Ud8,Z.Ps,{created:Z.zg},C.zy,U.GG,{created:U.v9},C.pn,Q.qT,{created:Q.BW},C.ri,W.yy,{},C.Hk,A.Gk,{created:A.cY},C.IWi,X.Vu,{created:X.B4}]
 I.$lazy($,"globalThis","DX","jk",function(){return function() { return this; }()})
 I.$lazy($,"globalWindow","pG","Qm",function(){return $.jk().window})
 I.$lazy($,"globalWorker","zA","Nl",function(){return $.jk().Worker})
@@ -23842,24 +24214,21 @@
 I.$lazy($,"customElementsReady","xp","ax",function(){return new B.wJ().call$0()})
 I.$lazy($,"_toStringList","Ml","RM",function(){return[]})
 I.$lazy($,"validationPattern","zP","R0",function(){return new H.VR(H.v4("^(?:[a-zA-Z$][a-zA-Z$0-9_]*\\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|-|unary-|\\[\\]=|~|==|\\[\\]|\\*|/|%|~/|\\+|<<|>>|>=|>|<=|<|&|\\^|\\|)$",!1,!0,!1),null,null)})
-I.$lazy($,"_dynamicType","QG","Cr",function(){return new H.EE(C.nN)})
+I.$lazy($,"_dynamicType","QG","P8",function(){return new H.EE(C.nN)})
 I.$lazy($,"_voidType","Q3","oj",function(){return new H.EE(C.z9)})
 I.$lazy($,"librariesByName","Ct","vK",function(){return H.dF()})
 I.$lazy($,"currentJsMirrorSystem","GR","Cm",function(){return new H.Sn(null,new H.Lj(init.globalState.N0))})
 I.$lazy($,"mangledNames","tj","bx",function(){return H.hY(init.mangledNames,!1)})
 I.$lazy($,"reflectiveNames","DE","I6",function(){return H.YK($.bx())})
 I.$lazy($,"mangledGlobalNames","iC","Sl",function(){return H.hY(init.mangledGlobalNames,!0)})
-I.$lazy($,"_asyncCallbacks","r1","P8",function(){var z,y
-z={func:"X0",void:true}
-y=H.VM(new P.Sw(null,0,0,0),[z])
-y.Eo(null,z)
-return y})
 I.$lazy($,"_toStringVisiting","xg","xb",function(){return P.yv(null)})
 I.$lazy($,"_toStringList","yu","tw",function(){return[]})
-I.$lazy($,"_splitRe","Um","cO",function(){return new H.VR(H.v4("^(?:([^:/?#]+):)?(?://(?:([^/?#]*)@)?(?:([\\w\\d\\-\\u0100-\\uffff.%]*)|\\[([A-Fa-f0-9:.]*)\\])(?::([0-9]+))?)?([^?#[]+)?(?:\\?([^#]*))?(?:#(.*))?$",!1,!0,!1),null,null)})
+I.$lazy($,"_splitRe","Um","qG",function(){return new H.VR(H.v4("^(?:([^:/?#]+):)?(?://(?:([^/?#]*)@)?(?:([\\w\\d\\-\\u0100-\\uffff.%]*)|\\[([A-Fa-f0-9:.]*)\\])(?::([0-9]+))?)?([^?#[]+)?(?:\\?([^#]*))?(?:#(.*))?$",!1,!0,!1),null,null)})
 I.$lazy($,"_safeConsole","wk","pl",function(){return new W.QZ()})
 I.$lazy($,"webkitEvents","fD","Vp",function(){return H.B7(["animationend","webkitAnimationEnd","animationiteration","webkitAnimationIteration","animationstart","webkitAnimationStart","fullscreenchange","webkitfullscreenchange","fullscreenerror","webkitfullscreenerror","keyadded","webkitkeyadded","keyerror","webkitkeyerror","keymessage","webkitkeymessage","needkey","webkitneedkey","pointerlockchange","webkitpointerlockchange","pointerlockerror","webkitpointerlockerror","resourcetimingbufferfull","webkitresourcetimingbufferfull","transitionend","webkitTransitionEnd","speechchange","webkitSpeechChange"],P.L5(null,null,null,null,null))})
 I.$lazy($,"context","eo","cM",function(){return P.ND(function() { return this; }())})
+I.$lazy($,"_DART_OBJECT_PROPERTY_NAME","kt","Iq",function(){return init.getIsolateTag("_$dart_dartObject")})
+I.$lazy($,"_DART_CLOSURE_PROPERTY_NAME","Ri","Dp",function(){return init.getIsolateTag("_$dart_dartClosure")})
 I.$lazy($,"_loggers","DY","U0",function(){return H.VM(H.B7([],P.L5(null,null,null,null,null)),[J.O,N.TJ])})
 I.$lazy($,"currentIsolateMatcher","qY","oy",function(){return new H.VR(H.v4("#/isolates/\\d+",!1,!0,!1),null,null)})
 I.$lazy($,"currentIsolateProfileMatcher","HT","wf",function(){return new H.VR(H.v4("#/isolates/\\d+/profile",!1,!0,!1),null,null)})
@@ -23872,22 +24241,13 @@
 I.$lazy($,"_pathRegExp","Jm","tN",function(){return new L.Md().call$0()})
 I.$lazy($,"_spacesRegExp","JV","c3",function(){return new H.VR(H.v4("\\s",!1,!0,!1),null,null)})
 I.$lazy($,"_logger","y7","aT",function(){return N.Jx("observe.PathObserver")})
-I.$lazy($,"url","As","jo",function(){var z,y
-z=$.wE()
-y=z==null?B.ab():"."
-if(z==null)z=$.Ur()
-return new F.lI(z,y)})
-I.$lazy($,"posix","yr","KL",function(){return new Z.OF("posix","/",new H.VR(H.v4("/",!1,!0,!1),null,null),new H.VR(H.v4("[^/]$",!1,!0,!1),null,null),new H.VR(H.v4("^/",!1,!0,!1),null,null),null)})
-I.$lazy($,"windows","ho","CE",function(){return new T.IV("windows","\\",new H.VR(H.v4("[/\\\\]",!1,!0,!1),null,null),new H.VR(H.v4("[^/\\\\]$",!1,!0,!1),null,null),new H.VR(H.v4("^(\\\\\\\\[^\\\\]+\\\\[^\\\\/]+|[a-zA-Z]:[/\\\\])",!1,!0,!1),null,null),new H.VR(H.v4("^[/\\\\](?![/\\\\])",!1,!0,!1),null,null),null)})
-I.$lazy($,"url","aC","wE",function(){return new E.rM("url","/",new H.VR(H.v4("/",!1,!0,!1),null,null),new H.VR(H.v4("(^[a-zA-Z][-+.a-zA-Z\\d]*://|[^/])$",!1,!0,!1),null,null),new H.VR(H.v4("[a-zA-Z][-+.a-zA-Z\\d]*://[^/]*",!1,!0,!1),null,null),new H.VR(H.v4("^/",!1,!0,!1),null,null),null)})
-I.$lazy($,"platform","Uc","Ur",function(){return S.Rh()})
 I.$lazy($,"_typesByName","Hi","Ej",function(){return P.L5(null,null,null,J.O,P.uq)})
 I.$lazy($,"_waitType","Mp","p2",function(){return P.L5(null,null,null,J.O,A.XP)})
 I.$lazy($,"_waitSuper","uv","xY",function(){return P.L5(null,null,null,J.O,[J.Q,A.XP])})
 I.$lazy($,"_declarations","EJ","cd",function(){return P.L5(null,null,null,J.O,A.XP)})
 I.$lazy($,"_objectType","Cy","Tf",function(){return P.re(C.nY)})
 I.$lazy($,"_sheetLog","Fa","vM",function(){return N.Jx("polymer.stylesheet")})
-I.$lazy($,"_reverseEventTranslations","fp","pT",function(){return new A.w11().call$0()})
+I.$lazy($,"_reverseEventTranslations","fp","QX",function(){return new A.w9().call$0()})
 I.$lazy($,"bindPattern","ZA","VC",function(){return new H.VR(H.v4("\\{\\{([^{}]*)}}",!1,!0,!1),null,null)})
 I.$lazy($,"_polymerSyntax","Df","Nd",function(){var z=P.L5(null,null,null,J.O,P.a)
 z.FV(0,C.va)
@@ -23902,23 +24262,19 @@
 I.$lazy($,"_librariesToLoad","x2","nT",function(){return A.GA(document,J.CC(C.ol.gmW(window)),null,null)})
 I.$lazy($,"_libs","D9","UG",function(){return $.Cm().gvU()})
 I.$lazy($,"_rootUri","aU","RQ",function(){return $.Cm().Aq.gcZ().gFP()})
-I.$lazy($,"_packageRoot","Po","rw",function(){var z,y
-z=$.jo()
-y=J.CC(C.ol.gmW(window))
-return z.tX(0,z.tM(P.r6($.cO().ej(y)).r0),"packages")+"/"})
 I.$lazy($,"_loaderLog","ha","M7",function(){return N.Jx("polymer.loader")})
-I.$lazy($,"_typeHandlers","FZ","WJ",function(){return new Z.W6().call$0()})
+I.$lazy($,"_typeHandlers","lq","CT",function(){return new Z.W6().call$0()})
 I.$lazy($,"_logger","m0","eH",function(){return N.Jx("polymer_expressions")})
-I.$lazy($,"_BINARY_OPERATORS","AM","e6",function(){return H.B7(["+",new K.Ra(),"-",new K.wJY(),"*",new K.zOQ(),"/",new K.W6o(),"==",new K.MdQ(),"!=",new K.YJG(),">",new K.DOe(),">=",new K.lPa(),"<",new K.Ufa(),"<=",new K.Raa(),"||",new K.w0(),"&&",new K.w4(),"|",new K.w5()],P.L5(null,null,null,null,null))})
-I.$lazy($,"_UNARY_OPERATORS","ju","ww",function(){return H.B7(["+",new K.w7(),"-",new K.w9(),"!",new K.w10()],P.L5(null,null,null,null,null))})
-I.$lazy($,"_checkboxEventType","S8","FF",function(){return new M.lP().call$0()})
+I.$lazy($,"_BINARY_OPERATORS","AM","e6",function(){return H.B7(["+",new K.lP(),"-",new K.Uf(),"*",new K.Ra(),"/",new K.wJY(),"==",new K.zOQ(),"!=",new K.W6o(),">",new K.MdQ(),">=",new K.YJG(),"<",new K.DOe(),"<=",new K.lPa(),"||",new K.Ufa(),"&&",new K.Raa(),"|",new K.w0()],P.L5(null,null,null,null,null))})
+I.$lazy($,"_UNARY_OPERATORS","ju","ww",function(){return H.B7(["+",new K.w4(),"-",new K.w5(),"!",new K.w7()],P.L5(null,null,null,null,null))})
+I.$lazy($,"_checkboxEventType","S8","FF",function(){return new M.YJ().call$0()})
 I.$lazy($,"_contentsOwner","mn","LQ",function(){return H.VM(new P.kM(null),[null])})
 I.$lazy($,"_ownerStagingDocument","EW","JM",function(){return H.VM(new P.kM(null),[null])})
-I.$lazy($,"_allTemplatesSelectors","Sf","cz",function(){return"template, "+J.C0(C.uE.gvc(C.uE),new M.Uf()).zV(0,", ")})
-I.$lazy($,"_expando","fF","cm",function(){return H.VM(new P.kM("template_binding"),[null])})
+I.$lazy($,"_allTemplatesSelectors","Sf","cz",function(){return"template, "+J.C0(C.uE.gvc(C.uE),new M.DO()).zV(0,", ")})
+I.$lazy($,"_expando","fF","rw",function(){return H.VM(new P.kM("template_binding"),[null])})
 
 init.functionAliases={}
-init.metadata=[P.a,C.WP,C.nz,C.xC,C.io,C.wW,"object","interceptor","proto","extension","indexability","type","name","codeUnit","isolate","function","entry","sender","e","msg","message","x","record","value","memberName",{func:"pL",args:[J.O]},"string","source","radix","handleError","array","codePoints","charCodes","years","month","day","hours","minutes","seconds","milliseconds","isUtc","receiver","key","positionalArguments","namedArguments","className","argument","index","ex","expression","keyValuePairs","result","closure","numberOfArguments","arg1","arg2","arg3","arg4","arity","functions","reflectionInfo","isStatic","jsArguments","propertyName","isIntercepted","fieldName","property","staticName","list","returnType","parameterTypes","optionalParameterTypes","rti","typeArguments","target","typeInfo","substitutionName",,"onTypeVariable","types","startIndex","substitution","arguments","isField","checks","asField","s","t","signature","context","contextName","o","allowShorter","obj","tag","interceptorClass","transformer","hooks","pattern","multiLine","caseSensitive","global","needle","haystack","other","from","to",{func:"X0",void:true},{func:"NT"},"iterable","f","initialValue","combine","leftDelimiter","rightDelimiter","start","end","skipCount","src","srcStart","dst","dstStart","count","a","element","endIndex","left","right","compare","symbol",{func:"pB",ret:P.vr,args:[P.a]},"reflectee","mangledName","methods","variables","mixinNames","code","typeVariables","owner","simpleName","victim","fieldSpecification","jsMangledNames","isGlobal","map","errorHandler","error","stackTrace","zone","listeners","callback","notificationHandler",{func:"G5",void:true,args:[null]},{func:"Vx",void:true,args:[null],opt:[P.MN]},"userCode","onSuccess","onError","subscription","future","duration",{func:"cX",void:true,args:[P.JB,P.e4,P.JB,null,P.MN]},"self","parent",{func:"aD",args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"wD",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]},null]},"arg",{func:"ta",args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]},null,null]},{func:"HQ",ret:{func:"NT"},args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"v7",ret:{func:"Dv",args:[null]},args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"IU",ret:{func:"bh",args:[null,null]},args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]}]},{func:"qH",void:true,args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"zo",ret:P.tU,args:[P.JB,P.e4,P.JB,P.a6,{func:"X0",void:true}]},{func:"Zb",void:true,args:[P.JB,P.e4,P.JB,J.O]},"line",{func:"xM",void:true,args:[J.O]},{func:"Nf",ret:P.JB,args:[P.JB,P.e4,P.JB,P.aY,[P.Z0,P.wv,null]]},"specification","zoneValues","table",{func:"Ib",ret:J.kn,args:[null,null]},"b",{func:"Re",ret:J.im,args:[null]},"parts","m","number","json","reviver",{func:"uJ",ret:P.a,args:[null]},"toEncodable","sb",{func:"xh",ret:J.im,args:[P.fR,P.fR]},"formattedString",{func:"E0",ret:J.kn,args:[P.a,P.a]},{func:"DZ",ret:J.im,args:[P.a]},{func:"K4",ret:J.im,args:[J.O],named:{onError:{func:"jK",ret:J.im,args:[J.O]},radix:J.im}},"segments","argumentError","host","scheme","query","queryParameters","fragment","component","val","val1","val2",{func:"zs",ret:J.O,args:[J.O]},"encodedComponent",C.xM,!1,"canonicalTable","text","encoding","spaceToPlus","pos","plusToSpace",{func:"Tf",ret:J.O,args:[W.D0]},"typeExtension","url","onProgress","withCredentials","method","mimeType","requestHeaders","responseType","sendData","thing","win","constructor",{func:"Dv",args:[null]},{func:"jn",args:[null,null,null,null]},"oldValue","newValue","document","extendsTagName","w","captureThis","data","createProxy","mustCopy","_","id","members",{func:"qE",ret:J.O,args:[J.im,J.im]},"pad","current","currentStart","currentEnd","old","oldStart","oldEnd","distances","arr1","arr2","searchLength","splices","records","field","args","cls","props","getter","template","extendee","sheet","node","path","originalPrepareBinding","methodName","style","scope","doc","baseUri","seen","scripts","uriString","currentValue","v","expr","l","hash",{func:"qq",ret:[P.cX,K.Ae],args:[P.cX]},"classMirror","c","delegate","model","bound","stagingDocument","el","useRoot","content","bindings","n","elementId","importedNode","deep","selectors","relativeSelectors","listener","useCapture","async","password","user","timestamp","canBubble","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","attributeFilter","attributeOldValue","attributes","characterData","characterDataOldValue","childList","subtree","otherNode","newChild","refChild","oldChild","targetOrigin","messagePorts","length","invocation","collection","","separator",0,!0,"growable","fractionDigits","str","i","portId","port","dataEvent","onData","cancelOnError","onDone","info",{func:"bh",args:[null,null]},"parameter","jsConstructor",{func:"Za",args:[J.O,null]},{func:"TS",args:[null,J.O]},"g",P.Z0,L.mL,[P.Z0,J.O,W.cv],{func:"qo",ret:P.Z0},C.nJ,C.Us,{func:"Hw",args:[P.Z0]},B.Vf,J.kn,Q.xI,Z.pv,L.kx,{func:"bR",ret:L.kx},{func:"VI",args:[L.kx]},{func:"I0",ret:J.O},F.Vfx,J.O,C.mI,{func:"Uf",ret:J.kn},{func:"zk",args:[J.kn]},"r",{func:"Np",void:true,args:[W.ea,null,W.uH]},R.Dsd,"action","test","library",{func:"h0",args:[H.Uz]},{func:"rm",args:[P.wv,P.ej]},"reflectiveName",{func:"lv",args:[P.wv,null]},"typeArgument","tv","methodOwner","fieldOwner",{func:"qe",ret:P.Ms,args:[J.im]},{func:"Z5",args:[J.im]},{func:"Pt",ret:J.O,args:[J.im]},{func:"ag",args:[J.O,J.O]},"eventId",{func:"uu",void:true,args:[P.a],opt:[P.MN]},{func:"YP",void:true,opt:[null]},{func:"BG",args:[null],opt:[null]},"ignored","convert","isMatch",{func:"rt",ret:P.b8},"pendingEvents","handleData","handleDone","resumeSignal","event","wasInputPaused",{func:"wN",void:true,args:[P.MO]},"dispatch",{func:"ha",args:[null,P.MN]},"sink",{func:"aR",void:true,args:[null,P.MN]},"inputEvent","otherZone","runGuarded","bucket","each","ifAbsent","cell","objects","orElse","k","elements","offset","comp","key1","key2",{func:"Q5",ret:J.kn,args:[P.jp]},{func:"ES",args:[J.O,P.a]},"leadingSurrogate","nextCodeUnit","codeUnits","matched",{func:"jK",ret:J.im,args:[J.O]},{func:"Zh",ret:J.GW,args:[J.O]},"factor","quotient","pathSegments","base","reference","windows","segment","ch",{func:"cd",ret:J.kn,args:[J.im]},"digit",{func:"Dt",ret:J.im,args:[J.im]},"part",{func:"wJ",ret:J.im,args:[null,null]},"byteString",{func:"BC",ret:J.im,args:[J.im,J.im]},"byte","buffer",{func:"YI",void:true,args:[P.a]},"title","xhr","header","prevValue","selector","stream",L.DP,{func:"JA",ret:L.DP},{func:"Qs",args:[L.DP]},E.tuj,F.Vct,A.D13,N.WZq,{func:"Xb",args:[P.Z0,J.im]},{func:"hN",ret:J.O,args:[J.kn]},"newSpace",K.pva,"response",H.Tp,"st",{func:"iR",args:[J.im,null]},Z.cda,Z.uL,J.im,J.Q,{func:"cH",ret:J.im},{func:"r5",ret:J.Q},{func:"mR",args:[J.Q]},{func:"ub",void:true,args:[L.bv,J.im,P.Z0]},"totalSamples",{func:"F9",void:true,args:[L.bv]},{func:"Jh",ret:J.O,args:[L.kx,J.kn]},"inclusive",{func:"Nu",ret:J.O,args:[L.kx]},X.waa,"profile",L.bv,{func:"Wy",ret:L.bv},{func:"Gt",args:[L.bv]},D.V0,Z.V4,M.V6,"logLevel","rec",{func:"IM",args:[N.HV]},{func:"cr",ret:[J.Q,P.Z0]},[J.Q,J.O],{func:"he",ret:[J.Q,J.O]},{func:"ZD",args:[[J.Q,J.O]]},"link",F.V10,L.dZ,L.R2,L.pt,"label","row",[P.Z0,J.O,L.rj],[J.Q,L.kx],[P.Z0,J.O,J.GW],{func:"Jm",ret:L.CM},{func:"Ve",args:[L.CM]},"address","coverages","trace","timer",[P.Z0,J.O,L.bv],"E",{func:"AU",ret:P.iD},{func:"Y4",args:[P.iD]},"scriptURL",{func:"jN",ret:J.O,args:[J.O,J.O]},"isolateId",{func:"fP",ret:J.GW},{func:"mV",args:[J.GW]},[J.Q,L.DP],"instructionList","dartCode","kind","otherCode","profileCode","tick",{func:"Ce",args:[L.N8]},{func:"VL",args:[L.kx,L.kx]},[J.Q,L.c2],{func:"dt",ret:P.cX},"lineNumber","hits",{func:"D8",args:[[J.Q,P.Z0]]},"responseString","requestString",{func:"Tz",void:true,args:[null,null]},V.V11,{func:"AG",void:true,args:[J.O,J.O,J.O]},{func:"ru",ret:L.mL},{func:"pu",args:[L.mL]},{func:"nxg",ret:J.O,args:[J.GW]},"time","bytes",{func:"kX",ret:J.O,args:[P.Z0]},"frame",Z.LP,{func:"Aa",args:[P.e4,P.JB]},{func:"TB",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"jc",ret:J.kn,args:[P.a]},{func:"Gm",args:[[J.Q,G.DA]]},{func:"mRV",args:[[J.Q,T.z2]]},"part1","part2","part3","part4","part5","part6","part7","part8","superDecl","delegates","matcher","scopeDescriptor","cssText","properties","onName","eventType","declaration","elementElement","root",{func:"qk",void:true,args:[J.O,J.O]},"preventCascade",{func:"KT",void:true,args:[[P.cX,T.z2]]},"changes","events",{func:"WW",void:true,args:[W.ea]},"callbackOrMethod","pair","p",{func:"YT",void:true,args:[[J.Q,T.z2]]},"d","def",{func:"Zu",args:[J.O,null,null]},"arg0",{func:"pp",ret:U.zX,args:[U.hw,U.hw]},"h","item","precedence","prefix",3,{func:"Nt",args:[U.hw]},L.rj,{func:"YE",ret:L.rj},{func:"PF",args:[L.rj]},{func:"Yg",ret:J.O,args:[L.c2]},U.V12,"coverage",Q.Ds,K.V13,X.V14,"y","instanceRef",{func:"en",ret:J.O,args:[P.a]},{func:"IK",ret:J.O,args:[[J.Q,P.a]]},"values","instanceNodes",{func:"K7",void:true,args:[[J.Q,G.DA]]},];$=null
+init.metadata=[P.a,C.WP,C.nz,C.xC,C.io,C.wW,"object","interceptor","proto","extension","indexability","type","name","codeUnit","isolate","function","entry","sender","e","msg","message","x","record","value","memberName",{func:"pL",args:[J.O]},"string","source","radix","handleError","array","codePoints","charCodes","years","month","day","hours","minutes","seconds","milliseconds","isUtc","receiver","key","positionalArguments","namedArguments","className","argument","index","ex","expression","keyValuePairs","result","closure","numberOfArguments","arg1","arg2","arg3","arg4","arity","functions","reflectionInfo","isStatic","jsArguments","propertyName","isIntercepted","fieldName","property","staticName","list","returnType","parameterTypes","optionalParameterTypes","rti","typeArguments","target","typeInfo","substitutionName",,"onTypeVariable","types","startIndex","substitution","arguments","isField","checks","asField","s","t","signature","context","contextName","o","allowShorter","obj","tag","interceptorClass","transformer","hooks","pattern","multiLine","caseSensitive","global","needle","haystack","other","from","to",{func:"kl",void:true},{func:"NT"},"iterable","f","initialValue","combine","leftDelimiter","rightDelimiter","start","end","skipCount","src","srcStart","dst","dstStart","count","a","element","endIndex","left","right","compare","symbol",{func:"pB",ret:P.vr,args:[P.a]},"reflectee","mangledName","methods","variables","mixinNames","code","typeVariables","owner","simpleName","victim","fieldSpecification","jsMangledNames","isGlobal","map","errorHandler","zone","listeners","callback","notificationHandler",{func:"G5",void:true,args:[null]},{func:"Vx",void:true,args:[null],opt:[P.MN]},"error","stackTrace","userCode","onSuccess","onError","subscription","future","duration",{func:"cX",void:true,args:[P.JB,P.e4,P.JB,null,P.MN]},"self","parent",{func:"aD",args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"wD",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]},null]},"arg",{func:"ta",args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]},null,null]},{func:"HQ",ret:{func:"NT"},args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"v7",ret:{func:"Dv",args:[null]},args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"IU",ret:{func:"bh",args:[null,null]},args:[P.JB,P.e4,P.JB,{func:"bh",args:[null,null]}]},{func:"iV",void:true,args:[P.JB,P.e4,P.JB,{func:"NT"}]},{func:"zo",ret:P.lO,args:[P.JB,P.e4,P.JB,P.a6,{func:"kl",void:true}]},{func:"Zb",void:true,args:[P.JB,P.e4,P.JB,J.O]},"line",{func:"xM",void:true,args:[J.O]},{func:"Nf",ret:P.JB,args:[P.JB,P.e4,P.JB,P.aY,[P.Z0,P.wv,null]]},"specification","zoneValues","table",{func:"Ib",ret:J.kn,args:[null,null]},"b",{func:"Re",ret:J.im,args:[null]},"parts","m","number","json","reviver",{func:"uJ",ret:P.a,args:[null]},"toEncodable","sb",{func:"xh",ret:J.im,args:[P.fR,P.fR]},"formattedString",{func:"E0",ret:J.kn,args:[P.a,P.a]},{func:"DZ",ret:J.im,args:[P.a]},{func:"K4",ret:J.im,args:[J.O],named:{onError:{func:"Tl",ret:J.im,args:[J.O]},radix:J.im}},"host","scheme","query","queryParameters","fragment","component","val","val1","val2",C.xM,!1,"canonicalTable","text","encoding","spaceToPlus",{func:"Tf",ret:J.O,args:[W.D0]},"typeExtension","url","onProgress","withCredentials","method","mimeType","requestHeaders","responseType","sendData","thing","win","constructor",{func:"Dv",args:[null]},{func:"jn",args:[null,null,null,null]},"oldValue","newValue","document","extendsTagName","w","captureThis","data","createProxy","mustCopy","total","_","id","members",{func:"qE",ret:J.O,args:[J.im,J.im]},"pad","current","currentStart","currentEnd","old","oldStart","oldEnd","distances","arr1","arr2","searchLength","splices","records","field","cls","props","getter","template","extendee","sheet","node","path","originalPrepareBinding","methodName","args","style","scope","doc","baseUri","seen","scripts","uriString","currentValue","v","expr","l","hash",{func:"qq",ret:[P.cX,K.Ae],args:[P.cX]},"classMirror","c","delegate","model","bound","stagingDocument","el","useRoot","content","bindings","n","elementId","deep","selectors","relativeSelectors","listener","useCapture","async","password","user","timestamp","canBubble","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","attributeFilter","attributeOldValue","attributes","characterData","characterDataOldValue","childList","subtree","otherNode","newChild","refChild","oldChild","targetOrigin","messagePorts","length","invocation","collection","","separator",0,!0,"growable","fractionDigits","str","authentification","resume","portId","port","dataEvent","info",{func:"bh",args:[null,null]},"parameter","jsConstructor",{func:"Za",args:[J.O,null]},{func:"TS",args:[null,J.O]},"g",P.Z0,L.mL,[P.Z0,J.O,W.cv],{func:"qo",ret:P.Z0},C.nJ,C.Us,{func:"Hw",args:[P.Z0]},B.Vf,J.kn,L.bv,Q.xI,Z.pv,L.kx,{func:"bR",ret:L.kx},{func:"VI",args:[L.kx]},{func:"I0",ret:J.O},F.Vfx,J.O,C.mI,{func:"Uf",ret:J.kn},{func:"zk",args:[J.kn]},"r",{func:"Np",void:true,args:[W.ea,null,W.KV]},R.Dsd,"action","test","library",{func:"h0",args:[H.Uz]},{func:"rm",args:[P.wv,P.ej]},"reflectiveName","useEval",{func:"lv",args:[P.wv,null]},"typeArgument","tv","methodOwner","fieldOwner","i",{func:"qe",ret:P.Ms,args:[J.im]},{func:"Z5",args:[J.im]},{func:"K6",ret:P.X9,args:[J.im]},{func:"Pt",ret:J.O,args:[J.im]},{func:"ag",args:[J.O,J.O]},"eventId",{func:"uu",void:true,args:[P.a],opt:[P.MN]},{func:"YP",void:true,opt:[null]},{func:"BG",args:[null],opt:[null]},"ignored","convert","isMatch","cancelOnError","handleData","handleDone","resumeSignal","event","wasInputPaused","onData","onDone","dispatch",{func:"ha",args:[null,P.MN]},"sink",{func:"aR",void:true,args:[null,P.MN]},"inputEvent","otherZone","runGuarded","bucket","each","ifAbsent","cell","objects","orElse","k","elements","offset","comp","key1","key2",{func:"Q5",ret:J.kn,args:[P.jp]},{func:"dc",args:[J.O,P.a]},"leadingSurrogate","nextCodeUnit","matched",{func:"Tl",ret:J.im,args:[J.O]},{func:"Zh",ret:J.GW,args:[J.O]},"factor","quotient","pathSegments","base","reference","ss","ch",{func:"cd",ret:J.kn,args:[J.im]},"digit",{func:"Dt",ret:J.im,args:[J.im]},"part",{func:"wJ",ret:J.im,args:[null,null]},"byteString",{func:"BC",ret:J.im,args:[J.im,J.im]},"byte","buffer",{func:"YI",void:true,args:[P.a]},"title","xhr","header","shouldAdd","prevValue","selector","stream","pos",L.DP,{func:"JA",ret:L.DP},{func:"Qs",args:[L.DP]},E.tuj,F.Vct,A.D13,N.WZq,{func:"Xb",args:[P.Z0,J.im]},{func:"hN",ret:J.O,args:[J.kn]},"newSpace",K.pva,"response",H.Tp,"st",{func:"iR",args:[J.im,null]},{func:"ZT",void:true,args:[null,null,null]},B.T5,"trace",Z.cda,Z.uL,J.im,[J.Q,L.Y2],[J.Q,J.O],"codeCaller",{func:"UO",args:[L.Vi]},J.Q,L.XN,{func:"cH",ret:J.im},{func:"r5",ret:J.Q},{func:"mR",args:[J.Q]},{func:"ub",void:true,args:[L.bv,J.im,P.Z0]},"totalSamples",{func:"F9",void:true,args:[L.bv]},{func:"bN",ret:J.O,args:[L.Y2]},"row",{func:"Sz",void:true,args:[W.ea,null,W.cv]},X.waa,"profile",{func:"Wy",ret:L.bv},{func:"Gt",args:[L.bv]},D.V0,Z.V4,M.V10,"logLevel","rec",{func:"IM",args:[N.HV]},{func:"cr",ret:[J.Q,P.Z0]},{func:"he",ret:[J.Q,J.O]},{func:"ZD",args:[[J.Q,J.O]]},{func:"zs",ret:J.O,args:[J.O]},"link",F.V11,L.dZ,L.Nu,L.yU,"label",[P.Z0,J.O,L.rj],[J.Q,L.kx],[P.Z0,J.O,J.GW],{func:"Ik",ret:L.CM},{func:"Ve",args:[L.CM]},"address","coverages","timer",[P.Z0,J.O,L.bv],"E",{func:"EU",ret:P.iD},{func:"Y4",args:[P.iD]},"scriptURL",{func:"jN",ret:J.O,args:[J.O,J.O]},"isolateId",{func:"fP",ret:J.GW},{func:"mV",args:[J.GW]},[J.Q,L.DP],"calls","codes","instructionList","profileCode",{func:"VL",args:[L.kx,L.kx]},[J.Q,L.c2],{func:"dt",ret:P.cX},"lineNumber","hits",{func:"D8",args:[[J.Q,P.Z0]]},"responseString","requestString",{func:"Tz",void:true,args:[null,null]},"children","rowIndex",V.V12,{func:"AG",void:true,args:[J.O,J.O,J.O]},{func:"ru",ret:L.mL},{func:"pu",args:[L.mL]},{func:"nx",ret:J.O,args:[J.GW]},"time","bytes",{func:"kX",ret:J.O,args:[P.Z0]},"frame",{func:"h6",ret:J.kn,args:[J.O]},Z.LP,{func:"Aa",args:[P.e4,P.JB]},{func:"TB",args:[P.JB,P.e4,P.JB,{func:"Dv",args:[null]}]},{func:"S5",ret:J.kn,args:[P.a]},{func:"na",args:[[J.Q,G.DA]]},{func:"mRV",args:[[J.Q,T.z2]]},"superDecl","delegates","matcher","scopeDescriptor","cssText","properties","onName","eventType","declaration","elementElement","root",{func:"qk",void:true,args:[J.O,J.O]},"preventCascade",{func:"KT",void:true,args:[[P.cX,T.z2]]},"changes","events",{func:"WW",void:true,args:[W.ea]},"callbackOrMethod","pair","p",{func:"YT",void:true,args:[[J.Q,T.z2]]},"d","def",{func:"Zu",args:[J.O,null,null]},"arg0",{func:"pp",ret:U.zX,args:[U.hw,U.hw]},"h","item","kind","precedence","prefix",3,{func:"Nt",args:[U.hw]},A.qe,L.rj,{func:"LW",ret:L.rj},{func:"PF",args:[L.rj]},{func:"Yg",ret:J.O,args:[L.c2]},U.V13,"coverage",Q.Ds,K.V14,X.V15,"y","instanceRef",{func:"en",ret:J.O,args:[P.a]},{func:"IK",ret:J.O,args:[[J.Q,P.a]]},"values","instanceNodes",{func:"K7",void:true,args:[[J.Q,G.DA]]},];$=null
 I = I.$finishIsolateConstructor(I)
 $=new I()
 function convertToFastObject(properties) {
@@ -23952,10 +24308,17 @@
 X = convertToFastObject(X)
 Y = convertToFastObject(Y)
 Z = convertToFastObject(Z)
-!function(){var z=Object.prototype
-for(var y=0;;y++){var x="___dart_dispatch_record_ZxYxX_0_"
-if(y>0)x=rootProperty+"_"+y
-if(!(x in z))return init.dispatchPropertyName=x}}()
+!function(){function intern(a){var v={}
+v[a]=1
+return Object.keys(convertToFastObject(v))[0]}init.getIsolateTag=function(a){return intern("___dart_"+a+init.isolateTag)}
+var z="___dart_isolate_tags_"
+var y=Object[z]||(Object[z]=Object.create(null))
+var x="_ZxYxX"
+for(var w=0;;w++){property=intern(x+"_"+w+"_")
+if(!(property in y)){y[property]=1
+init.isolateTag=property
+break}}}()
+init.dispatchPropertyName=init.getIsolateTag("dispatch_record")
 ;(function (callback) {
   if (typeof document === "undefined") {
     callback(null);
@@ -23980,9 +24343,9 @@
   init.currentScript = currentScript;
 
   if (typeof dartMainRunner === "function") {
-    dartMainRunner(function() { H.oT(E.Im()); });
+    dartMainRunner(function() { H.oT(E.Pc()); });
   } else {
-    H.oT(E.Im());
+    H.oT(E.Pc());
   }
 })
 function init(){I.p={}
@@ -24040,7 +24403,7 @@
 if(typeof dart_precompiled=="function"){var v=dart_precompiled(a)}else{var u="function $reflectable(fn){fn.$reflectable=1;return fn};\n"+"var $desc;\n"
 var t=[]}for(var s in a){if(w.call(a,s)){var r=a[s]
 if(r instanceof Array)r=r[1]
-var q=r[""],p,o=s,n=q
+var q=r["^"],p,o=s,n=q
 if(typeof q=="object"&&q instanceof Array){q=n=q[0]}if(typeof q=="string"){var m=q.split("/")
 if(m.length==2){o=m[0]
 n=m[1]}}var l=n.split(";")
@@ -24126,20 +24489,20 @@
 Gh.prototype.gcC=function(receiver){return receiver.hash}
 Gh.prototype.scC=function(receiver,v){return receiver.hash=v}
 Gh.prototype.gmH=function(receiver){return receiver.href}
-function rK(){}rK.builtin$cls="rK"
-if(!"name" in rK)rK.name="rK"
-$desc=$collectedClasses.rK
+function A0(){}A0.builtin$cls="A0"
+if(!"name" in A0)A0.name="A0"
+$desc=$collectedClasses.A0
 if($desc instanceof Array)$desc=$desc[1]
-rK.prototype=$desc
-function fY(){}fY.builtin$cls="fY"
-if(!"name" in fY)fY.name="fY"
-$desc=$collectedClasses.fY
+A0.prototype=$desc
+function na(){}na.builtin$cls="na"
+if(!"name" in na)na.name="na"
+$desc=$collectedClasses.na
 if($desc instanceof Array)$desc=$desc[1]
-fY.prototype=$desc
-fY.prototype.gN=function(receiver){return receiver.target}
-fY.prototype.gcC=function(receiver){return receiver.hash}
-fY.prototype.scC=function(receiver,v){return receiver.hash=v}
-fY.prototype.gmH=function(receiver){return receiver.href}
+na.prototype=$desc
+na.prototype.gN=function(receiver){return receiver.target}
+na.prototype.gcC=function(receiver){return receiver.hash}
+na.prototype.scC=function(receiver,v){return receiver.hash=v}
+na.prototype.gmH=function(receiver){return receiver.href}
 function Mr(){}Mr.builtin$cls="Mr"
 if(!"name" in Mr)Mr.name="Mr"
 $desc=$collectedClasses.Mr
@@ -24168,11 +24531,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 W2.prototype=$desc
 W2.prototype.gO3=function(receiver){return receiver.url}
-function zJ(){}zJ.builtin$cls="zJ"
-if(!"name" in zJ)zJ.name="zJ"
-$desc=$collectedClasses.zJ
+function it(){}it.builtin$cls="it"
+if(!"name" in it)it.name="it"
+$desc=$collectedClasses.it
 if($desc instanceof Array)$desc=$desc[1]
-zJ.prototype=$desc
+it.prototype=$desc
 function Az(){}Az.builtin$cls="Az"
 if(!"name" in Az)Az.name="Az"
 $desc=$collectedClasses.Az
@@ -24196,23 +24559,23 @@
 QW.prototype.st5=function(receiver,v){return receiver.type=v}
 QW.prototype.gP=function(receiver){return receiver.value}
 QW.prototype.sP=function(receiver,v){return receiver.value=v}
-function n6(){}n6.builtin$cls="n6"
-if(!"name" in n6)n6.name="n6"
-$desc=$collectedClasses.n6
+function jr(){}jr.builtin$cls="jr"
+if(!"name" in jr)jr.name="jr"
+$desc=$collectedClasses.jr
 if($desc instanceof Array)$desc=$desc[1]
-n6.prototype=$desc
-function Nu(){}Nu.builtin$cls="Nu"
-if(!"name" in Nu)Nu.name="Nu"
-$desc=$collectedClasses.Nu
+jr.prototype=$desc
+function Ny(){}Ny.builtin$cls="Ny"
+if(!"name" in Ny)Ny.name="Ny"
+$desc=$collectedClasses.Ny
 if($desc instanceof Array)$desc=$desc[1]
-Nu.prototype=$desc
-function OM(){}OM.builtin$cls="OM"
-if(!"name" in OM)OM.name="OM"
-$desc=$collectedClasses.OM
+Ny.prototype=$desc
+function nx(){}nx.builtin$cls="nx"
+if(!"name" in nx)nx.name="nx"
+$desc=$collectedClasses.nx
 if($desc instanceof Array)$desc=$desc[1]
-OM.prototype=$desc
-OM.prototype.gRn=function(receiver){return receiver.data}
-OM.prototype.gB=function(receiver){return receiver.length}
+nx.prototype=$desc
+nx.prototype.gRn=function(receiver){return receiver.data}
+nx.prototype.gB=function(receiver){return receiver.length}
 function QQ(){}QQ.builtin$cls="QQ"
 if(!"name" in QQ)QQ.name="QQ"
 $desc=$collectedClasses.QQ
@@ -24224,44 +24587,38 @@
 $desc=$collectedClasses.BR
 if($desc instanceof Array)$desc=$desc[1]
 BR.prototype=$desc
-function wT(){}wT.builtin$cls="wT"
-if(!"name" in wT)wT.name="wT"
-$desc=$collectedClasses.wT
+function di(){}di.builtin$cls="di"
+if(!"name" in di)di.name="di"
+$desc=$collectedClasses.di
 if($desc instanceof Array)$desc=$desc[1]
-wT.prototype=$desc
-wT.prototype.gRn=function(receiver){return receiver.data}
+di.prototype=$desc
+di.prototype.gRn=function(receiver){return receiver.data}
 function d7(){}d7.builtin$cls="d7"
 if(!"name" in d7)d7.name="d7"
 $desc=$collectedClasses.d7
 if($desc instanceof Array)$desc=$desc[1]
 d7.prototype=$desc
-function na(){}na.builtin$cls="na"
-if(!"name" in na)na.name="na"
-$desc=$collectedClasses.na
+function yJ(){}yJ.builtin$cls="yJ"
+if(!"name" in yJ)yJ.name="yJ"
+$desc=$collectedClasses.yJ
 if($desc instanceof Array)$desc=$desc[1]
-na.prototype=$desc
-function oJ(){}oJ.builtin$cls="oJ"
-if(!"name" in oJ)oJ.name="oJ"
-$desc=$collectedClasses.oJ
+yJ.prototype=$desc
+function He(){}He.builtin$cls="He"
+if(!"name" in He)He.name="He"
+$desc=$collectedClasses.He
 if($desc instanceof Array)$desc=$desc[1]
-oJ.prototype=$desc
-oJ.prototype.gB=function(receiver){return receiver.length}
-function DG(){}DG.builtin$cls="DG"
-if(!"name" in DG)DG.name="DG"
-$desc=$collectedClasses.DG
-if($desc instanceof Array)$desc=$desc[1]
-DG.prototype=$desc
+He.prototype=$desc
 function vz(){}vz.builtin$cls="vz"
 if(!"name" in vz)vz.name="vz"
 $desc=$collectedClasses.vz
 if($desc instanceof Array)$desc=$desc[1]
 vz.prototype=$desc
-function bY(){}bY.builtin$cls="bY"
-if(!"name" in bY)bY.name="bY"
-$desc=$collectedClasses.bY
+function vHT(){}vHT.builtin$cls="vHT"
+if(!"name" in vHT)vHT.name="vHT"
+$desc=$collectedClasses.vHT
 if($desc instanceof Array)$desc=$desc[1]
-bY.prototype=$desc
-bY.prototype.gbG=function(receiver){return receiver.options}
+vHT.prototype=$desc
+vHT.prototype.gbG=function(receiver){return receiver.options}
 function n0(){}n0.builtin$cls="n0"
 if(!"name" in n0)n0.name="n0"
 $desc=$collectedClasses.n0
@@ -24272,11 +24629,11 @@
 $desc=$collectedClasses.Em
 if($desc instanceof Array)$desc=$desc[1]
 Em.prototype=$desc
-function rD(){}rD.builtin$cls="rD"
-if(!"name" in rD)rD.name="rD"
-$desc=$collectedClasses.rD
+function pt(){}pt.builtin$cls="pt"
+if(!"name" in pt)pt.name="pt"
+$desc=$collectedClasses.pt
 if($desc instanceof Array)$desc=$desc[1]
-rD.prototype=$desc
+pt.prototype=$desc
 function rV(){}rV.builtin$cls="rV"
 if(!"name" in rV)rV.name="rV"
 $desc=$collectedClasses.rV
@@ -24292,34 +24649,29 @@
 $desc=$collectedClasses.QF
 if($desc instanceof Array)$desc=$desc[1]
 QF.prototype=$desc
-function hN(){}hN.builtin$cls="hN"
-if(!"name" in hN)hN.name="hN"
-$desc=$collectedClasses.hN
+function Aj(){}Aj.builtin$cls="Aj"
+if(!"name" in Aj)Aj.name="Aj"
+$desc=$collectedClasses.Aj
 if($desc instanceof Array)$desc=$desc[1]
-hN.prototype=$desc
-function SL(){}SL.builtin$cls="SL"
-if(!"name" in SL)SL.name="SL"
-$desc=$collectedClasses.SL
+Aj.prototype=$desc
+function cm(){}cm.builtin$cls="cm"
+if(!"name" in cm)cm.name="cm"
+$desc=$collectedClasses.cm
 if($desc instanceof Array)$desc=$desc[1]
-SL.prototype=$desc
-function rv(){}rv.builtin$cls="rv"
-if(!"name" in rv)rv.name="rv"
-$desc=$collectedClasses.rv
-if($desc instanceof Array)$desc=$desc[1]
-rv.prototype=$desc
-rv.prototype.gG1=function(receiver){return receiver.message}
-rv.prototype.goc=function(receiver){return receiver.name}
+cm.prototype=$desc
+cm.prototype.gG1=function(receiver){return receiver.message}
+cm.prototype.goc=function(receiver){return receiver.name}
 function Nh(){}Nh.builtin$cls="Nh"
 if(!"name" in Nh)Nh.name="Nh"
 $desc=$collectedClasses.Nh
 if($desc instanceof Array)$desc=$desc[1]
 Nh.prototype=$desc
 Nh.prototype.gG1=function(receiver){return receiver.message}
-function ac(){}ac.builtin$cls="ac"
-if(!"name" in ac)ac.name="ac"
-$desc=$collectedClasses.ac
+function wj(){}wj.builtin$cls="wj"
+if(!"name" in wj)wj.name="wj"
+$desc=$collectedClasses.wj
 if($desc instanceof Array)$desc=$desc[1]
-ac.prototype=$desc
+wj.prototype=$desc
 function cv(){}cv.builtin$cls="cv"
 if(!"name" in cv)cv.name="cv"
 $desc=$collectedClasses.cv
@@ -24374,27 +24726,27 @@
 if($desc instanceof Array)$desc=$desc[1]
 hH.prototype=$desc
 hH.prototype.goc=function(receiver){return receiver.name}
-function QU(){}QU.builtin$cls="QU"
-if(!"name" in QU)QU.name="QU"
-$desc=$collectedClasses.QU
+function Aa(){}Aa.builtin$cls="Aa"
+if(!"name" in Aa)Aa.name="Aa"
+$desc=$collectedClasses.Aa
 if($desc instanceof Array)$desc=$desc[1]
-QU.prototype=$desc
-QU.prototype.gtT=function(receiver){return receiver.code}
+Aa.prototype=$desc
+Aa.prototype.gtT=function(receiver){return receiver.code}
 function u5(){}u5.builtin$cls="u5"
 if(!"name" in u5)u5.name="u5"
 $desc=$collectedClasses.u5
 if($desc instanceof Array)$desc=$desc[1]
 u5.prototype=$desc
-function Yu(){}Yu.builtin$cls="Yu"
-if(!"name" in Yu)Yu.name="Yu"
-$desc=$collectedClasses.Yu
+function h4(){}h4.builtin$cls="h4"
+if(!"name" in h4)h4.name="h4"
+$desc=$collectedClasses.h4
 if($desc instanceof Array)$desc=$desc[1]
-Yu.prototype=$desc
-Yu.prototype.gB=function(receiver){return receiver.length}
-Yu.prototype.gbP=function(receiver){return receiver.method}
-Yu.prototype.goc=function(receiver){return receiver.name}
-Yu.prototype.soc=function(receiver,v){return receiver.name=v}
-Yu.prototype.gN=function(receiver){return receiver.target}
+h4.prototype=$desc
+h4.prototype.gB=function(receiver){return receiver.length}
+h4.prototype.gbP=function(receiver){return receiver.method}
+h4.prototype.goc=function(receiver){return receiver.name}
+h4.prototype.soc=function(receiver,v){return receiver.name=v}
+h4.prototype.gN=function(receiver){return receiver.target}
 function W4(){}W4.builtin$cls="W4"
 if(!"name" in W4)W4.name="W4"
 $desc=$collectedClasses.W4
@@ -24405,21 +24757,21 @@
 $desc=$collectedClasses.jP
 if($desc instanceof Array)$desc=$desc[1]
 jP.prototype=$desc
-function Cz(){}Cz.builtin$cls="Cz"
-if(!"name" in Cz)Cz.name="Cz"
-$desc=$collectedClasses.Cz
+function Hd(){}Hd.builtin$cls="Hd"
+if(!"name" in Hd)Hd.name="Hd"
+$desc=$collectedClasses.Hd
 if($desc instanceof Array)$desc=$desc[1]
-Cz.prototype=$desc
+Hd.prototype=$desc
 function tA(){}tA.builtin$cls="tA"
 if(!"name" in tA)tA.name="tA"
 $desc=$collectedClasses.tA
 if($desc instanceof Array)$desc=$desc[1]
 tA.prototype=$desc
-function Cv(){}Cv.builtin$cls="Cv"
-if(!"name" in Cv)Cv.name="Cv"
-$desc=$collectedClasses.Cv
+function wa(){}wa.builtin$cls="wa"
+if(!"name" in wa)wa.name="wa"
+$desc=$collectedClasses.wa
 if($desc instanceof Array)$desc=$desc[1]
-Cv.prototype=$desc
+wa.prototype=$desc
 function Uq(){}Uq.builtin$cls="Uq"
 if(!"name" in Uq)Uq.name="Uq"
 $desc=$collectedClasses.Uq
@@ -24430,11 +24782,11 @@
 $desc=$collectedClasses.QH
 if($desc instanceof Array)$desc=$desc[1]
 QH.prototype=$desc
-function So(){}So.builtin$cls="So"
-if(!"name" in So)So.name="So"
-$desc=$collectedClasses.So
+function Rt(){}Rt.builtin$cls="Rt"
+if(!"name" in Rt)Rt.name="Rt"
+$desc=$collectedClasses.Rt
 if($desc instanceof Array)$desc=$desc[1]
-So.prototype=$desc
+Rt.prototype=$desc
 function X2(){}X2.builtin$cls="X2"
 if(!"name" in X2)X2.name="X2"
 $desc=$collectedClasses.X2
@@ -24448,11 +24800,11 @@
 zU.prototype.giC=function(receiver){return receiver.responseText}
 zU.prototype.gys=function(receiver){return receiver.status}
 zU.prototype.gpo=function(receiver){return receiver.statusText}
-function wa(){}wa.builtin$cls="wa"
-if(!"name" in wa)wa.name="wa"
-$desc=$collectedClasses.wa
+function pk(){}pk.builtin$cls="pk"
+if(!"name" in pk)pk.name="pk"
+$desc=$collectedClasses.pk
 if($desc instanceof Array)$desc=$desc[1]
-wa.prototype=$desc
+pk.prototype=$desc
 function tX(){}tX.builtin$cls="tX"
 if(!"name" in tX)tX.name="tX"
 $desc=$collectedClasses.tX
@@ -24494,15 +24846,15 @@
 $desc=$collectedClasses.Gt
 if($desc instanceof Array)$desc=$desc[1]
 Gt.prototype=$desc
-function ttH(){}ttH.builtin$cls="ttH"
-if(!"name" in ttH)ttH.name="ttH"
-$desc=$collectedClasses.ttH
+function In(){}In.builtin$cls="In"
+if(!"name" in In)In.name="In"
+$desc=$collectedClasses.In
 if($desc instanceof Array)$desc=$desc[1]
-ttH.prototype=$desc
-ttH.prototype.gMB=function(receiver){return receiver.form}
-ttH.prototype.goc=function(receiver){return receiver.name}
-ttH.prototype.soc=function(receiver,v){return receiver.name=v}
-ttH.prototype.gt5=function(receiver){return receiver.type}
+In.prototype=$desc
+In.prototype.gMB=function(receiver){return receiver.form}
+In.prototype.goc=function(receiver){return receiver.name}
+In.prototype.soc=function(receiver,v){return receiver.name=v}
+In.prototype.gt5=function(receiver){return receiver.type}
 function wP(){}wP.builtin$cls="wP"
 if(!"name" in wP)wP.name="wP"
 $desc=$collectedClasses.wP
@@ -24538,13 +24890,13 @@
 cS.prototype.gcC=function(receiver){return receiver.hash}
 cS.prototype.scC=function(receiver,v){return receiver.hash=v}
 cS.prototype.gmH=function(receiver){return receiver.href}
-function M6(){}M6.builtin$cls="M6"
-if(!"name" in M6)M6.name="M6"
-$desc=$collectedClasses.M6
+function YI(){}YI.builtin$cls="YI"
+if(!"name" in YI)YI.name="YI"
+$desc=$collectedClasses.YI
 if($desc instanceof Array)$desc=$desc[1]
-M6.prototype=$desc
-M6.prototype.goc=function(receiver){return receiver.name}
-M6.prototype.soc=function(receiver,v){return receiver.name=v}
+YI.prototype=$desc
+YI.prototype.goc=function(receiver){return receiver.name}
+YI.prototype.soc=function(receiver,v){return receiver.name=v}
 function El(){}El.builtin$cls="El"
 if(!"name" in El)El.name="El"
 $desc=$collectedClasses.El
@@ -24592,11 +24944,11 @@
 $desc=$collectedClasses.HO
 if($desc instanceof Array)$desc=$desc[1]
 HO.prototype=$desc
-function rC(){}rC.builtin$cls="rC"
-if(!"name" in rC)rC.name="rC"
-$desc=$collectedClasses.rC
+function Kk(){}Kk.builtin$cls="Kk"
+if(!"name" in Kk)Kk.name="Kk"
+$desc=$collectedClasses.Kk
 if($desc instanceof Array)$desc=$desc[1]
-rC.prototype=$desc
+Kk.prototype=$desc
 function ZY(){}ZY.builtin$cls="ZY"
 if(!"name" in ZY)ZY.name="ZY"
 $desc=$collectedClasses.ZY
@@ -24607,14 +24959,14 @@
 $desc=$collectedClasses.DD
 if($desc instanceof Array)$desc=$desc[1]
 DD.prototype=$desc
-function la(){}la.builtin$cls="la"
-if(!"name" in la)la.name="la"
-$desc=$collectedClasses.la
+function EeC(){}EeC.builtin$cls="EeC"
+if(!"name" in EeC)EeC.name="EeC"
+$desc=$collectedClasses.EeC
 if($desc instanceof Array)$desc=$desc[1]
-la.prototype=$desc
-la.prototype.gjb=function(receiver){return receiver.content}
-la.prototype.goc=function(receiver){return receiver.name}
-la.prototype.soc=function(receiver,v){return receiver.name=v}
+EeC.prototype=$desc
+EeC.prototype.gjb=function(receiver){return receiver.content}
+EeC.prototype.goc=function(receiver){return receiver.name}
+EeC.prototype.soc=function(receiver,v){return receiver.name=v}
 function Qb(){}Qb.builtin$cls="Qb"
 if(!"name" in Qb)Qb.name="Qb"
 $desc=$collectedClasses.Qb
@@ -24643,24 +24995,24 @@
 $desc=$collectedClasses.bn
 if($desc instanceof Array)$desc=$desc[1]
 bn.prototype=$desc
-function tH(){}tH.builtin$cls="tH"
-if(!"name" in tH)tH.name="tH"
-$desc=$collectedClasses.tH
+function Imr(){}Imr.builtin$cls="Imr"
+if(!"name" in Imr)Imr.name="Imr"
+$desc=$collectedClasses.Imr
 if($desc instanceof Array)$desc=$desc[1]
-tH.prototype=$desc
-tH.prototype.gjO=function(receiver){return receiver.id}
-tH.prototype.goc=function(receiver){return receiver.name}
-tH.prototype.gt5=function(receiver){return receiver.type}
-function oB(){}oB.builtin$cls="oB"
-if(!"name" in oB)oB.name="oB"
-$desc=$collectedClasses.oB
+Imr.prototype=$desc
+Imr.prototype.gjO=function(receiver){return receiver.id}
+Imr.prototype.goc=function(receiver){return receiver.name}
+Imr.prototype.gt5=function(receiver){return receiver.type}
+function Ve(){}Ve.builtin$cls="Ve"
+if(!"name" in Ve)Ve.name="Ve"
+$desc=$collectedClasses.Ve
 if($desc instanceof Array)$desc=$desc[1]
-oB.prototype=$desc
-function Aj(){}Aj.builtin$cls="Aj"
-if(!"name" in Aj)Aj.name="Aj"
-$desc=$collectedClasses.Aj
+Ve.prototype=$desc
+function Oq(){}Oq.builtin$cls="Oq"
+if(!"name" in Oq)Oq.name="Oq"
+$desc=$collectedClasses.Oq
 if($desc instanceof Array)$desc=$desc[1]
-Aj.prototype=$desc
+Oq.prototype=$desc
 function H9(){}H9.builtin$cls="H9"
 if(!"name" in H9)H9.name="H9"
 $desc=$collectedClasses.H9
@@ -24686,18 +25038,18 @@
 ih.prototype=$desc
 ih.prototype.gG1=function(receiver){return receiver.message}
 ih.prototype.goc=function(receiver){return receiver.name}
-function uH(){}uH.builtin$cls="uH"
-if(!"name" in uH)uH.name="uH"
-$desc=$collectedClasses.uH
+function KV(){}KV.builtin$cls="KV"
+if(!"name" in KV)KV.name="KV"
+$desc=$collectedClasses.KV
 if($desc instanceof Array)$desc=$desc[1]
-uH.prototype=$desc
-uH.prototype.gq6=function(receiver){return receiver.firstChild}
-uH.prototype.guD=function(receiver){return receiver.nextSibling}
-uH.prototype.gM0=function(receiver){return receiver.ownerDocument}
-uH.prototype.geT=function(receiver){return receiver.parentElement}
-uH.prototype.gKV=function(receiver){return receiver.parentNode}
-uH.prototype.ga4=function(receiver){return receiver.textContent}
-uH.prototype.sa4=function(receiver,v){return receiver.textContent=v}
+KV.prototype=$desc
+KV.prototype.gq6=function(receiver){return receiver.firstChild}
+KV.prototype.guD=function(receiver){return receiver.nextSibling}
+KV.prototype.gM0=function(receiver){return receiver.ownerDocument}
+KV.prototype.geT=function(receiver){return receiver.parentElement}
+KV.prototype.gKV=function(receiver){return receiver.parentNode}
+KV.prototype.ga4=function(receiver){return receiver.textContent}
+KV.prototype.sa4=function(receiver,v){return receiver.textContent=v}
 function yk(){}yk.builtin$cls="yk"
 if(!"name" in yk)yk.name="yk"
 $desc=$collectedClasses.yk
@@ -24756,11 +25108,11 @@
 $desc=$collectedClasses.FH
 if($desc instanceof Array)$desc=$desc[1]
 FH.prototype=$desc
-function SN(){}SN.builtin$cls="SN"
-if(!"name" in SN)SN.name="SN"
-$desc=$collectedClasses.SN
+function iL(){}iL.builtin$cls="iL"
+if(!"name" in iL)iL.name="iL"
+$desc=$collectedClasses.iL
 if($desc instanceof Array)$desc=$desc[1]
-SN.prototype=$desc
+iL.prototype=$desc
 function HD(){}HD.builtin$cls="HD"
 if(!"name" in HD)HD.name="HD"
 $desc=$collectedClasses.HD
@@ -24859,11 +25211,11 @@
 lp.prototype.gt5=function(receiver){return receiver.type}
 lp.prototype.gP=function(receiver){return receiver.value}
 lp.prototype.sP=function(receiver,v){return receiver.value=v}
-function kd(){}kd.builtin$cls="kd"
-if(!"name" in kd)kd.name="kd"
-$desc=$collectedClasses.kd
+function pD(){}pD.builtin$cls="pD"
+if(!"name" in pD)pD.name="pD"
+$desc=$collectedClasses.pD
 if($desc instanceof Array)$desc=$desc[1]
-kd.prototype=$desc
+pD.prototype=$desc
 function I0(){}I0.builtin$cls="I0"
 if(!"name" in I0)I0.name="I0"
 $desc=$collectedClasses.I0
@@ -24888,13 +25240,13 @@
 $desc=$collectedClasses.Ta
 if($desc instanceof Array)$desc=$desc[1]
 Ta.prototype=$desc
-function Hd(){}Hd.builtin$cls="Hd"
-if(!"name" in Hd)Hd.name="Hd"
-$desc=$collectedClasses.Hd
+function zD9(){}zD9.builtin$cls="zD9"
+if(!"name" in zD9)zD9.name="zD9"
+$desc=$collectedClasses.zD9
 if($desc instanceof Array)$desc=$desc[1]
-Hd.prototype=$desc
-Hd.prototype.gkc=function(receiver){return receiver.error}
-Hd.prototype.gG1=function(receiver){return receiver.message}
+zD9.prototype=$desc
+zD9.prototype.gkc=function(receiver){return receiver.error}
+zD9.prototype.gG1=function(receiver){return receiver.message}
 function Ul(){}Ul.builtin$cls="Ul"
 if(!"name" in Ul)Ul.name="Ul"
 $desc=$collectedClasses.Ul
@@ -24906,15 +25258,15 @@
 if($desc instanceof Array)$desc=$desc[1]
 G5.prototype=$desc
 G5.prototype.goc=function(receiver){return receiver.name}
-function wb(){}wb.builtin$cls="wb"
-if(!"name" in wb)wb.name="wb"
-$desc=$collectedClasses.wb
+function bk(){}bk.builtin$cls="bk"
+if(!"name" in bk)bk.name="bk"
+$desc=$collectedClasses.bk
 if($desc instanceof Array)$desc=$desc[1]
-wb.prototype=$desc
-wb.prototype.gG3=function(receiver){return receiver.key}
-wb.prototype.gzZ=function(receiver){return receiver.newValue}
-wb.prototype.gjL=function(receiver){return receiver.oldValue}
-wb.prototype.gO3=function(receiver){return receiver.url}
+bk.prototype=$desc
+bk.prototype.gG3=function(receiver){return receiver.key}
+bk.prototype.gzZ=function(receiver){return receiver.newValue}
+bk.prototype.gjL=function(receiver){return receiver.oldValue}
+bk.prototype.gO3=function(receiver){return receiver.url}
 function fq(){}fq.builtin$cls="fq"
 if(!"name" in fq)fq.name="fq"
 $desc=$collectedClasses.fq
@@ -24922,11 +25274,11 @@
 fq.prototype=$desc
 fq.prototype.gt5=function(receiver){return receiver.type}
 fq.prototype.st5=function(receiver,v){return receiver.type=v}
-function h4(){}h4.builtin$cls="h4"
-if(!"name" in h4)h4.name="h4"
-$desc=$collectedClasses.h4
+function Er(){}Er.builtin$cls="Er"
+if(!"name" in Er)Er.name="Er"
+$desc=$collectedClasses.Er
 if($desc instanceof Array)$desc=$desc[1]
-h4.prototype=$desc
+Er.prototype=$desc
 function qk(){}qk.builtin$cls="qk"
 if(!"name" in qk)qk.name="qk"
 $desc=$collectedClasses.qk
@@ -24971,6 +25323,8 @@
 AE.prototype.gMB=function(receiver){return receiver.form}
 AE.prototype.goc=function(receiver){return receiver.name}
 AE.prototype.soc=function(receiver,v){return receiver.name=v}
+AE.prototype.gWT=function(receiver){return receiver.rows}
+AE.prototype.sWT=function(receiver,v){return receiver.rows=v}
 AE.prototype.gt5=function(receiver){return receiver.type}
 AE.prototype.gP=function(receiver){return receiver.value}
 AE.prototype.sP=function(receiver,v){return receiver.value=v}
@@ -24998,11 +25352,11 @@
 RH.prototype.gfY=function(receiver){return receiver.kind}
 RH.prototype.sfY=function(receiver,v){return receiver.kind=v}
 RH.prototype.gLA=function(receiver){return receiver.src}
-function pU(){}pU.builtin$cls="pU"
-if(!"name" in pU)pU.name="pU"
-$desc=$collectedClasses.pU
+function ho(){}ho.builtin$cls="ho"
+if(!"name" in ho)ho.name="ho"
+$desc=$collectedClasses.ho
 if($desc instanceof Array)$desc=$desc[1]
-pU.prototype=$desc
+ho.prototype=$desc
 function OJ(){}OJ.builtin$cls="OJ"
 if(!"name" in OJ)OJ.name="OJ"
 $desc=$collectedClasses.OJ
@@ -25018,11 +25372,11 @@
 $desc=$collectedClasses.dp
 if($desc instanceof Array)$desc=$desc[1]
 dp.prototype=$desc
-function r4(){}r4.builtin$cls="r4"
-if(!"name" in r4)r4.name="r4"
-$desc=$collectedClasses.r4
+function vw(){}vw.builtin$cls="vw"
+if(!"name" in vw)vw.name="vw"
+$desc=$collectedClasses.vw
 if($desc instanceof Array)$desc=$desc[1]
-r4.prototype=$desc
+vw.prototype=$desc
 function aG(){}aG.builtin$cls="aG"
 if(!"name" in aG)aG.name="aG"
 $desc=$collectedClasses.aG
@@ -25049,21 +25403,21 @@
 Bn.prototype.goc=function(receiver){return receiver.name}
 Bn.prototype.gP=function(receiver){return receiver.value}
 Bn.prototype.sP=function(receiver,v){return receiver.value=v}
+function hq(){}hq.builtin$cls="hq"
+if(!"name" in hq)hq.name="hq"
+$desc=$collectedClasses.hq
+if($desc instanceof Array)$desc=$desc[1]
+hq.prototype=$desc
 function UL(){}UL.builtin$cls="UL"
 if(!"name" in UL)UL.name="UL"
 $desc=$collectedClasses.UL
 if($desc instanceof Array)$desc=$desc[1]
 UL.prototype=$desc
-function rq(){}rq.builtin$cls="rq"
-if(!"name" in rq)rq.name="rq"
-$desc=$collectedClasses.rq
+function tZ(){}tZ.builtin$cls="tZ"
+if(!"name" in tZ)tZ.name="tZ"
+$desc=$collectedClasses.tZ
 if($desc instanceof Array)$desc=$desc[1]
-rq.prototype=$desc
-function I1(){}I1.builtin$cls="I1"
-if(!"name" in I1)I1.name="I1"
-$desc=$collectedClasses.I1
-if($desc instanceof Array)$desc=$desc[1]
-I1.prototype=$desc
+tZ.prototype=$desc
 function kc(){}kc.builtin$cls="kc"
 if(!"name" in kc)kc.name="kc"
 $desc=$collectedClasses.kc
@@ -25074,11 +25428,11 @@
 $desc=$collectedClasses.AK
 if($desc instanceof Array)$desc=$desc[1]
 AK.prototype=$desc
-function dM(){}dM.builtin$cls="dM"
-if(!"name" in dM)dM.name="dM"
-$desc=$collectedClasses.dM
+function ty(){}ty.builtin$cls="ty"
+if(!"name" in ty)ty.name="ty"
+$desc=$collectedClasses.ty
 if($desc instanceof Array)$desc=$desc[1]
-dM.prototype=$desc
+ty.prototype=$desc
 function Nf(){}Nf.builtin$cls="Nf"
 if(!"name" in Nf)Nf.name="Nf"
 $desc=$collectedClasses.Nf
@@ -25114,11 +25468,11 @@
 $desc=$collectedClasses.hF
 if($desc instanceof Array)$desc=$desc[1]
 hF.prototype=$desc
-function hr(){}hr.builtin$cls="hr"
-if(!"name" in hr)hr.name="hr"
-$desc=$collectedClasses.hr
+function OF(){}OF.builtin$cls="OF"
+if(!"name" in OF)OF.name="OF"
+$desc=$collectedClasses.OF
 if($desc instanceof Array)$desc=$desc[1]
-hr.prototype=$desc
+OF.prototype=$desc
 function Dh(){}Dh.builtin$cls="Dh"
 if(!"name" in Dh)Dh.name="Dh"
 $desc=$collectedClasses.Dh
@@ -25142,11 +25496,11 @@
 $desc=$collectedClasses.NE
 if($desc instanceof Array)$desc=$desc[1]
 NE.prototype=$desc
-function Fl(){}Fl.builtin$cls="Fl"
-if(!"name" in Fl)Fl.name="Fl"
-$desc=$collectedClasses.Fl
+function lC(){}lC.builtin$cls="lC"
+if(!"name" in lC)lC.name="lC"
+$desc=$collectedClasses.lC
 if($desc instanceof Array)$desc=$desc[1]
-Fl.prototype=$desc
+lC.prototype=$desc
 function y5(){}y5.builtin$cls="y5"
 if(!"name" in y5)y5.name="y5"
 $desc=$collectedClasses.y5
@@ -25167,11 +25521,11 @@
 $desc=$collectedClasses.ui
 if($desc instanceof Array)$desc=$desc[1]
 ui.prototype=$desc
-function vO(){}vO.builtin$cls="vO"
-if(!"name" in vO)vO.name="vO"
-$desc=$collectedClasses.vO
+function mk(){}mk.builtin$cls="mk"
+if(!"name" in mk)mk.name="mk"
+$desc=$collectedClasses.mk
 if($desc instanceof Array)$desc=$desc[1]
-vO.prototype=$desc
+mk.prototype=$desc
 function DQ(){}DQ.builtin$cls="DQ"
 if(!"name" in DQ)DQ.name="DQ"
 $desc=$collectedClasses.DQ
@@ -25220,21 +25574,21 @@
 $desc=$collectedClasses.W1
 if($desc instanceof Array)$desc=$desc[1]
 W1.prototype=$desc
-function HC(){}HC.builtin$cls="HC"
-if(!"name" in HC)HC.name="HC"
-$desc=$collectedClasses.HC
+function mCz(){}mCz.builtin$cls="mCz"
+if(!"name" in mCz)mCz.name="mCz"
+$desc=$collectedClasses.mCz
 if($desc instanceof Array)$desc=$desc[1]
-HC.prototype=$desc
+mCz.prototype=$desc
 function kK(){}kK.builtin$cls="kK"
 if(!"name" in kK)kK.name="kK"
 $desc=$collectedClasses.kK
 if($desc instanceof Array)$desc=$desc[1]
 kK.prototype=$desc
-function hq(){}hq.builtin$cls="hq"
-if(!"name" in hq)hq.name="hq"
-$desc=$collectedClasses.hq
+function n5(){}n5.builtin$cls="n5"
+if(!"name" in n5)n5.name="n5"
+$desc=$collectedClasses.n5
 if($desc instanceof Array)$desc=$desc[1]
-hq.prototype=$desc
+n5.prototype=$desc
 function bb(){}bb.builtin$cls="bb"
 if(!"name" in bb)bb.name="bb"
 $desc=$collectedClasses.bb
@@ -25271,11 +25625,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 me.prototype=$desc
 me.prototype.gmH=function(receiver){return receiver.href}
-function bO(){}bO.builtin$cls="bO"
-if(!"name" in bO)bO.name="bO"
-$desc=$collectedClasses.bO
+function oB(){}oB.builtin$cls="oB"
+if(!"name" in oB)oB.name="oB"
+$desc=$collectedClasses.oB
 if($desc instanceof Array)$desc=$desc[1]
-bO.prototype=$desc
+oB.prototype=$desc
 function nh(){}nh.builtin$cls="nh"
 if(!"name" in nh)nh.name="nh"
 $desc=$collectedClasses.nh
@@ -25297,11 +25651,11 @@
 $desc=$collectedClasses.ca
 if($desc instanceof Array)$desc=$desc[1]
 ca.prototype=$desc
-function zt(){}zt.builtin$cls="zt"
-if(!"name" in zt)zt.name="zt"
-$desc=$collectedClasses.zt
+function um(){}um.builtin$cls="um"
+if(!"name" in um)um.name="um"
+$desc=$collectedClasses.um
 if($desc instanceof Array)$desc=$desc[1]
-zt.prototype=$desc
+um.prototype=$desc
 function eW(){}eW.builtin$cls="eW"
 if(!"name" in eW)eW.name="eW"
 $desc=$collectedClasses.eW
@@ -25318,12 +25672,12 @@
 if($desc instanceof Array)$desc=$desc[1]
 Fu.prototype=$desc
 Fu.prototype.gt5=function(receiver){return receiver.type}
-function OE(){}OE.builtin$cls="OE"
-if(!"name" in OE)OE.name="OE"
-$desc=$collectedClasses.OE
+function QN(){}QN.builtin$cls="QN"
+if(!"name" in QN)QN.name="QN"
+$desc=$collectedClasses.QN
 if($desc instanceof Array)$desc=$desc[1]
-OE.prototype=$desc
-OE.prototype.gmH=function(receiver){return receiver.href}
+QN.prototype=$desc
+QN.prototype.gmH=function(receiver){return receiver.href}
 function N9(){}N9.builtin$cls="N9"
 if(!"name" in N9)N9.name="N9"
 $desc=$collectedClasses.N9
@@ -25334,6 +25688,11 @@
 $desc=$collectedClasses.BA
 if($desc instanceof Array)$desc=$desc[1]
 BA.prototype=$desc
+function d0(){}d0.builtin$cls="d0"
+if(!"name" in d0)d0.name="d0"
+$desc=$collectedClasses.d0
+if($desc instanceof Array)$desc=$desc[1]
+d0.prototype=$desc
 function zp(){}zp.builtin$cls="zp"
 if(!"name" in zp)zp.name="zp"
 $desc=$collectedClasses.zp
@@ -25350,11 +25709,11 @@
 $desc=$collectedClasses.PIw
 if($desc instanceof Array)$desc=$desc[1]
 PIw.prototype=$desc
-function PQ(){}PQ.builtin$cls="PQ"
-if(!"name" in PQ)PQ.name="PQ"
-$desc=$collectedClasses.PQ
+function vd(){}vd.builtin$cls="vd"
+if(!"name" in vd)vd.name="vd"
+$desc=$collectedClasses.vd
 if($desc instanceof Array)$desc=$desc[1]
-PQ.prototype=$desc
+vd.prototype=$desc
 function Jq(){}Jq.builtin$cls="Jq"
 if(!"name" in Jq)Jq.name="Jq"
 $desc=$collectedClasses.Jq
@@ -25391,11 +25750,11 @@
 $desc=$collectedClasses.GH
 if($desc instanceof Array)$desc=$desc[1]
 GH.prototype=$desc
-function Lx(){}Lx.builtin$cls="Lx"
-if(!"name" in Lx)Lx.name="Lx"
-$desc=$collectedClasses.Lx
+function lo(){}lo.builtin$cls="lo"
+if(!"name" in lo)lo.name="lo"
+$desc=$collectedClasses.lo
 if($desc instanceof Array)$desc=$desc[1]
-Lx.prototype=$desc
+lo.prototype=$desc
 function NJ(){}NJ.builtin$cls="NJ"
 if(!"name" in NJ)NJ.name="NJ"
 $desc=$collectedClasses.NJ
@@ -25419,23 +25778,23 @@
 $desc=$collectedClasses.rQ
 if($desc instanceof Array)$desc=$desc[1]
 rQ.prototype=$desc
-function Lu(){}Lu.builtin$cls="Lu"
-if(!"name" in Lu)Lu.name="Lu"
-$desc=$collectedClasses.Lu
+function Lx(){}Lx.builtin$cls="Lx"
+if(!"name" in Lx)Lx.name="Lx"
+$desc=$collectedClasses.Lx
 if($desc instanceof Array)$desc=$desc[1]
-Lu.prototype=$desc
-Lu.prototype.gt5=function(receiver){return receiver.type}
-Lu.prototype.st5=function(receiver,v){return receiver.type=v}
+Lx.prototype=$desc
+Lx.prototype.gt5=function(receiver){return receiver.type}
+Lx.prototype.st5=function(receiver,v){return receiver.type=v}
 function LR(){}LR.builtin$cls="LR"
 if(!"name" in LR)LR.name="LR"
 $desc=$collectedClasses.LR
 if($desc instanceof Array)$desc=$desc[1]
 LR.prototype=$desc
-function GN(){}GN.builtin$cls="GN"
-if(!"name" in GN)GN.name="GN"
-$desc=$collectedClasses.GN
+function d5(){}d5.builtin$cls="d5"
+if(!"name" in d5)d5.name="d5"
+$desc=$collectedClasses.d5
 if($desc instanceof Array)$desc=$desc[1]
-GN.prototype=$desc
+d5.prototype=$desc
 function hy(){}hy.builtin$cls="hy"
 if(!"name" in hy)hy.name="hy"
 $desc=$collectedClasses.hy
@@ -25494,11 +25853,11 @@
 $desc=$collectedClasses.ZD
 if($desc instanceof Array)$desc=$desc[1]
 ZD.prototype=$desc
-function Rlr(){}Rlr.builtin$cls="Rlr"
-if(!"name" in Rlr)Rlr.name="Rlr"
-$desc=$collectedClasses.Rlr
+function rD(){}rD.builtin$cls="rD"
+if(!"name" in rD)rD.name="rD"
+$desc=$collectedClasses.rD
 if($desc instanceof Array)$desc=$desc[1]
-Rlr.prototype=$desc
+rD.prototype=$desc
 function wD(){}wD.builtin$cls="wD"
 if(!"name" in wD)wD.name="wD"
 $desc=$collectedClasses.wD
@@ -25520,26 +25879,26 @@
 $desc=$collectedClasses.Fi
 if($desc instanceof Array)$desc=$desc[1]
 Fi.prototype=$desc
-function Qr(){}Qr.builtin$cls="Qr"
-if(!"name" in Qr)Qr.name="Qr"
-$desc=$collectedClasses.Qr
+function Ja(){}Ja.builtin$cls="Ja"
+if(!"name" in Ja)Ja.name="Ja"
+$desc=$collectedClasses.Ja
 if($desc instanceof Array)$desc=$desc[1]
-Qr.prototype=$desc
-function zI(){}zI.builtin$cls="zI"
-if(!"name" in zI)zI.name="zI"
-$desc=$collectedClasses.zI
+Ja.prototype=$desc
+function mj(){}mj.builtin$cls="mj"
+if(!"name" in mj)mj.name="mj"
+$desc=$collectedClasses.mj
 if($desc instanceof Array)$desc=$desc[1]
-zI.prototype=$desc
+mj.prototype=$desc
 function cB(){}cB.builtin$cls="cB"
 if(!"name" in cB)cB.name="cB"
 $desc=$collectedClasses.cB
 if($desc instanceof Array)$desc=$desc[1]
 cB.prototype=$desc
-function uY(){}uY.builtin$cls="uY"
-if(!"name" in uY)uY.name="uY"
-$desc=$collectedClasses.uY
+function Mh(){}Mh.builtin$cls="Mh"
+if(!"name" in Mh)Mh.name="Mh"
+$desc=$collectedClasses.Mh
 if($desc instanceof Array)$desc=$desc[1]
-uY.prototype=$desc
+Mh.prototype=$desc
 function yR(){}yR.builtin$cls="yR"
 if(!"name" in yR)yR.name="yR"
 $desc=$collectedClasses.yR
@@ -25555,11 +25914,11 @@
 $desc=$collectedClasses.xJ
 if($desc instanceof Array)$desc=$desc[1]
 xJ.prototype=$desc
-function oI(){}oI.builtin$cls="oI"
-if(!"name" in oI)oI.name="oI"
-$desc=$collectedClasses.oI
+function Nn(){}Nn.builtin$cls="Nn"
+if(!"name" in Nn)Nn.name="Nn"
+$desc=$collectedClasses.Nn
 if($desc instanceof Array)$desc=$desc[1]
-oI.prototype=$desc
+Nn.prototype=$desc
 function Et(){}Et.builtin$cls="Et"
 if(!"name" in Et)Et.name="Et"
 $desc=$collectedClasses.Et
@@ -25585,11 +25944,11 @@
 $desc=$collectedClasses.xt
 if($desc instanceof Array)$desc=$desc[1]
 xt.prototype=$desc
-function tG(){}tG.builtin$cls="tG"
-if(!"name" in tG)tG.name="tG"
-$desc=$collectedClasses.tG
+function wx(){}wx.builtin$cls="wx"
+if(!"name" in wx)wx.name="wx"
+$desc=$collectedClasses.wx
 if($desc instanceof Array)$desc=$desc[1]
-tG.prototype=$desc
+wx.prototype=$desc
 function P0(){}P0.builtin$cls="P0"
 if(!"name" in P0)P0.name="P0"
 $desc=$collectedClasses.P0
@@ -25617,66 +25976,66 @@
 TM.prototype=$desc
 TM.prototype.gtT=function(receiver){return receiver.code}
 TM.prototype.gG1=function(receiver){return receiver.message}
-function I2(){}I2.builtin$cls="I2"
-if(!"name" in I2)I2.name="I2"
-$desc=$collectedClasses.I2
+function WZ(){}WZ.builtin$cls="WZ"
+if(!"name" in WZ)WZ.name="WZ"
+$desc=$collectedClasses.WZ
 if($desc instanceof Array)$desc=$desc[1]
-I2.prototype=$desc
-function HY(){}HY.builtin$cls="HY"
-if(!"name" in HY)HY.name="HY"
-$desc=$collectedClasses.HY
+WZ.prototype=$desc
+function rn(){}rn.builtin$cls="rn"
+if(!"name" in rn)rn.name="rn"
+$desc=$collectedClasses.rn
 if($desc instanceof Array)$desc=$desc[1]
-HY.prototype=$desc
-function Kq(){}Kq.builtin$cls="Kq"
-if(!"name" in Kq)Kq.name="Kq"
-$desc=$collectedClasses.Kq
+rn.prototype=$desc
+function df(){}df.builtin$cls="df"
+if(!"name" in df)df.name="df"
+$desc=$collectedClasses.df
 if($desc instanceof Array)$desc=$desc[1]
-Kq.prototype=$desc
-function Nn(){}Nn.builtin$cls="Nn"
-if(!"name" in Nn)Nn.name="Nn"
-$desc=$collectedClasses.Nn
+df.prototype=$desc
+function Hg(){}Hg.builtin$cls="Hg"
+if(!"name" in Hg)Hg.name="Hg"
+$desc=$collectedClasses.Hg
 if($desc instanceof Array)$desc=$desc[1]
-Nn.prototype=$desc
-function Un(){}Un.builtin$cls="Un"
-if(!"name" in Un)Un.name="Un"
-$desc=$collectedClasses.Un
+Hg.prototype=$desc
+function L3(){}L3.builtin$cls="L3"
+if(!"name" in L3)L3.name="L3"
+$desc=$collectedClasses.L3
 if($desc instanceof Array)$desc=$desc[1]
-Un.prototype=$desc
-function rF(){}rF.builtin$cls="rF"
-if(!"name" in rF)rF.name="rF"
-$desc=$collectedClasses.rF
+L3.prototype=$desc
+function xj(){}xj.builtin$cls="xj"
+if(!"name" in xj)xj.name="xj"
+$desc=$collectedClasses.xj
 if($desc instanceof Array)$desc=$desc[1]
-rF.prototype=$desc
-function Sb(){}Sb.builtin$cls="Sb"
-if(!"name" in Sb)Sb.name="Sb"
-$desc=$collectedClasses.Sb
+xj.prototype=$desc
+function dE(){}dE.builtin$cls="dE"
+if(!"name" in dE)dE.name="dE"
+$desc=$collectedClasses.dE
 if($desc instanceof Array)$desc=$desc[1]
-Sb.prototype=$desc
-function UZ(){}UZ.builtin$cls="UZ"
-if(!"name" in UZ)UZ.name="UZ"
-$desc=$collectedClasses.UZ
+dE.prototype=$desc
+function Eb(){}Eb.builtin$cls="Eb"
+if(!"name" in Eb)Eb.name="Eb"
+$desc=$collectedClasses.Eb
 if($desc instanceof Array)$desc=$desc[1]
-UZ.prototype=$desc
-function yc(){}yc.builtin$cls="yc"
-if(!"name" in yc)yc.name="yc"
-$desc=$collectedClasses.yc
+Eb.prototype=$desc
+function dT(){}dT.builtin$cls="dT"
+if(!"name" in dT)dT.name="dT"
+$desc=$collectedClasses.dT
 if($desc instanceof Array)$desc=$desc[1]
-yc.prototype=$desc
-function Aw(){}Aw.builtin$cls="Aw"
-if(!"name" in Aw)Aw.name="Aw"
-$desc=$collectedClasses.Aw
+dT.prototype=$desc
+function N2(){}N2.builtin$cls="N2"
+if(!"name" in N2)N2.name="N2"
+$desc=$collectedClasses.N2
 if($desc instanceof Array)$desc=$desc[1]
-Aw.prototype=$desc
-function jx(){}jx.builtin$cls="jx"
-if(!"name" in jx)jx.name="jx"
-$desc=$collectedClasses.jx
+N2.prototype=$desc
+function eE(){}eE.builtin$cls="eE"
+if(!"name" in eE)eE.name="eE"
+$desc=$collectedClasses.eE
 if($desc instanceof Array)$desc=$desc[1]
-jx.prototype=$desc
-function F0(){}F0.builtin$cls="F0"
-if(!"name" in F0)F0.name="F0"
-$desc=$collectedClasses.F0
+eE.prototype=$desc
+function V6(){}V6.builtin$cls="V6"
+if(!"name" in V6)V6.name="V6"
+$desc=$collectedClasses.V6
 if($desc instanceof Array)$desc=$desc[1]
-F0.prototype=$desc
+V6.prototype=$desc
 function Lt(tT){this.tT=tT}Lt.builtin$cls="Lt"
 if(!"name" in Lt)Lt.name="Lt"
 $desc=$collectedClasses.Lt
@@ -25693,11 +26052,11 @@
 $desc=$collectedClasses.kn
 if($desc instanceof Array)$desc=$desc[1]
 kn.prototype=$desc
-function PE(){}PE.builtin$cls="PE"
-if(!"name" in PE)PE.name="PE"
-$desc=$collectedClasses.PE
+function ht(){}ht.builtin$cls="Null"
+if(!"name" in ht)ht.name="ht"
+$desc=$collectedClasses.ht
 if($desc instanceof Array)$desc=$desc[1]
-PE.prototype=$desc
+ht.prototype=$desc
 function QI(){}QI.builtin$cls="QI"
 if(!"name" in QI)QI.name="QI"
 $desc=$collectedClasses.QI
@@ -25718,11 +26077,11 @@
 $desc=$collectedClasses.Q
 if($desc instanceof Array)$desc=$desc[1]
 Q.prototype=$desc
-function NK(){}NK.builtin$cls="NK"
-if(!"name" in NK)NK.name="NK"
-$desc=$collectedClasses.NK
+function nM(){}nM.builtin$cls="nM"
+if(!"name" in nM)nM.name="nM"
+$desc=$collectedClasses.nM
 if($desc instanceof Array)$desc=$desc[1]
-NK.prototype=$desc
+nM.prototype=$desc
 function ZC(){}ZC.builtin$cls="ZC"
 if(!"name" in ZC)ZC.name="ZC"
 $desc=$collectedClasses.ZC
@@ -25768,11 +26127,6 @@
 $desc=$collectedClasses.O
 if($desc instanceof Array)$desc=$desc[1]
 O.prototype=$desc
-function Qe(iN){this.iN=iN}Qe.builtin$cls="Qe"
-if(!"name" in Qe)Qe.name="Qe"
-$desc=$collectedClasses.Qe
-if($desc instanceof Array)$desc=$desc[1]
-Qe.prototype=$desc
 function PK(a){this.a=a}PK.builtin$cls="PK"
 if(!"name" in PK)PK.name="PK"
 $desc=$collectedClasses.PK
@@ -25783,7 +26137,7 @@
 $desc=$collectedClasses.JO
 if($desc instanceof Array)$desc=$desc[1]
 JO.prototype=$desc
-function f0(Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2,my,XC,w2){this.Hg=Hg
+function f0(Hg,oL,hJ,N0,Nr,Xz,vu,EF,ji,i2,vd,XC,w2){this.Hg=Hg
 this.oL=oL
 this.hJ=hJ
 this.N0=N0
@@ -25793,7 +26147,7 @@
 this.EF=EF
 this.ji=ji
 this.i2=i2
-this.my=my
+this.vd=vd
 this.XC=XC
 this.w2=w2}f0.builtin$cls="f0"
 if(!"name" in f0)f0.name="f0"
@@ -25803,16 +26157,24 @@
 f0.prototype.gi2=function(){return this.i2}
 f0.prototype.si2=function(v){return this.i2=v}
 f0.prototype.gw2=function(){return this.w2}
-function aX(jO,Gx,fW,En){this.jO=jO
+function aX(jO,Gx,fW,En,EE,Qy,RW,C9,lJ){this.jO=jO
 this.Gx=Gx
 this.fW=fW
-this.En=En}aX.builtin$cls="aX"
+this.En=En
+this.EE=EE
+this.Qy=Qy
+this.RW=RW
+this.C9=C9
+this.lJ=lJ}aX.builtin$cls="aX"
 if(!"name" in aX)aX.name="aX"
 $desc=$collectedClasses.aX
 if($desc instanceof Array)$desc=$desc[1]
 aX.prototype=$desc
 aX.prototype.gjO=function(receiver){return this.jO}
 aX.prototype.gEn=function(){return this.En}
+aX.prototype.gEE=function(){return this.EE}
+aX.prototype.gRW=function(){return this.RW}
+aX.prototype.gC9=function(){return this.C9}
 function cC(Rk,bZ){this.Rk=Rk
 this.bZ=bZ}cC.builtin$cls="cC"
 if(!"name" in cC)cC.name="cC"
@@ -25849,11 +26211,11 @@
 $desc=$collectedClasses.jl
 if($desc instanceof Array)$desc=$desc[1]
 jl.prototype=$desc
-function Iy4(){}Iy4.builtin$cls="Iy4"
-if(!"name" in Iy4)Iy4.name="Iy4"
-$desc=$collectedClasses.Iy4
+function Iy(){}Iy.builtin$cls="Iy"
+if(!"name" in Iy)Iy.name="Iy"
+$desc=$collectedClasses.Iy
 if($desc instanceof Array)$desc=$desc[1]
-Iy4.prototype=$desc
+Iy.prototype=$desc
 function Z6(JE,Jz){this.JE=JE
 this.Jz=Jz}Z6.builtin$cls="Z6"
 if(!"name" in Z6)Z6.name="Z6"
@@ -25881,20 +26243,14 @@
 $desc=$collectedClasses.yo
 if($desc instanceof Array)$desc=$desc[1]
 yo.prototype=$desc
-yo.prototype.gng=function(){return this.ng}
+yo.prototype.gng=function(receiver){return this.ng}
 yo.prototype.gP0=function(){return this.P0}
-function Rd(vl,da){this.vl=vl
-this.da=da}Rd.builtin$cls="Rd"
-if(!"name" in Rd)Rd.name="Rd"
-$desc=$collectedClasses.Rd
+function NA(CN,il){this.CN=CN
+this.il=il}NA.builtin$cls="NA"
+if(!"name" in NA)NA.name="NA"
+$desc=$collectedClasses.NA
 if($desc instanceof Array)$desc=$desc[1]
-Rd.prototype=$desc
-function Bj(CN,il){this.CN=CN
-this.il=il}Bj.builtin$cls="Bj"
-if(!"name" in Bj)Bj.name="Bj"
-$desc=$collectedClasses.Bj
-if($desc instanceof Array)$desc=$desc[1]
-Bj.prototype=$desc
+NA.prototype=$desc
 function NO(il){this.il=il}NO.builtin$cls="NO"
 if(!"name" in NO)NO.name="NO"
 $desc=$collectedClasses.NO
@@ -25936,11 +26292,11 @@
 $desc=$collectedClasses.hz
 if($desc instanceof Array)$desc=$desc[1]
 hz.prototype=$desc
-function AP(){}AP.builtin$cls="AP"
-if(!"name" in AP)AP.name="AP"
-$desc=$collectedClasses.AP
+function iY(){}iY.builtin$cls="iY"
+if(!"name" in iY)iY.name="iY"
+$desc=$collectedClasses.iY
 if($desc instanceof Array)$desc=$desc[1]
-AP.prototype=$desc
+iY.prototype=$desc
 function yH(Kf,zu,p9){this.Kf=Kf
 this.zu=zu
 this.p9=p9}yH.builtin$cls="yH"
@@ -25960,6 +26316,12 @@
 $desc=$collectedClasses.Av
 if($desc instanceof Array)$desc=$desc[1]
 Av.prototype=$desc
+function ku(ng){this.ng=ng}ku.builtin$cls="ku"
+if(!"name" in ku)ku.name="ku"
+$desc=$collectedClasses.ku
+if($desc instanceof Array)$desc=$desc[1]
+ku.prototype=$desc
+ku.prototype.gng=function(receiver){return this.ng}
 function Zd(){}Zd.builtin$cls="Zd"
 if(!"name" in Zd)Zd.name="Zd"
 $desc=$collectedClasses.Zd
@@ -25970,18 +26332,18 @@
 $desc=$collectedClasses.xQ
 if($desc instanceof Array)$desc=$desc[1]
 xQ.prototype=$desc
-function Q9(){}Q9.builtin$cls="Q9"
-if(!"name" in Q9)Q9.name="Q9"
-$desc=$collectedClasses.Q9
+function F0(){}F0.builtin$cls="F0"
+if(!"name" in F0)F0.name="F0"
+$desc=$collectedClasses.F0
 if($desc instanceof Array)$desc=$desc[1]
-Q9.prototype=$desc
+F0.prototype=$desc
 function oH(){}oH.builtin$cls="oH"
 if(!"name" in oH)oH.name="oH"
 $desc=$collectedClasses.oH
 if($desc instanceof Array)$desc=$desc[1]
 oH.prototype=$desc
-function LPe(B,eZ,tc){this.B=B
-this.eZ=eZ
+function LPe(B,HV,tc){this.B=B
+this.HV=HV
 this.tc=tc}LPe.builtin$cls="LPe"
 if(!"name" in LPe)LPe.name="LPe"
 $desc=$collectedClasses.LPe
@@ -26020,14 +26382,18 @@
 $desc=$collectedClasses.LI
 if($desc instanceof Array)$desc=$desc[1]
 LI.prototype=$desc
-function Ny(mr,eK,Ot){this.mr=mr
+function A2(Pi,mr,eK,Ot){this.Pi=Pi
+this.mr=mr
 this.eK=eK
-this.Ot=Ot}Ny.builtin$cls="Ny"
-if(!"name" in Ny)Ny.name="Ny"
-$desc=$collectedClasses.Ny
+this.Ot=Ot}A2.builtin$cls="A2"
+if(!"name" in A2)A2.name="A2"
+$desc=$collectedClasses.A2
 if($desc instanceof Array)$desc=$desc[1]
-Ny.prototype=$desc
-function IW(qa,mr,eK,Ot){this.qa=qa
+A2.prototype=$desc
+A2.prototype.gPi=function(){return this.Pi}
+A2.prototype.geK=function(){return this.eK}
+function IW(qa,Pi,mr,eK,Ot){this.qa=qa
+this.Pi=Pi
 this.mr=mr
 this.eK=eK
 this.Ot=Ot}IW.builtin$cls="IW"
@@ -26293,7 +26659,7 @@
 $desc=$collectedClasses.tQ
 if($desc instanceof Array)$desc=$desc[1]
 tQ.prototype=$desc
-function G6(eE,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eE=eE
+function G6(BW,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.BW=BW
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26301,29 +26667,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}G6.builtin$cls="G6"
+this.X0=X0}G6.builtin$cls="G6"
 if(!"name" in G6)G6.name="G6"
 $desc=$collectedClasses.G6
 if($desc instanceof Array)$desc=$desc[1]
 G6.prototype=$desc
-G6.prototype.geE=function(receiver){return receiver.eE}
-G6.prototype.geE.$reflectable=1
-G6.prototype.seE=function(receiver,v){return receiver.eE=v}
-G6.prototype.seE.$reflectable=1
+G6.prototype.gBW=function(receiver){return receiver.BW}
+G6.prototype.gBW.$reflectable=1
+G6.prototype.sBW=function(receiver,v){return receiver.BW=v}
+G6.prototype.sBW.$reflectable=1
 function Vf(){}Vf.builtin$cls="Vf"
 if(!"name" in Vf)Vf.name="Vf"
 $desc=$collectedClasses.Vf
 if($desc instanceof Array)$desc=$desc[1]
 Vf.prototype=$desc
-function kf(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function Tg(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26331,19 +26698,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}kf.builtin$cls="kf"
-if(!"name" in kf)kf.name="kf"
-$desc=$collectedClasses.kf
+this.X0=X0}Tg.builtin$cls="Tg"
+if(!"name" in Tg)Tg.name="Tg"
+$desc=$collectedClasses.Tg
 if($desc instanceof Array)$desc=$desc[1]
-kf.prototype=$desc
-function Ps(F0,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.F0=F0
+Tg.prototype=$desc
+function Ps(F0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.F0=F0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26351,14 +26718,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Ps.builtin$cls="Ps"
+this.X0=X0}Ps.builtin$cls="Ps"
 if(!"name" in Ps)Ps.name="Ps"
 $desc=$collectedClasses.Ps
 if($desc instanceof Array)$desc=$desc[1]
@@ -26372,8 +26739,9 @@
 $desc=$collectedClasses.pv
 if($desc instanceof Array)$desc=$desc[1]
 pv.prototype=$desc
-function CN(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function CN(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26381,19 +26749,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}CN.builtin$cls="CN"
+this.X0=X0}CN.builtin$cls="CN"
 if(!"name" in CN)CN.name="CN"
 $desc=$collectedClasses.CN
 if($desc instanceof Array)$desc=$desc[1]
 CN.prototype=$desc
-function vc(eJ,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eJ=eJ
+function vc(eJ,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.eJ=eJ
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -26401,14 +26769,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}vc.builtin$cls="vc"
+this.X0=X0}vc.builtin$cls="vc"
 if(!"name" in vc)vc.name="vc"
 $desc=$collectedClasses.vc
 if($desc instanceof Array)$desc=$desc[1]
@@ -26422,7 +26790,7 @@
 $desc=$collectedClasses.Vfx
 if($desc instanceof Array)$desc=$desc[1]
 Vfx.prototype=$desc
-function i6(zh,HX,Uy,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.zh=zh
+function i6(zh,HX,Uy,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.zh=zh
 this.HX=HX
 this.Uy=Uy
 this.AP=AP
@@ -26432,14 +26800,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}i6.builtin$cls="i6"
+this.X0=X0}i6.builtin$cls="i6"
 if(!"name" in i6)i6.name="i6"
 $desc=$collectedClasses.i6
 if($desc instanceof Array)$desc=$desc[1]
@@ -26543,12 +26911,12 @@
 $desc=$collectedClasses.H6
 if($desc instanceof Array)$desc=$desc[1]
 H6.prototype=$desc
-function d5(l6,FT){this.l6=l6
-this.FT=FT}d5.builtin$cls="d5"
-if(!"name" in d5)d5.name="d5"
-$desc=$collectedClasses.d5
+function wB(l6,FT){this.l6=l6
+this.FT=FT}wB.builtin$cls="wB"
+if(!"name" in wB)wB.name="wB"
+$desc=$collectedClasses.wB
 if($desc instanceof Array)$desc=$desc[1]
-d5.prototype=$desc
+wB.prototype=$desc
 function U1(OI,FT){this.OI=OI
 this.FT=FT}U1.builtin$cls="U1"
 if(!"name" in U1)U1.name="U1"
@@ -26565,16 +26933,16 @@
 $desc=$collectedClasses.SU7
 if($desc instanceof Array)$desc=$desc[1]
 SU7.prototype=$desc
-function JJ(){}JJ.builtin$cls="JJ"
-if(!"name" in JJ)JJ.name="JJ"
-$desc=$collectedClasses.JJ
+function Qr(){}Qr.builtin$cls="Qr"
+if(!"name" in Qr)Qr.name="Qr"
+$desc=$collectedClasses.Qr
 if($desc instanceof Array)$desc=$desc[1]
-JJ.prototype=$desc
-function Iy(){}Iy.builtin$cls="Iy"
-if(!"name" in Iy)Iy.name="Iy"
-$desc=$collectedClasses.Iy
+Qr.prototype=$desc
+function w2Y(){}w2Y.builtin$cls="w2Y"
+if(!"name" in w2Y)w2Y.name="w2Y"
+$desc=$collectedClasses.w2Y
 if($desc instanceof Array)$desc=$desc[1]
-Iy.prototype=$desc
+w2Y.prototype=$desc
 function iK(CR){this.CR=CR}iK.builtin$cls="iK"
 if(!"name" in iK)iK.name="iK"
 $desc=$collectedClasses.iK
@@ -26613,12 +26981,12 @@
 $desc=$collectedClasses.mb
 if($desc instanceof Array)$desc=$desc[1]
 mb.prototype=$desc
-function mZ(If){this.If=If}mZ.builtin$cls="mZ"
-if(!"name" in mZ)mZ.name="mZ"
-$desc=$collectedClasses.mZ
+function am(If){this.If=If}am.builtin$cls="am"
+if(!"name" in am)am.name="am"
+$desc=$collectedClasses.am
 if($desc instanceof Array)$desc=$desc[1]
-mZ.prototype=$desc
-mZ.prototype.gIf=function(){return this.If}
+am.prototype=$desc
+am.prototype.gIf=function(){return this.If}
 function cw(XP,xW,Nz,LQ,If){this.XP=XP
 this.xW=xW
 this.Nz=Nz
@@ -26659,11 +27027,11 @@
 Uz.prototype.gFP=function(){return this.FP}
 Uz.prototype.gGD=function(){return this.GD}
 Uz.prototype.gae=function(){return this.ae}
-function NZ(){}NZ.builtin$cls="NZ"
-if(!"name" in NZ)NZ.name="NZ"
-$desc=$collectedClasses.NZ
+function uh(){}uh.builtin$cls="uh"
+if(!"name" in uh)uh.name="uh"
+$desc=$collectedClasses.uh
 if($desc instanceof Array)$desc=$desc[1]
-NZ.prototype=$desc
+uh.prototype=$desc
 function IB(a){this.a=a}IB.builtin$cls="IB"
 if(!"name" in IB)IB.name="IB"
 $desc=$collectedClasses.IB
@@ -26689,17 +27057,18 @@
 if($desc instanceof Array)$desc=$desc[1]
 BI.prototype=$desc
 BI.prototype.gAY=function(){return this.AY}
-function vk(){}vk.builtin$cls="vk"
-if(!"name" in vk)vk.name="vk"
-$desc=$collectedClasses.vk
+function Un(){}Un.builtin$cls="Un"
+if(!"name" in Un)Un.name="Un"
+$desc=$collectedClasses.Un
 if($desc instanceof Array)$desc=$desc[1]
-vk.prototype=$desc
+Un.prototype=$desc
 function M2(){}M2.builtin$cls="M2"
 if(!"name" in M2)M2.name="M2"
 $desc=$collectedClasses.M2
 if($desc instanceof Array)$desc=$desc[1]
 M2.prototype=$desc
-function iu(Ax){this.Ax=Ax}iu.builtin$cls="iu"
+function iu(Ax,xq){this.Ax=Ax
+this.xq=xq}iu.builtin$cls="iu"
 if(!"name" in iu)iu.name="iu"
 $desc=$collectedClasses.iu
 if($desc instanceof Array)$desc=$desc[1]
@@ -26710,7 +27079,7 @@
 $desc=$collectedClasses.mg
 if($desc instanceof Array)$desc=$desc[1]
 mg.prototype=$desc
-function bl(NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,QY,If){this.NK=NK
+function bl(NK,EZ,ut,Db,uA,b0,M2,T1,fX,FU,qu,qN,qm,eL,RH,If){this.NK=NK
 this.EZ=EZ
 this.ut=ut
 this.Db=Db
@@ -26724,7 +27093,7 @@
 this.qN=qN
 this.qm=qm
 this.eL=eL
-this.QY=QY
+this.RH=RH
 this.If=If}bl.builtin$cls="bl"
 if(!"name" in bl)bl.name="bl"
 $desc=$collectedClasses.bl
@@ -26750,7 +27119,7 @@
 $desc=$collectedClasses.Ax
 if($desc instanceof Array)$desc=$desc[1]
 Ax.prototype=$desc
-function Wf(Cr,Tx,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,QY,nz,If){this.Cr=Cr
+function Wf(Cr,Tx,H8,Ht,pz,le,qN,qu,zE,b0,FU,T1,fX,M2,uA,Db,xO,qm,UF,eL,RH,nz,If){this.Cr=Cr
 this.Tx=Tx
 this.H8=H8
 this.Ht=Ht
@@ -26770,7 +27139,7 @@
 this.qm=qm
 this.UF=UF
 this.eL=eL
-this.QY=QY
+this.RH=RH
 this.nz=nz
 this.If=If}Wf.builtin$cls="Wf"
 if(!"name" in Wf)Wf.name="Wf"
@@ -26779,11 +27148,11 @@
 Wf.prototype=$desc
 Wf.prototype.gCr=function(){return this.Cr}
 Wf.prototype.gTx=function(){return this.Tx}
-function HZT(){}HZT.builtin$cls="HZT"
-if(!"name" in HZT)HZT.name="HZT"
-$desc=$collectedClasses.HZT
+function vk(){}vk.builtin$cls="vk"
+if(!"name" in vk)vk.name="vk"
+$desc=$collectedClasses.vk
 if($desc instanceof Array)$desc=$desc[1]
-HZT.prototype=$desc
+vk.prototype=$desc
 function Ei(a){this.a=a}Ei.builtin$cls="Ei"
 if(!"name" in Ei)Ei.name="Ei"
 $desc=$collectedClasses.Ei
@@ -26815,12 +27184,13 @@
 Ld.prototype.gV5=function(){return this.V5}
 Ld.prototype.gFo=function(){return this.Fo}
 Ld.prototype.gAy=function(receiver){return this.Ay}
-function Sz(Ax){this.Ax=Ax}Sz.builtin$cls="Sz"
+function Sz(Ax,xq){this.Ax=Ax
+this.xq=xq}Sz.builtin$cls="Sz"
 if(!"name" in Sz)Sz.name="Sz"
 $desc=$collectedClasses.Sz
 if($desc instanceof Array)$desc=$desc[1]
 Sz.prototype=$desc
-function Zk(dl,Yq,lT,hB,Fo,xV,qx,nz,le,G6,H3,If){this.dl=dl
+function Zk(dl,Yq,lT,hB,Fo,xV,qx,nz,le,wM,H3,If){this.dl=dl
 this.Yq=Yq
 this.lT=lT
 this.hB=hB
@@ -26829,7 +27199,7 @@
 this.qx=qx
 this.nz=nz
 this.le=le
-this.G6=G6
+this.wM=wM
 this.H3=H3
 this.If=If}Zk.builtin$cls="Zk"
 if(!"name" in Zk)Zk.name="Zk"
@@ -26840,11 +27210,12 @@
 Zk.prototype.ghB=function(){return this.hB}
 Zk.prototype.gFo=function(){return this.Fo}
 Zk.prototype.gxV=function(){return this.xV}
-function fu(XP,Ay,Q2,Sh,BE,If){this.XP=XP
+function fu(XP,Ay,Q2,Sh,BE,QY,If){this.XP=XP
 this.Ay=Ay
 this.Q2=Q2
 this.Sh=Sh
 this.BE=BE
+this.QY=QY
 this.If=If}fu.builtin$cls="fu"
 if(!"name" in fu)fu.name="fu"
 $desc=$collectedClasses.fu
@@ -26853,6 +27224,11 @@
 fu.prototype.gXP=function(){return this.XP}
 fu.prototype.gAy=function(receiver){return this.Ay}
 fu.prototype.gQ2=function(){return this.Q2}
+function wt(){}wt.builtin$cls="wt"
+if(!"name" in wt)wt.name="wt"
+$desc=$collectedClasses.wt
+if($desc instanceof Array)$desc=$desc[1]
+wt.prototype=$desc
 function ng(Cr,CM,If){this.Cr=Cr
 this.CM=CM
 this.If=If}ng.builtin$cls="ng"
@@ -26940,16 +27316,12 @@
 JI.prototype.siE=function(v){return this.iE=v}
 JI.prototype.gSJ=function(){return this.SJ}
 JI.prototype.sSJ=function(v){return this.SJ=v}
-function Ks(nL,QC,iE,SJ){this.nL=nL
-this.QC=QC
-this.iE=iE
+function Ks(iE,SJ){this.iE=iE
 this.SJ=SJ}Ks.builtin$cls="Ks"
 if(!"name" in Ks)Ks.name="Ks"
 $desc=$collectedClasses.Ks
 if($desc instanceof Array)$desc=$desc[1]
 Ks.prototype=$desc
-Ks.prototype.gnL=function(){return this.nL}
-Ks.prototype.gQC=function(){return this.QC}
 Ks.prototype.giE=function(){return this.iE}
 Ks.prototype.siE=function(v){return this.iE=v}
 Ks.prototype.gSJ=function(){return this.SJ}
@@ -27053,45 +27425,64 @@
 $desc=$collectedClasses.ZL
 if($desc instanceof Array)$desc=$desc[1]
 ZL.prototype=$desc
-function mi(c,d){this.c=c
-this.d=d}mi.builtin$cls="mi"
-if(!"name" in mi)mi.name="mi"
-$desc=$collectedClasses.mi
+function rq(b,c,d,e){this.b=b
+this.c=c
+this.d=d
+this.e=e}rq.builtin$cls="rq"
+if(!"name" in rq)rq.name="rq"
+$desc=$collectedClasses.rq
 if($desc instanceof Array)$desc=$desc[1]
-mi.prototype=$desc
-function jb(c,b,e,f){this.c=c
+rq.prototype=$desc
+function RW(c,b,f,UI){this.c=c
 this.b=b
-this.e=e
-this.f=f}jb.builtin$cls="jb"
-if(!"name" in jb)jb.name="jb"
-$desc=$collectedClasses.jb
+this.f=f
+this.UI=UI}RW.builtin$cls="RW"
+if(!"name" in RW)RW.name="RW"
+$desc=$collectedClasses.RW
 if($desc instanceof Array)$desc=$desc[1]
-jb.prototype=$desc
-function wB(c,UI){this.c=c
-this.UI=UI}wB.builtin$cls="wB"
-if(!"name" in wB)wB.name="wB"
-$desc=$collectedClasses.wB
+RW.prototype=$desc
+function RT(c,b,bK,Gq,Rm){this.c=c
+this.b=b
+this.bK=bK
+this.Gq=Gq
+this.Rm=Rm}RT.builtin$cls="RT"
+if(!"name" in RT)RT.name="RT"
+$desc=$collectedClasses.RT
 if($desc instanceof Array)$desc=$desc[1]
-wB.prototype=$desc
-function Pu(a,bK){this.a=a
-this.bK=bK}Pu.builtin$cls="Pu"
-if(!"name" in Pu)Pu.name="Pu"
-$desc=$collectedClasses.Pu
+RT.prototype=$desc
+function jZ(c,w3){this.c=c
+this.w3=w3}jZ.builtin$cls="jZ"
+if(!"name" in jZ)jZ.name="jZ"
+$desc=$collectedClasses.jZ
 if($desc instanceof Array)$desc=$desc[1]
-Pu.prototype=$desc
+jZ.prototype=$desc
+function FZ(a,HZ){this.a=a
+this.HZ=HZ}FZ.builtin$cls="FZ"
+if(!"name" in FZ)FZ.name="FZ"
+$desc=$collectedClasses.FZ
+if($desc instanceof Array)$desc=$desc[1]
+FZ.prototype=$desc
+function OM(FR,aw){this.FR=FR
+this.aw=aw}OM.builtin$cls="OM"
+if(!"name" in OM)OM.name="OM"
+$desc=$collectedClasses.OM
+if($desc instanceof Array)$desc=$desc[1]
+OM.prototype=$desc
+OM.prototype.gaw=function(){return this.aw}
+OM.prototype.saw=function(v){return this.aw=v}
 function qh(){}qh.builtin$cls="qh"
 if(!"name" in qh)qh.name="qh"
 $desc=$collectedClasses.qh
 if($desc instanceof Array)$desc=$desc[1]
 qh.prototype=$desc
-function YJ(a,b,c,d){this.a=a
+function tG(a,b,c,d){this.a=a
 this.b=b
 this.c=c
-this.d=d}YJ.builtin$cls="YJ"
-if(!"name" in YJ)YJ.name="YJ"
-$desc=$collectedClasses.YJ
+this.d=d}tG.builtin$cls="tG"
+if(!"name" in tG)tG.name="tG"
+$desc=$collectedClasses.tG
 if($desc instanceof Array)$desc=$desc[1]
-YJ.prototype=$desc
+tG.prototype=$desc
 function jv(e,f){this.e=e
 this.f=f}jv.builtin$cls="jv"
 if(!"name" in jv)jv.name="jv"
@@ -27104,11 +27495,11 @@
 $desc=$collectedClasses.LB
 if($desc instanceof Array)$desc=$desc[1]
 LB.prototype=$desc
-function DO(bK){this.bK=bK}DO.builtin$cls="DO"
-if(!"name" in DO)DO.name="DO"
-$desc=$collectedClasses.DO
+function zn(bK){this.bK=bK}zn.builtin$cls="zn"
+if(!"name" in zn)zn.name="zn"
+$desc=$collectedClasses.zn
 if($desc instanceof Array)$desc=$desc[1]
-DO.prototype=$desc
+zn.prototype=$desc
 function lz(a,b,c,d){this.a=a
 this.b=b
 this.c=c
@@ -27234,89 +27625,17 @@
 $desc=$collectedClasses.MO
 if($desc instanceof Array)$desc=$desc[1]
 MO.prototype=$desc
-function ms(){}ms.builtin$cls="ms"
-if(!"name" in ms)ms.name="ms"
-$desc=$collectedClasses.ms
-if($desc instanceof Array)$desc=$desc[1]
-ms.prototype=$desc
-function UO(a){this.a=a}UO.builtin$cls="UO"
-if(!"name" in UO)UO.name="UO"
-$desc=$collectedClasses.UO
-if($desc instanceof Array)$desc=$desc[1]
-UO.prototype=$desc
-function Bc(a){this.a=a}Bc.builtin$cls="Bc"
-if(!"name" in Bc)Bc.name="Bc"
-$desc=$collectedClasses.Bc
-if($desc instanceof Array)$desc=$desc[1]
-Bc.prototype=$desc
-function vp(){}vp.builtin$cls="vp"
-if(!"name" in vp)vp.name="vp"
-$desc=$collectedClasses.vp
-if($desc instanceof Array)$desc=$desc[1]
-vp.prototype=$desc
-function lk(){}lk.builtin$cls="lk"
-if(!"name" in lk)lk.name="lk"
-$desc=$collectedClasses.lk
-if($desc instanceof Array)$desc=$desc[1]
-lk.prototype=$desc
-function q1(nL,p4,Z9,QC,iP,Gv,Ip){this.nL=nL
-this.p4=p4
-this.Z9=Z9
-this.QC=QC
-this.iP=iP
-this.Gv=Gv
-this.Ip=Ip}q1.builtin$cls="q1"
-if(!"name" in q1)q1.name="q1"
-$desc=$collectedClasses.q1
-if($desc instanceof Array)$desc=$desc[1]
-q1.prototype=$desc
-q1.prototype.gnL=function(){return this.nL}
-q1.prototype.gp4=function(){return this.p4}
-q1.prototype.gZ9=function(){return this.Z9}
-q1.prototype.gQC=function(){return this.QC}
-function ZzD(){}ZzD.builtin$cls="ZzD"
-if(!"name" in ZzD)ZzD.name="ZzD"
-$desc=$collectedClasses.ZzD
-if($desc instanceof Array)$desc=$desc[1]
-ZzD.prototype=$desc
-function ly(nL,p4,Z9,QC,iP,Gv,Ip){this.nL=nL
-this.p4=p4
-this.Z9=Z9
-this.QC=QC
-this.iP=iP
-this.Gv=Gv
-this.Ip=Ip}ly.builtin$cls="ly"
-if(!"name" in ly)ly.name="ly"
-$desc=$collectedClasses.ly
-if($desc instanceof Array)$desc=$desc[1]
-ly.prototype=$desc
-ly.prototype.gnL=function(){return this.nL}
-ly.prototype.gp4=function(){return this.p4}
-ly.prototype.gZ9=function(){return this.Z9}
-ly.prototype.gQC=function(){return this.QC}
-function fE(){}fE.builtin$cls="fE"
-if(!"name" in fE)fE.name="fE"
-$desc=$collectedClasses.fE
-if($desc instanceof Array)$desc=$desc[1]
-fE.prototype=$desc
-function O9(Y8){this.Y8=Y8}O9.builtin$cls="O9"
+function O9(){}O9.builtin$cls="O9"
 if(!"name" in O9)O9.name="O9"
 $desc=$collectedClasses.O9
 if($desc instanceof Array)$desc=$desc[1]
 O9.prototype=$desc
-function yU(Y8,dB,o7,Bd,Lj,Gv,lz,Ri){this.Y8=Y8
-this.dB=dB
-this.o7=o7
-this.Bd=Bd
-this.Lj=Lj
-this.Gv=Gv
-this.lz=lz
-this.Ri=Ri}yU.builtin$cls="yU"
-if(!"name" in yU)yU.name="yU"
-$desc=$collectedClasses.yU
+function oh(Y8){this.Y8=Y8}oh.builtin$cls="oh"
+if(!"name" in oh)oh.name="oh"
+$desc=$collectedClasses.oh
 if($desc instanceof Array)$desc=$desc[1]
-yU.prototype=$desc
-yU.prototype.gY8=function(){return this.Y8}
+oh.prototype=$desc
+oh.prototype.gY8=function(){return this.Y8}
 function nP(){}nP.builtin$cls="nP"
 if(!"name" in nP)nP.name="nP"
 $desc=$collectedClasses.nP
@@ -27352,23 +27671,23 @@
 $desc=$collectedClasses.ez
 if($desc instanceof Array)$desc=$desc[1]
 ez.prototype=$desc
-function lx(LD){this.LD=LD}lx.builtin$cls="lx"
+function lx(aw){this.aw=aw}lx.builtin$cls="lx"
 if(!"name" in lx)lx.name="lx"
 $desc=$collectedClasses.lx
 if($desc instanceof Array)$desc=$desc[1]
 lx.prototype=$desc
-lx.prototype.gLD=function(){return this.LD}
-lx.prototype.sLD=function(v){return this.LD=v}
-function LV(P,LD){this.P=P
-this.LD=LD}LV.builtin$cls="LV"
+lx.prototype.gaw=function(){return this.aw}
+lx.prototype.saw=function(v){return this.aw=v}
+function LV(P,aw){this.P=P
+this.aw=aw}LV.builtin$cls="LV"
 if(!"name" in LV)LV.name="LV"
 $desc=$collectedClasses.LV
 if($desc instanceof Array)$desc=$desc[1]
 LV.prototype=$desc
 LV.prototype.gP=function(receiver){return this.P}
-function DS(kc,I4,LD){this.kc=kc
+function DS(kc,I4,aw){this.kc=kc
 this.I4=I4
-this.LD=LD}DS.builtin$cls="DS"
+this.aw=aw}DS.builtin$cls="DS"
 if(!"name" in DS)DS.name="DS"
 $desc=$collectedClasses.DS
 if($desc instanceof Array)$desc=$desc[1]
@@ -27380,11 +27699,11 @@
 $desc=$collectedClasses.JF
 if($desc instanceof Array)$desc=$desc[1]
 JF.prototype=$desc
-function ht(){}ht.builtin$cls="ht"
-if(!"name" in ht)ht.name="ht"
-$desc=$collectedClasses.ht
+function Je(){}Je.builtin$cls="Je"
+if(!"name" in Je)Je.name="Je"
+$desc=$collectedClasses.Je
 if($desc instanceof Array)$desc=$desc[1]
-ht.prototype=$desc
+Je.prototype=$desc
 function CR(a,b){this.a=a
 this.b=b}CR.builtin$cls="CR"
 if(!"name" in CR)CR.name="CR"
@@ -27398,25 +27717,25 @@
 $desc=$collectedClasses.Qk
 if($desc instanceof Array)$desc=$desc[1]
 Qk.prototype=$desc
-function dR(a,b,c){this.a=a
+function v1y(a,b,c){this.a=a
 this.b=b
-this.c=c}dR.builtin$cls="dR"
-if(!"name" in dR)dR.name="dR"
-$desc=$collectedClasses.dR
+this.c=c}v1y.builtin$cls="v1y"
+if(!"name" in v1y)v1y.name="v1y"
+$desc=$collectedClasses.v1y
 if($desc instanceof Array)$desc=$desc[1]
-dR.prototype=$desc
+v1y.prototype=$desc
 function uR(a,b){this.a=a
 this.b=b}uR.builtin$cls="uR"
 if(!"name" in uR)uR.name="uR"
 $desc=$collectedClasses.uR
 if($desc instanceof Array)$desc=$desc[1]
 uR.prototype=$desc
-function QX(a,b){this.a=a
-this.b=b}QX.builtin$cls="QX"
-if(!"name" in QX)QX.name="QX"
-$desc=$collectedClasses.QX
+function Q0(a,b){this.a=a
+this.b=b}Q0.builtin$cls="Q0"
+if(!"name" in Q0)Q0.name="Q0"
+$desc=$collectedClasses.Q0
 if($desc instanceof Array)$desc=$desc[1]
-QX.prototype=$desc
+Q0.prototype=$desc
 function YR(){}YR.builtin$cls="YR"
 if(!"name" in YR)YR.name="YR"
 $desc=$collectedClasses.YR
@@ -27453,11 +27772,11 @@
 $desc=$collectedClasses.dq
 if($desc instanceof Array)$desc=$desc[1]
 dq.prototype=$desc
-function tU(){}tU.builtin$cls="tU"
-if(!"name" in tU)tU.name="tU"
-$desc=$collectedClasses.tU
+function lO(){}lO.builtin$cls="lO"
+if(!"name" in lO)lO.name="lO"
+$desc=$collectedClasses.lO
 if($desc instanceof Array)$desc=$desc[1]
-tU.prototype=$desc
+lO.prototype=$desc
 function aY(){}aY.builtin$cls="aY"
 if(!"name" in aY)aY.name="aY"
 $desc=$collectedClasses.aY
@@ -27500,7 +27819,7 @@
 $desc=$collectedClasses.JB
 if($desc instanceof Array)$desc=$desc[1]
 JB.prototype=$desc
-function Id(nU){this.nU=nU}Id.builtin$cls="Id"
+function Id(oh){this.oh=oh}Id.builtin$cls="Id"
 if(!"name" in Id)Id.name="Id"
 $desc=$collectedClasses.Id
 if($desc instanceof Array)$desc=$desc[1]
@@ -27546,15 +27865,15 @@
 $desc=$collectedClasses.pV
 if($desc instanceof Array)$desc=$desc[1]
 pV.prototype=$desc
-function cc(eT,zU,R1){this.eT=eT
+function uo(eT,zU,R1){this.eT=eT
 this.zU=zU
-this.R1=R1}cc.builtin$cls="cc"
-if(!"name" in cc)cc.name="cc"
-$desc=$collectedClasses.cc
+this.R1=R1}uo.builtin$cls="uo"
+if(!"name" in uo)uo.name="uo"
+$desc=$collectedClasses.uo
 if($desc instanceof Array)$desc=$desc[1]
-cc.prototype=$desc
-cc.prototype.geT=function(receiver){return this.eT}
-cc.prototype.gzU=function(){return this.zU}
+uo.prototype=$desc
+uo.prototype.geT=function(receiver){return this.eT}
+uo.prototype.gzU=function(){return this.zU}
 function pK(a,b){this.a=a
 this.b=b}pK.builtin$cls="pK"
 if(!"name" in pK)pK.name="pK"
@@ -27572,21 +27891,21 @@
 $desc=$collectedClasses.Uez
 if($desc instanceof Array)$desc=$desc[1]
 Uez.prototype=$desc
-function W5(){}W5.builtin$cls="W5"
-if(!"name" in W5)W5.name="W5"
-$desc=$collectedClasses.W5
+function nU(){}nU.builtin$cls="nU"
+if(!"name" in nU)nU.name="nU"
+$desc=$collectedClasses.nU
 if($desc instanceof Array)$desc=$desc[1]
-W5.prototype=$desc
+nU.prototype=$desc
 function R8(){}R8.builtin$cls="R8"
 if(!"name" in R8)R8.name="R8"
 $desc=$collectedClasses.R8
 if($desc instanceof Array)$desc=$desc[1]
 R8.prototype=$desc
-function k6(X5,vv,OX,OB,aw){this.X5=X5
+function k6(X5,vv,OX,OB,wV){this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}k6.builtin$cls="k6"
+this.wV=wV}k6.builtin$cls="k6"
 if(!"name" in k6)k6.name="k6"
 $desc=$collectedClasses.k6
 if($desc instanceof Array)$desc=$desc[1]
@@ -27607,23 +27926,23 @@
 $desc=$collectedClasses.DJ
 if($desc instanceof Array)$desc=$desc[1]
 DJ.prototype=$desc
-function PL(X5,vv,OX,OB,aw){this.X5=X5
+function PL(X5,vv,OX,OB,wV){this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}PL.builtin$cls="PL"
+this.wV=wV}PL.builtin$cls="PL"
 if(!"name" in PL)PL.name="PL"
 $desc=$collectedClasses.PL
 if($desc instanceof Array)$desc=$desc[1]
 PL.prototype=$desc
-function Fq(m6,Q6,ac,X5,vv,OX,OB,aw){this.m6=m6
+function Fq(m6,Q6,ac,X5,vv,OX,OB,wV){this.m6=m6
 this.Q6=Q6
 this.ac=ac
 this.X5=X5
 this.vv=vv
 this.OX=OX
 this.OB=OB
-this.aw=aw}Fq.builtin$cls="Fq"
+this.wV=wV}Fq.builtin$cls="Fq"
 if(!"name" in Fq)Fq.name="Fq"
 $desc=$collectedClasses.Fq
 if($desc instanceof Array)$desc=$desc[1]
@@ -27638,8 +27957,8 @@
 $desc=$collectedClasses.fG
 if($desc instanceof Array)$desc=$desc[1]
 fG.prototype=$desc
-function EQ(Fb,aw,zi,fD){this.Fb=Fb
-this.aw=aw
+function EQ(Fb,wV,zi,fD){this.Fb=Fb
+this.wV=wV
 this.zi=zi
 this.fD=fD}EQ.builtin$cls="EQ"
 if(!"name" in EQ)EQ.name="EQ"
@@ -27815,16 +28134,16 @@
 $desc=$collectedClasses.ZQ
 if($desc instanceof Array)$desc=$desc[1]
 ZQ.prototype=$desc
-function Sw(v5,av,HV,qT){this.v5=v5
+function Sw(v5,av,eZ,qT){this.v5=v5
 this.av=av
-this.HV=HV
+this.eZ=eZ
 this.qT=qT}Sw.builtin$cls="Sw"
 if(!"name" in Sw)Sw.name="Sw"
 $desc=$collectedClasses.Sw
 if($desc instanceof Array)$desc=$desc[1]
 Sw.prototype=$desc
-function o0(Lz,dP,qT,Dc,fD){this.Lz=Lz
-this.dP=dP
+function o0(Lz,pP,qT,Dc,fD){this.Lz=Lz
+this.pP=pP
 this.qT=qT
 this.Dc=Dc
 this.fD=fD}o0.builtin$cls="o0"
@@ -27840,8 +28159,8 @@
 if($desc instanceof Array)$desc=$desc[1]
 qv.prototype=$desc
 qv.prototype.gG3=function(receiver){return this.G3}
-qv.prototype.gBb=function(receiver){return this.Bb}
-qv.prototype.gT8=function(receiver){return this.T8}
+qv.prototype.gBb=function(){return this.Bb}
+qv.prototype.gT8=function(){return this.T8}
 function jp(P,G3,Bb,T8){this.P=P
 this.G3=G3
 this.Bb=Bb
@@ -27964,16 +28283,17 @@
 $desc=$collectedClasses.K8
 if($desc instanceof Array)$desc=$desc[1]
 K8.prototype=$desc
-function by(){}by.builtin$cls="by"
+function by(N5,iY){this.N5=N5
+this.iY=iY}by.builtin$cls="by"
 if(!"name" in by)by.name="by"
 $desc=$collectedClasses.by
 if($desc instanceof Array)$desc=$desc[1]
 by.prototype=$desc
-function pD(Xi){this.Xi=Xi}pD.builtin$cls="pD"
-if(!"name" in pD)pD.name="pD"
-$desc=$collectedClasses.pD
+function dI(Xi){this.Xi=Xi}dI.builtin$cls="dI"
+if(!"name" in dI)dI.name="dI"
+$desc=$collectedClasses.dI
 if($desc instanceof Array)$desc=$desc[1]
-pD.prototype=$desc
+dI.prototype=$desc
 function Cf(N5){this.N5=N5}Cf.builtin$cls="Cf"
 if(!"name" in Cf)Cf.name="Cf"
 $desc=$collectedClasses.Cf
@@ -28009,21 +28329,6 @@
 $desc=$collectedClasses.Rw
 if($desc instanceof Array)$desc=$desc[1]
 Rw.prototype=$desc
-function GY(lH){this.lH=lH}GY.builtin$cls="GY"
-if(!"name" in GY)GY.name="GY"
-$desc=$collectedClasses.GY
-if($desc instanceof Array)$desc=$desc[1]
-GY.prototype=$desc
-function jZ(lH,aS,rU,Ok,TY,VN){this.lH=lH
-this.aS=aS
-this.rU=rU
-this.Ok=Ok
-this.TY=TY
-this.VN=VN}jZ.builtin$cls="jZ"
-if(!"name" in jZ)jZ.name="jZ"
-$desc=$collectedClasses.jZ
-if($desc instanceof Array)$desc=$desc[1]
-jZ.prototype=$desc
 function HB(a){this.a=a}HB.builtin$cls="HB"
 if(!"name" in HB)HB.name="HB"
 $desc=$collectedClasses.HB
@@ -28252,24 +28557,19 @@
 $desc=$collectedClasses.uq
 if($desc instanceof Array)$desc=$desc[1]
 uq.prototype=$desc
-function iD(NN,HC,r0,Fi,iV,tP,Ka,ld,yW){this.NN=NN
+function iD(NN,HC,r0,Fi,ku,tP,Ka,YG,yW){this.NN=NN
 this.HC=HC
 this.r0=r0
 this.Fi=Fi
-this.iV=iV
+this.ku=ku
 this.tP=tP
 this.Ka=Ka
-this.ld=ld
+this.YG=YG
 this.yW=yW}iD.builtin$cls="iD"
 if(!"name" in iD)iD.name="iD"
 $desc=$collectedClasses.iD
 if($desc instanceof Array)$desc=$desc[1]
 iD.prototype=$desc
-function In(a){this.a=a}In.builtin$cls="In"
-if(!"name" in In)In.name="In"
-$desc=$collectedClasses.In
-if($desc instanceof Array)$desc=$desc[1]
-In.prototype=$desc
 function hb(){}hb.builtin$cls="hb"
 if(!"name" in hb)hb.name="hb"
 $desc=$collectedClasses.hb
@@ -28365,16 +28665,6 @@
 $desc=$collectedClasses.QZ
 if($desc instanceof Array)$desc=$desc[1]
 QZ.prototype=$desc
-function BV(){}BV.builtin$cls="BV"
-if(!"name" in BV)BV.name="BV"
-$desc=$collectedClasses.BV
-if($desc instanceof Array)$desc=$desc[1]
-BV.prototype=$desc
-function E1(){}E1.builtin$cls="E1"
-if(!"name" in E1)E1.name="E1"
-$desc=$collectedClasses.E1
-if($desc instanceof Array)$desc=$desc[1]
-E1.prototype=$desc
 function VG(MW,vG){this.MW=MW
 this.vG=vG}VG.builtin$cls="VG"
 if(!"name" in VG)VG.name="VG"
@@ -28415,11 +28705,11 @@
 $desc=$collectedClasses.RAp
 if($desc instanceof Array)$desc=$desc[1]
 RAp.prototype=$desc
-function ma(){}ma.builtin$cls="ma"
-if(!"name" in ma)ma.name="ma"
-$desc=$collectedClasses.ma
+function Gb(){}Gb.builtin$cls="Gb"
+if(!"name" in Gb)Gb.name="Gb"
+$desc=$collectedClasses.Gb
 if($desc instanceof Array)$desc=$desc[1]
-ma.prototype=$desc
+Gb.prototype=$desc
 function Kx(){}Kx.builtin$cls="Kx"
 if(!"name" in Kx)Kx.name="Kx"
 $desc=$collectedClasses.Kx
@@ -28507,6 +28797,12 @@
 $desc=$collectedClasses.vf
 if($desc instanceof Array)$desc=$desc[1]
 vf.prototype=$desc
+function Iw(a,b){this.a=a
+this.b=b}Iw.builtin$cls="Iw"
+if(!"name" in Iw)Iw.name="Iw"
+$desc=$collectedClasses.Iw
+if($desc instanceof Array)$desc=$desc[1]
+Iw.prototype=$desc
 function Fc(a){this.a=a}Fc.builtin$cls="Fc"
 if(!"name" in Fc)Fc.name="Fc"
 $desc=$collectedClasses.Fc
@@ -28589,16 +28885,26 @@
 $desc=$collectedClasses.RX
 if($desc instanceof Array)$desc=$desc[1]
 RX.prototype=$desc
-function hP(Vy){this.Vy=Vy}hP.builtin$cls="hP"
-if(!"name" in hP)hP.name="hP"
-$desc=$collectedClasses.hP
+function bO(xY){this.xY=xY}bO.builtin$cls="bO"
+if(!"name" in bO)bO.name="bO"
+$desc=$collectedClasses.bO
 if($desc instanceof Array)$desc=$desc[1]
-hP.prototype=$desc
+bO.prototype=$desc
 function Gm(){}Gm.builtin$cls="Gm"
 if(!"name" in Gm)Gm.name="Gm"
 $desc=$collectedClasses.Gm
 if($desc instanceof Array)$desc=$desc[1]
 Gm.prototype=$desc
+function Of(xa){this.xa=xa}Of.builtin$cls="Of"
+if(!"name" in Of)Of.name="Of"
+$desc=$collectedClasses.Of
+if($desc instanceof Array)$desc=$desc[1]
+Of.prototype=$desc
+function Qg(je){this.je=je}Qg.builtin$cls="Qg"
+if(!"name" in Qg)Qg.name="Qg"
+$desc=$collectedClasses.Qg
+if($desc instanceof Array)$desc=$desc[1]
+Qg.prototype=$desc
 function W9(nj,vN,Nq,QZ){this.nj=nj
 this.vN=vN
 this.Nq=Nq
@@ -28628,16 +28934,21 @@
 $desc=$collectedClasses.O7
 if($desc instanceof Array)$desc=$desc[1]
 O7.prototype=$desc
+function IU(){}IU.builtin$cls="IU"
+if(!"name" in IU)IU.name="IU"
+$desc=$collectedClasses.IU
+if($desc instanceof Array)$desc=$desc[1]
+IU.prototype=$desc
 function E4(eh){this.eh=eh}E4.builtin$cls="E4"
 if(!"name" in E4)E4.name="E4"
 $desc=$collectedClasses.E4
 if($desc instanceof Array)$desc=$desc[1]
 E4.prototype=$desc
-function Xb(a){this.a=a}Xb.builtin$cls="Xb"
-if(!"name" in Xb)Xb.name="Xb"
-$desc=$collectedClasses.Xb
+function Gn(a){this.a=a}Gn.builtin$cls="Gn"
+if(!"name" in Gn)Gn.name="Gn"
+$desc=$collectedClasses.Gn
 if($desc instanceof Array)$desc=$desc[1]
-Xb.prototype=$desc
+Gn.prototype=$desc
 function r7(eh){this.eh=eh}r7.builtin$cls="r7"
 if(!"name" in r7)r7.name="r7"
 $desc=$collectedClasses.r7
@@ -28708,11 +29019,11 @@
 $desc=$collectedClasses.Ms
 if($desc instanceof Array)$desc=$desc[1]
 Ms.prototype=$desc
-function tg(){}tg.builtin$cls="tg"
-if(!"name" in tg)tg.name="tg"
-$desc=$collectedClasses.tg
+function ac(){}ac.builtin$cls="ac"
+if(!"name" in ac)ac.name="ac"
+$desc=$collectedClasses.ac
 if($desc instanceof Array)$desc=$desc[1]
-tg.prototype=$desc
+ac.prototype=$desc
 function RS(){}RS.builtin$cls="RS"
 if(!"name" in RS)RS.name="RS"
 $desc=$collectedClasses.RS
@@ -28728,19 +29039,19 @@
 $desc=$collectedClasses.Ys
 if($desc instanceof Array)$desc=$desc[1]
 Ys.prototype=$desc
-function WS4(EE,m2,nV,V3){this.EE=EE
-this.m2=m2
+function WS4(ew,yz,nV,V3){this.ew=ew
+this.yz=yz
 this.nV=nV
 this.V3=V3}WS4.builtin$cls="WS4"
 if(!"name" in WS4)WS4.name="WS4"
 $desc=$collectedClasses.WS4
 if($desc instanceof Array)$desc=$desc[1]
 WS4.prototype=$desc
-function A2(EV){this.EV=EV}A2.builtin$cls="A2"
-if(!"name" in A2)A2.name="A2"
-$desc=$collectedClasses.A2
+function Gj(EV){this.EV=EV}Gj.builtin$cls="Gj"
+if(!"name" in Gj)Gj.name="Gj"
+$desc=$collectedClasses.Gj
 if($desc instanceof Array)$desc=$desc[1]
-A2.prototype=$desc
+Gj.prototype=$desc
 function U4(){}U4.builtin$cls="U4"
 if(!"name" in U4)U4.name="U4"
 $desc=$collectedClasses.U4
@@ -28756,42 +29067,42 @@
 $desc=$collectedClasses.Nx
 if($desc instanceof Array)$desc=$desc[1]
 Nx.prototype=$desc
-function ue(){}ue.builtin$cls="ue"
-if(!"name" in ue)ue.name="ue"
-$desc=$collectedClasses.ue
+function LZ(){}LZ.builtin$cls="LZ"
+if(!"name" in LZ)LZ.name="LZ"
+$desc=$collectedClasses.LZ
 if($desc instanceof Array)$desc=$desc[1]
-ue.prototype=$desc
-function GG(){}GG.builtin$cls="GG"
-if(!"name" in GG)GG.name="GG"
-$desc=$collectedClasses.GG
+LZ.prototype=$desc
+function Dg(){}Dg.builtin$cls="Dg"
+if(!"name" in Dg)Dg.name="Dg"
+$desc=$collectedClasses.Dg
 if($desc instanceof Array)$desc=$desc[1]
-GG.prototype=$desc
-function Y8(){}Y8.builtin$cls="Y8"
-if(!"name" in Y8)Y8.name="Y8"
-$desc=$collectedClasses.Y8
+Dg.prototype=$desc
+function Ob(){}Ob.builtin$cls="Ob"
+if(!"name" in Ob)Ob.name="Ob"
+$desc=$collectedClasses.Ob
 if($desc instanceof Array)$desc=$desc[1]
-Y8.prototype=$desc
-function Bk(){}Bk.builtin$cls="Bk"
-if(!"name" in Bk)Bk.name="Bk"
-$desc=$collectedClasses.Bk
+Ob.prototype=$desc
+function Ip(){}Ip.builtin$cls="Ip"
+if(!"name" in Ip)Ip.name="Ip"
+$desc=$collectedClasses.Ip
 if($desc instanceof Array)$desc=$desc[1]
-Bk.prototype=$desc
-function iY(){}iY.builtin$cls="iY"
-if(!"name" in iY)iY.name="iY"
-$desc=$collectedClasses.iY
+Ip.prototype=$desc
+function Pg(){}Pg.builtin$cls="Pg"
+if(!"name" in Pg)Pg.name="Pg"
+$desc=$collectedClasses.Pg
 if($desc instanceof Array)$desc=$desc[1]
-iY.prototype=$desc
-function C0A(){}C0A.builtin$cls="C0A"
-if(!"name" in C0A)C0A.name="C0A"
-$desc=$collectedClasses.C0A
+Pg.prototype=$desc
+function Nb(){}Nb.builtin$cls="Nb"
+if(!"name" in Nb)Nb.name="Nb"
+$desc=$collectedClasses.Nb
 if($desc instanceof Array)$desc=$desc[1]
-C0A.prototype=$desc
-function RAK(){}RAK.builtin$cls="RAK"
-if(!"name" in RAK)RAK.name="RAK"
-$desc=$collectedClasses.RAK
+Nb.prototype=$desc
+function nA(){}nA.builtin$cls="nA"
+if(!"name" in nA)nA.name="nA"
+$desc=$collectedClasses.nA
 if($desc instanceof Array)$desc=$desc[1]
-RAK.prototype=$desc
-function FvP(m0,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.m0=m0
+nA.prototype=$desc
+function Fv(F8,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.F8=F8
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28799,28 +29110,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}FvP.builtin$cls="FvP"
-if(!"name" in FvP)FvP.name="FvP"
-$desc=$collectedClasses.FvP
+this.X0=X0}Fv.builtin$cls="Fv"
+if(!"name" in Fv)Fv.name="Fv"
+$desc=$collectedClasses.Fv
 if($desc instanceof Array)$desc=$desc[1]
-FvP.prototype=$desc
-FvP.prototype.gm0=function(receiver){return receiver.m0}
-FvP.prototype.gm0.$reflectable=1
-FvP.prototype.sm0=function(receiver,v){return receiver.m0=v}
-FvP.prototype.sm0.$reflectable=1
+Fv.prototype=$desc
+Fv.prototype.gF8=function(receiver){return receiver.F8}
+Fv.prototype.gF8.$reflectable=1
+Fv.prototype.sF8=function(receiver,v){return receiver.F8=v}
+Fv.prototype.sF8.$reflectable=1
 function tuj(){}tuj.builtin$cls="tuj"
 if(!"name" in tuj)tuj.name="tuj"
 $desc=$collectedClasses.tuj
 if($desc instanceof Array)$desc=$desc[1]
 tuj.prototype=$desc
-function Ir(Py,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Py=Py
+function E9(Py,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Py=Py
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28828,29 +29139,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Ir.builtin$cls="Ir"
-if(!"name" in Ir)Ir.name="Ir"
-$desc=$collectedClasses.Ir
+this.X0=X0}E9.builtin$cls="E9"
+if(!"name" in E9)E9.name="E9"
+$desc=$collectedClasses.E9
 if($desc instanceof Array)$desc=$desc[1]
-Ir.prototype=$desc
-Ir.prototype.gPy=function(receiver){return receiver.Py}
-Ir.prototype.gPy.$reflectable=1
-Ir.prototype.sPy=function(receiver,v){return receiver.Py=v}
-Ir.prototype.sPy.$reflectable=1
+E9.prototype=$desc
+E9.prototype.gPy=function(receiver){return receiver.Py}
+E9.prototype.gPy.$reflectable=1
+E9.prototype.sPy=function(receiver,v){return receiver.Py=v}
+E9.prototype.sPy.$reflectable=1
 function Vct(){}Vct.builtin$cls="Vct"
 if(!"name" in Vct)Vct.name="Vct"
 $desc=$collectedClasses.Vct
 if($desc instanceof Array)$desc=$desc[1]
 Vct.prototype=$desc
-function m8(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function m8(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28858,19 +29170,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}m8.builtin$cls="m8"
+this.X0=X0}m8.builtin$cls="m8"
 if(!"name" in m8)m8.name="m8"
 $desc=$collectedClasses.m8
 if($desc instanceof Array)$desc=$desc[1]
 m8.prototype=$desc
-function jM(vt,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.vt=vt
+function Gk(vt,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.vt=vt
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28878,29 +29190,30 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}jM.builtin$cls="jM"
-if(!"name" in jM)jM.name="jM"
-$desc=$collectedClasses.jM
+this.X0=X0}Gk.builtin$cls="Gk"
+if(!"name" in Gk)Gk.name="Gk"
+$desc=$collectedClasses.Gk
 if($desc instanceof Array)$desc=$desc[1]
-jM.prototype=$desc
-jM.prototype.gvt=function(receiver){return receiver.vt}
-jM.prototype.gvt.$reflectable=1
-jM.prototype.svt=function(receiver,v){return receiver.vt=v}
-jM.prototype.svt.$reflectable=1
+Gk.prototype=$desc
+Gk.prototype.gvt=function(receiver){return receiver.vt}
+Gk.prototype.gvt.$reflectable=1
+Gk.prototype.svt=function(receiver,v){return receiver.vt=v}
+Gk.prototype.svt.$reflectable=1
 function D13(){}D13.builtin$cls="D13"
 if(!"name" in D13)D13.name="D13"
 $desc=$collectedClasses.D13
 if($desc instanceof Array)$desc=$desc[1]
 D13.prototype=$desc
-function DKl(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function GG(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28908,19 +29221,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}DKl.builtin$cls="DKl"
-if(!"name" in DKl)DKl.name="DKl"
-$desc=$collectedClasses.DKl
+this.X0=X0}GG.builtin$cls="GG"
+if(!"name" in GG)GG.name="GG"
+$desc=$collectedClasses.GG
 if($desc instanceof Array)$desc=$desc[1]
-DKl.prototype=$desc
-function mk(Z8,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Z8=Z8
+GG.prototype=$desc
+function yb(Z8,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Z8=Z8
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -28928,28 +29241,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}mk.builtin$cls="mk"
-if(!"name" in mk)mk.name="mk"
-$desc=$collectedClasses.mk
+this.X0=X0}yb.builtin$cls="yb"
+if(!"name" in yb)yb.name="yb"
+$desc=$collectedClasses.yb
 if($desc instanceof Array)$desc=$desc[1]
-mk.prototype=$desc
-mk.prototype.gZ8=function(receiver){return receiver.Z8}
-mk.prototype.gZ8.$reflectable=1
-mk.prototype.sZ8=function(receiver,v){return receiver.Z8=v}
-mk.prototype.sZ8.$reflectable=1
+yb.prototype=$desc
+yb.prototype.gZ8=function(receiver){return receiver.Z8}
+yb.prototype.gZ8.$reflectable=1
+yb.prototype.sZ8=function(receiver,v){return receiver.Z8=v}
+yb.prototype.sZ8.$reflectable=1
 function WZq(){}WZq.builtin$cls="WZq"
 if(!"name" in WZq)WZq.name="WZq"
 $desc=$collectedClasses.WZq
 if($desc instanceof Array)$desc=$desc[1]
 WZq.prototype=$desc
-function NM(GQ,J0,Oc,CO,e6,an,Ol,X3,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.GQ=GQ
+function NM(GQ,J0,Oc,CO,e6,an,Ol,X3,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.GQ=GQ
 this.J0=J0
 this.Oc=Oc
 this.CO=CO
@@ -28964,14 +29277,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}NM.builtin$cls="NM"
+this.X0=X0}NM.builtin$cls="NM"
 if(!"name" in NM)NM.name="NM"
 $desc=$collectedClasses.NM
 if($desc instanceof Array)$desc=$desc[1]
@@ -29051,12 +29364,12 @@
 $desc=$collectedClasses.Tm
 if($desc instanceof Array)$desc=$desc[1]
 Tm.prototype=$desc
-function rz(a,Gq){this.a=a
-this.Gq=Gq}rz.builtin$cls="rz"
-if(!"name" in rz)rz.name="rz"
-$desc=$collectedClasses.rz
+function q1(a,Gq){this.a=a
+this.Gq=Gq}q1.builtin$cls="q1"
+if(!"name" in q1)q1.name="q1"
+$desc=$collectedClasses.q1
 if($desc instanceof Array)$desc=$desc[1]
-rz.prototype=$desc
+q1.prototype=$desc
 function CA(a,b){this.a=a
 this.b=b}CA.builtin$cls="CA"
 if(!"name" in CA)CA.name="CA"
@@ -29081,11 +29394,11 @@
 $desc=$collectedClasses.xL
 if($desc instanceof Array)$desc=$desc[1]
 xL.prototype=$desc
-function Ay(){}Ay.builtin$cls="Ay"
-if(!"name" in Ay)Ay.name="Ay"
-$desc=$collectedClasses.Ay
+function As(){}As.builtin$cls="As"
+if(!"name" in As)As.name="As"
+$desc=$collectedClasses.As
 if($desc instanceof Array)$desc=$desc[1]
-Ay.prototype=$desc
+As.prototype=$desc
 function GE(a){this.a=a}GE.builtin$cls="GE"
 if(!"name" in GE)GE.name="GE"
 $desc=$collectedClasses.GE
@@ -29117,8 +29430,12 @@
 $desc=$collectedClasses.GS
 if($desc instanceof Array)$desc=$desc[1]
 GS.prototype=$desc
-function pR(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function pR(qX,AP,fn,tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.qX=qX
+this.AP=AP
+this.fn=fn
+this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29126,19 +29443,38 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}pR.builtin$cls="pR"
+this.X0=X0}pR.builtin$cls="pR"
 if(!"name" in pR)pR.name="pR"
 $desc=$collectedClasses.pR
 if($desc instanceof Array)$desc=$desc[1]
 pR.prototype=$desc
-function hx(Xh,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Xh=Xh
+pR.prototype.gqX=function(receiver){return receiver.qX}
+pR.prototype.gqX.$reflectable=1
+pR.prototype.sqX=function(receiver,v){return receiver.qX=v}
+pR.prototype.sqX.$reflectable=1
+function T5(){}T5.builtin$cls="T5"
+if(!"name" in T5)T5.name="T5"
+$desc=$collectedClasses.T5
+if($desc instanceof Array)$desc=$desc[1]
+T5.prototype=$desc
+function YE(a){this.a=a}YE.builtin$cls="YE"
+if(!"name" in YE)YE.name="YE"
+$desc=$collectedClasses.YE
+if($desc instanceof Array)$desc=$desc[1]
+YE.prototype=$desc
+function we(){}we.builtin$cls="we"
+if(!"name" in we)we.name="we"
+$desc=$collectedClasses.we
+if($desc instanceof Array)$desc=$desc[1]
+we.prototype=$desc
+function hx(Xh,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Xh=Xh
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29146,14 +29482,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}hx.builtin$cls="hx"
+this.X0=X0}hx.builtin$cls="hx"
 if(!"name" in hx)hx.name="hx"
 $desc=$collectedClasses.hx
 if($desc instanceof Array)$desc=$desc[1]
@@ -29167,19 +29503,19 @@
 $desc=$collectedClasses.cda
 if($desc instanceof Array)$desc=$desc[1]
 cda.prototype=$desc
-function u7(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+function u7(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}u7.builtin$cls="u7"
+this.X0=X0}u7.builtin$cls="u7"
 if(!"name" in u7)u7.name="u7"
 $desc=$collectedClasses.u7
 if($desc instanceof Array)$desc=$desc[1]
@@ -29189,10 +29525,32 @@
 $desc=$collectedClasses.fW
 if($desc instanceof Array)$desc=$desc[1]
 fW.prototype=$desc
-function E7(BA,fb,iZ,qY,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.BA=BA
+function qm(Aq,tT,eT,yt,wd,oH,np,AP,fn){this.Aq=Aq
+this.tT=tT
+this.eT=eT
+this.yt=yt
+this.wd=wd
+this.oH=oH
+this.np=np
+this.AP=AP
+this.fn=fn}qm.builtin$cls="qm"
+if(!"name" in qm)qm.name="qm"
+$desc=$collectedClasses.qm
+if($desc instanceof Array)$desc=$desc[1]
+qm.prototype=$desc
+qm.prototype.gAq=function(receiver){return this.Aq}
+qm.prototype.gtT=function(receiver){return this.tT}
+qm.prototype.gtT.$reflectable=1
+function vO(a){this.a=a}vO.builtin$cls="vO"
+if(!"name" in vO)vO.name="vO"
+$desc=$collectedClasses.vO
+if($desc instanceof Array)$desc=$desc[1]
+vO.prototype=$desc
+function E7(BA,fb,qY,qO,Hm,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.BA=BA
 this.fb=fb
-this.iZ=iZ
 this.qY=qY
+this.qO=qO
+this.Hm=Hm
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29200,14 +29558,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}E7.builtin$cls="E7"
+this.X0=X0}E7.builtin$cls="E7"
 if(!"name" in E7)E7.name="E7"
 $desc=$collectedClasses.E7
 if($desc instanceof Array)$desc=$desc[1]
@@ -29218,14 +29576,16 @@
 E7.prototype.sBA.$reflectable=1
 E7.prototype.gfb=function(receiver){return receiver.fb}
 E7.prototype.gfb.$reflectable=1
-E7.prototype.giZ=function(receiver){return receiver.iZ}
-E7.prototype.giZ.$reflectable=1
-E7.prototype.siZ=function(receiver,v){return receiver.iZ=v}
-E7.prototype.siZ.$reflectable=1
 E7.prototype.gqY=function(receiver){return receiver.qY}
 E7.prototype.gqY.$reflectable=1
 E7.prototype.sqY=function(receiver,v){return receiver.qY=v}
 E7.prototype.sqY.$reflectable=1
+E7.prototype.gqO=function(receiver){return receiver.qO}
+E7.prototype.gqO.$reflectable=1
+E7.prototype.gHm=function(receiver){return receiver.Hm}
+E7.prototype.gHm.$reflectable=1
+E7.prototype.sHm=function(receiver,v){return receiver.Hm=v}
+E7.prototype.sHm.$reflectable=1
 function waa(){}waa.builtin$cls="waa"
 if(!"name" in waa)waa.name="waa"
 $desc=$collectedClasses.waa
@@ -29242,7 +29602,7 @@
 $desc=$collectedClasses.EL
 if($desc instanceof Array)$desc=$desc[1]
 EL.prototype=$desc
-function St(Pw,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Pw=Pw
+function St(Pw,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Pw=Pw
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29250,14 +29610,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}St.builtin$cls="St"
+this.X0=X0}St.builtin$cls="St"
 if(!"name" in St)St.name="St"
 $desc=$collectedClasses.St
 if($desc instanceof Array)$desc=$desc[1]
@@ -29271,7 +29631,7 @@
 $desc=$collectedClasses.V0
 if($desc instanceof Array)$desc=$desc[1]
 V0.prototype=$desc
-function vj(eb,kf,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.eb=eb
+function vj(eb,kf,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.eb=eb
 this.kf=kf
 this.AP=AP
 this.fn=fn
@@ -29280,14 +29640,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}vj.builtin$cls="vj"
+this.X0=X0}vj.builtin$cls="vj"
 if(!"name" in vj)vj.name="vj"
 $desc=$collectedClasses.vj
 if($desc instanceof Array)$desc=$desc[1]
@@ -29305,8 +29665,9 @@
 $desc=$collectedClasses.V4
 if($desc instanceof Array)$desc=$desc[1]
 V4.prototype=$desc
-function LU(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function LU(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29314,19 +29675,19 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}LU.builtin$cls="LU"
+this.X0=X0}LU.builtin$cls="LU"
 if(!"name" in LU)LU.name="LU"
 $desc=$collectedClasses.LU
 if($desc instanceof Array)$desc=$desc[1]
 LU.prototype=$desc
-function CX(N7,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.N7=N7
+function T2(N7,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.N7=N7
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29334,27 +29695,27 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}CX.builtin$cls="CX"
-if(!"name" in CX)CX.name="CX"
-$desc=$collectedClasses.CX
+this.X0=X0}T2.builtin$cls="T2"
+if(!"name" in T2)T2.name="T2"
+$desc=$collectedClasses.T2
 if($desc instanceof Array)$desc=$desc[1]
-CX.prototype=$desc
-CX.prototype.gN7=function(receiver){return receiver.N7}
-CX.prototype.gN7.$reflectable=1
-CX.prototype.sN7=function(receiver,v){return receiver.N7=v}
-CX.prototype.sN7.$reflectable=1
-function V6(){}V6.builtin$cls="V6"
-if(!"name" in V6)V6.name="V6"
-$desc=$collectedClasses.V6
+T2.prototype=$desc
+T2.prototype.gN7=function(receiver){return receiver.N7}
+T2.prototype.gN7.$reflectable=1
+T2.prototype.sN7=function(receiver,v){return receiver.N7=v}
+T2.prototype.sN7.$reflectable=1
+function V10(){}V10.builtin$cls="V10"
+if(!"name" in V10)V10.name="V10"
+$desc=$collectedClasses.V10
 if($desc instanceof Array)$desc=$desc[1]
-V6.prototype=$desc
+V10.prototype=$desc
 function TJ(oc,eT,n2,Cj,wd,Gs){this.oc=oc
 this.eT=eT
 this.n2=n2
@@ -29408,20 +29769,20 @@
 $desc=$collectedClasses.Lb
 if($desc instanceof Array)$desc=$desc[1]
 Lb.prototype=$desc
-function PF(Gj,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Gj=Gj
+function PF(Gj,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Gj=Gj
 this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}PF.builtin$cls="PF"
+this.X0=X0}PF.builtin$cls="PF"
 if(!"name" in PF)PF.name="PF"
 $desc=$collectedClasses.PF
 if($desc instanceof Array)$desc=$desc[1]
@@ -29447,34 +29808,34 @@
 if($desc instanceof Array)$desc=$desc[1]
 jA.prototype=$desc
 jA.prototype.goc=function(receiver){return this.oc}
-function Jo(){}Jo.builtin$cls="Jo"
-if(!"name" in Jo)Jo.name="Jo"
-$desc=$collectedClasses.Jo
+function PO(){}PO.builtin$cls="PO"
+if(!"name" in PO)PO.name="PO"
+$desc=$collectedClasses.PO
 if($desc instanceof Array)$desc=$desc[1]
-Jo.prototype=$desc
+PO.prototype=$desc
 function c5(){}c5.builtin$cls="c5"
 if(!"name" in c5)c5.name="c5"
 $desc=$collectedClasses.c5
 if($desc instanceof Array)$desc=$desc[1]
 c5.prototype=$desc
-function qT(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+function qT(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}qT.builtin$cls="qT"
+this.X0=X0}qT.builtin$cls="qT"
 if(!"name" in qT)qT.name="qT"
 $desc=$collectedClasses.qT
 if($desc instanceof Array)$desc=$desc[1]
 qT.prototype=$desc
-function Xd(rK,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.rK=rK
+function Xd(rK,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.rK=rK
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29482,14 +29843,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Xd.builtin$cls="Xd"
+this.X0=X0}Xd.builtin$cls="Xd"
 if(!"name" in Xd)Xd.name="Xd"
 $desc=$collectedClasses.Xd
 if($desc instanceof Array)$desc=$desc[1]
@@ -29498,13 +29859,13 @@
 Xd.prototype.grK.$reflectable=1
 Xd.prototype.srK=function(receiver,v){return receiver.rK=v}
 Xd.prototype.srK.$reflectable=1
-function V10(){}V10.builtin$cls="V10"
-if(!"name" in V10)V10.name="V10"
-$desc=$collectedClasses.V10
+function V11(){}V11.builtin$cls="V11"
+if(!"name" in V11)V11.name="V11"
+$desc=$collectedClasses.V11
 if($desc instanceof Array)$desc=$desc[1]
-V10.prototype=$desc
-function mL(Z6,lw,nI,AP,fn){this.Z6=Z6
-this.lw=lw
+V11.prototype=$desc
+function mL(Z6,DF,nI,AP,fn){this.Z6=Z6
+this.DF=DF
 this.nI=nI
 this.AP=AP
 this.fn=fn}mL.builtin$cls="mL"
@@ -29514,8 +29875,8 @@
 mL.prototype=$desc
 mL.prototype.gZ6=function(){return this.Z6}
 mL.prototype.gZ6.$reflectable=1
-mL.prototype.glw=function(){return this.lw}
-mL.prototype.glw.$reflectable=1
+mL.prototype.gDF=function(){return this.DF}
+mL.prototype.gDF.$reflectable=1
 mL.prototype.gnI=function(){return this.nI}
 mL.prototype.gnI.$reflectable=1
 function Kf(oV){this.oV=oV}Kf.builtin$cls="Kf"
@@ -29531,15 +29892,15 @@
 if($desc instanceof Array)$desc=$desc[1]
 qu.prototype=$desc
 qu.prototype.gbG=function(receiver){return this.bG}
-function bv(WP,XR,Z0,md,mY,F3,Gg,LE,a3,mU,mM,Td,AP,fn){this.WP=WP
+function bv(WP,XR,Z0,md,mY,F3,rU,LE,iP,mU,mM,Td,AP,fn){this.WP=WP
 this.XR=XR
 this.Z0=Z0
 this.md=md
 this.mY=mY
 this.F3=F3
-this.Gg=Gg
+this.rU=rU
 this.LE=LE
-this.a3=a3
+this.iP=iP
 this.mU=mU
 this.mM=mM
 this.Td=Td
@@ -29570,17 +29931,17 @@
 $desc=$collectedClasses.TI
 if($desc instanceof Array)$desc=$desc[1]
 TI.prototype=$desc
-function pt(XT,i2,AP,fn){this.XT=XT
+function yU(XT,i2,AP,fn){this.XT=XT
 this.i2=i2
 this.AP=AP
-this.fn=fn}pt.builtin$cls="pt"
-if(!"name" in pt)pt.name="pt"
-$desc=$collectedClasses.pt
+this.fn=fn}yU.builtin$cls="yU"
+if(!"name" in yU)yU.name="yU"
+$desc=$collectedClasses.yU
 if($desc instanceof Array)$desc=$desc[1]
-pt.prototype=$desc
-pt.prototype.sXT=function(v){return this.XT=v}
-pt.prototype.gi2=function(){return this.i2}
-pt.prototype.gi2.$reflectable=1
+yU.prototype=$desc
+yU.prototype.sXT=function(v){return this.XT=v}
+yU.prototype.gi2=function(){return this.i2}
+yU.prototype.gi2.$reflectable=1
 function Ub(a){this.a=a}Ub.builtin$cls="Ub"
 if(!"name" in Ub)Ub.name="Ub"
 $desc=$collectedClasses.Ub
@@ -29618,11 +29979,11 @@
 if($desc instanceof Array)$desc=$desc[1]
 dZ.prototype=$desc
 dZ.prototype.sXT=function(v){return this.XT=v}
-function us(a){this.a=a}us.builtin$cls="us"
-if(!"name" in us)us.name="us"
-$desc=$collectedClasses.us
+function Qe(a){this.a=a}Qe.builtin$cls="Qe"
+if(!"name" in Qe)Qe.name="Qe"
+$desc=$collectedClasses.Qe
 if($desc instanceof Array)$desc=$desc[1]
-us.prototype=$desc
+Qe.prototype=$desc
 function DP(Yu,m7,L4,Fv,ZZ,AP,fn){this.Yu=Yu
 this.m7=m7
 this.L4=L4
@@ -29645,25 +30006,35 @@
 $desc=$collectedClasses.WAE
 if($desc instanceof Array)$desc=$desc[1]
 WAE.prototype=$desc
-function N8(Yu,a0){this.Yu=Yu
-this.a0=a0}N8.builtin$cls="N8"
+function N8(Yu,z4,Iw){this.Yu=Yu
+this.z4=z4
+this.Iw=Iw}N8.builtin$cls="N8"
 if(!"name" in N8)N8.name="N8"
 $desc=$collectedClasses.N8
 if($desc instanceof Array)$desc=$desc[1]
 N8.prototype=$desc
 N8.prototype.gYu=function(){return this.Yu}
-N8.prototype.ga0=function(){return this.a0}
-function kx(fY,vg,Mb,a0,fF,Du,va,Qo,kY,mY,Tl,AP,fn){this.fY=fY
+function Vi(tT,Ou){this.tT=tT
+this.Ou=Ou}Vi.builtin$cls="Vi"
+if(!"name" in Vi)Vi.name="Vi"
+$desc=$collectedClasses.Vi
+if($desc instanceof Array)$desc=$desc[1]
+Vi.prototype=$desc
+Vi.prototype.gtT=function(receiver){return this.tT}
+Vi.prototype.gOu=function(){return this.Ou}
+function kx(fY,vg,Mb,a0,VS,hw,fF,Du,va,Qo,uP,mY,B0,AP,fn){this.fY=fY
 this.vg=vg
 this.Mb=Mb
 this.a0=a0
+this.VS=VS
+this.hw=hw
 this.fF=fF
 this.Du=Du
 this.va=va
 this.Qo=Qo
-this.kY=kY
+this.uP=uP
 this.mY=mY
-this.Tl=Tl
+this.B0=B0
 this.AP=AP
 this.fn=fn}kx.builtin$cls="kx"
 if(!"name" in kx)kx.name="kx"
@@ -29672,13 +30043,18 @@
 kx.prototype=$desc
 kx.prototype.gfY=function(receiver){return this.fY}
 kx.prototype.ga0=function(){return this.a0}
+kx.prototype.gVS=function(){return this.VS}
 kx.prototype.gfF=function(){return this.fF}
-kx.prototype.sfF=function(v){return this.fF=v}
 kx.prototype.gDu=function(){return this.Du}
-kx.prototype.sDu=function(v){return this.Du=v}
 kx.prototype.gva=function(){return this.va}
 kx.prototype.gva.$reflectable=1
-function CM(Aq,hV){this.Aq=Aq
+function fx(){}fx.builtin$cls="fx"
+if(!"name" in fx)fx.name="fx"
+$desc=$collectedClasses.fx
+if($desc instanceof Array)$desc=$desc[1]
+fx.prototype=$desc
+function CM(Aq,jV,hV){this.Aq=Aq
+this.jV=jV
 this.hV=hV}CM.builtin$cls="CM"
 if(!"name" in CM)CM.name="CM"
 $desc=$collectedClasses.CM
@@ -29691,26 +30067,11 @@
 $desc=$collectedClasses.xn
 if($desc instanceof Array)$desc=$desc[1]
 xn.prototype=$desc
-function ct(a){this.a=a}ct.builtin$cls="ct"
-if(!"name" in ct)ct.name="ct"
-$desc=$collectedClasses.ct
-if($desc instanceof Array)$desc=$desc[1]
-ct.prototype=$desc
-function hM(a){this.a=a}hM.builtin$cls="hM"
-if(!"name" in hM)hM.name="hM"
-$desc=$collectedClasses.hM
-if($desc instanceof Array)$desc=$desc[1]
-hM.prototype=$desc
 function vu(){}vu.builtin$cls="vu"
 if(!"name" in vu)vu.name="vu"
 $desc=$collectedClasses.vu
 if($desc instanceof Array)$desc=$desc[1]
 vu.prototype=$desc
-function Ja(){}Ja.builtin$cls="Ja"
-if(!"name" in Ja)Ja.name="Ja"
-$desc=$collectedClasses.Ja
-if($desc instanceof Array)$desc=$desc[1]
-Ja.prototype=$desc
 function c2(Rd,eB,P2,AP,fn){this.Rd=Rd
 this.eB=eB
 this.P2=P2
@@ -29720,7 +30081,7 @@
 $desc=$collectedClasses.c2
 if($desc instanceof Array)$desc=$desc[1]
 c2.prototype=$desc
-c2.prototype.gRd=function(){return this.Rd}
+c2.prototype.gRd=function(receiver){return this.Rd}
 c2.prototype.gRd.$reflectable=1
 function rj(W6,xN,Hz,Sw,UK,AP,fn){this.W6=W6
 this.xN=xN
@@ -29735,14 +30096,14 @@
 rj.prototype=$desc
 rj.prototype.gSw=function(){return this.Sw}
 rj.prototype.gSw.$reflectable=1
-function R2(XT,e0){this.XT=XT
-this.e0=e0}R2.builtin$cls="R2"
-if(!"name" in R2)R2.name="R2"
-$desc=$collectedClasses.R2
+function Nu(XT,e0){this.XT=XT
+this.e0=e0}Nu.builtin$cls="Nu"
+if(!"name" in Nu)Nu.name="Nu"
+$desc=$collectedClasses.Nu
 if($desc instanceof Array)$desc=$desc[1]
-R2.prototype=$desc
-R2.prototype.sXT=function(v){return this.XT=v}
-R2.prototype.se0=function(v){return this.e0=v}
+Nu.prototype=$desc
+Nu.prototype.sXT=function(v){return this.XT=v}
+Nu.prototype.se0=function(v){return this.e0=v}
 function Q4(a,b,c){this.a=a
 this.b=b
 this.c=c}Q4.builtin$cls="Q4"
@@ -29773,16 +30134,16 @@
 $desc=$collectedClasses.Q2
 if($desc instanceof Array)$desc=$desc[1]
 Q2.prototype=$desc
-function tb(XT,e0,SI,Tj,AP,fn){this.XT=XT
+function r1(XT,e0,SI,Tj,AP,fn){this.XT=XT
 this.e0=e0
 this.SI=SI
 this.Tj=Tj
 this.AP=AP
-this.fn=fn}tb.builtin$cls="tb"
-if(!"name" in tb)tb.name="tb"
-$desc=$collectedClasses.tb
+this.fn=fn}r1.builtin$cls="r1"
+if(!"name" in r1)r1.name="r1"
+$desc=$collectedClasses.r1
 if($desc instanceof Array)$desc=$desc[1]
-tb.prototype=$desc
+r1.prototype=$desc
 function Rb(eA,Wj,XT,e0,SI,Tj,AP,fn){this.eA=eA
 this.Wj=Wj
 this.XT=XT
@@ -29795,7 +30156,32 @@
 $desc=$collectedClasses.Rb
 if($desc instanceof Array)$desc=$desc[1]
 Rb.prototype=$desc
-function F1(k5,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.k5=k5
+function Y2(eT,yt,wd,oH){this.eT=eT
+this.yt=yt
+this.wd=wd
+this.oH=oH}Y2.builtin$cls="Y2"
+if(!"name" in Y2)Y2.name="Y2"
+$desc=$collectedClasses.Y2
+if($desc instanceof Array)$desc=$desc[1]
+Y2.prototype=$desc
+Y2.prototype.geT=function(receiver){return this.eT}
+Y2.prototype.gyt=function(){return this.yt}
+Y2.prototype.gyt.$reflectable=1
+Y2.prototype.gwd=function(receiver){return this.wd}
+Y2.prototype.gwd.$reflectable=1
+Y2.prototype.goH=function(){return this.oH}
+Y2.prototype.goH.$reflectable=1
+function XN(JL,WT,AP,fn){this.JL=JL
+this.WT=WT
+this.AP=AP
+this.fn=fn}XN.builtin$cls="XN"
+if(!"name" in XN)XN.name="XN"
+$desc=$collectedClasses.XN
+if($desc instanceof Array)$desc=$desc[1]
+XN.prototype=$desc
+XN.prototype.gWT=function(receiver){return this.WT}
+XN.prototype.gWT.$reflectable=1
+function F1(k5,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.k5=k5
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -29803,14 +30189,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}F1.builtin$cls="F1"
+this.X0=X0}F1.builtin$cls="F1"
 if(!"name" in F1)F1.name="F1"
 $desc=$collectedClasses.F1
 if($desc instanceof Array)$desc=$desc[1]
@@ -29819,24 +30205,24 @@
 F1.prototype.gk5.$reflectable=1
 F1.prototype.sk5=function(receiver,v){return receiver.k5=v}
 F1.prototype.sk5.$reflectable=1
-function V11(){}V11.builtin$cls="V11"
-if(!"name" in V11)V11.name="V11"
-$desc=$collectedClasses.V11
+function V12(){}V12.builtin$cls="V12"
+if(!"name" in V12)V12.name="V12"
+$desc=$collectedClasses.V12
 if($desc instanceof Array)$desc=$desc[1]
-V11.prototype=$desc
-function uL(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+V12.prototype=$desc
+function uL(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}uL.builtin$cls="uL"
+this.X0=X0}uL.builtin$cls="uL"
 if(!"name" in uL)uL.name="uL"
 $desc=$collectedClasses.uL
 if($desc instanceof Array)$desc=$desc[1]
@@ -29899,11 +30285,11 @@
 $desc=$collectedClasses.b5
 if($desc instanceof Array)$desc=$desc[1]
 b5.prototype=$desc
-function u3(b){this.b=b}u3.builtin$cls="u3"
-if(!"name" in u3)u3.name="u3"
-$desc=$collectedClasses.u3
+function zI(b){this.b=b}zI.builtin$cls="zI"
+if(!"name" in zI)zI.name="zI"
+$desc=$collectedClasses.zI
 if($desc instanceof Array)$desc=$desc[1]
-u3.prototype=$desc
+zI.prototype=$desc
 function Zb(c,d,e,f){this.c=c
 this.d=d
 this.e=e
@@ -29951,12 +30337,12 @@
 $desc=$collectedClasses.d3
 if($desc instanceof Array)$desc=$desc[1]
 d3.prototype=$desc
-function X6(a,b){this.a=a
-this.b=b}X6.builtin$cls="X6"
-if(!"name" in X6)X6.name="X6"
-$desc=$collectedClasses.X6
+function lS(a,b){this.a=a
+this.b=b}lS.builtin$cls="lS"
+if(!"name" in lS)lS.name="lS"
+$desc=$collectedClasses.lS
 if($desc instanceof Array)$desc=$desc[1]
-X6.prototype=$desc
+lS.prototype=$desc
 function xh(L1,AP,fn){this.L1=L1
 this.AP=AP
 this.fn=fn}xh.builtin$cls="xh"
@@ -29973,16 +30359,16 @@
 $desc=$collectedClasses.wn
 if($desc instanceof Array)$desc=$desc[1]
 wn.prototype=$desc
-function uF(){}uF.builtin$cls="uF"
-if(!"name" in uF)uF.name="uF"
-$desc=$collectedClasses.uF
+function Ay(){}Ay.builtin$cls="Ay"
+if(!"name" in Ay)Ay.name="Ay"
+$desc=$collectedClasses.Ay
 if($desc instanceof Array)$desc=$desc[1]
-uF.prototype=$desc
-function cj(a){this.a=a}cj.builtin$cls="cj"
-if(!"name" in cj)cj.name="cj"
-$desc=$collectedClasses.cj
+Ay.prototype=$desc
+function Bj(a){this.a=a}Bj.builtin$cls="Bj"
+if(!"name" in Bj)Bj.name="Bj"
+$desc=$collectedClasses.Bj
 if($desc instanceof Array)$desc=$desc[1]
-cj.prototype=$desc
+Bj.prototype=$desc
 function HA(G3,jL,zZ,JD,dr){this.G3=G3
 this.jL=jL
 this.zZ=zZ
@@ -30053,96 +30439,6 @@
 $desc=$collectedClasses.km
 if($desc instanceof Array)$desc=$desc[1]
 km.prototype=$desc
-function lI(S,l){this.S=S
-this.l=l}lI.builtin$cls="lI"
-if(!"name" in lI)lI.name="lI"
-$desc=$collectedClasses.lI
-if($desc instanceof Array)$desc=$desc[1]
-lI.prototype=$desc
-function u2(){}u2.builtin$cls="u2"
-if(!"name" in u2)u2.name="u2"
-$desc=$collectedClasses.u2
-if($desc instanceof Array)$desc=$desc[1]
-u2.prototype=$desc
-function q7(){}q7.builtin$cls="q7"
-if(!"name" in q7)q7.name="q7"
-$desc=$collectedClasses.q7
-if($desc instanceof Array)$desc=$desc[1]
-q7.prototype=$desc
-function Qt(){}Qt.builtin$cls="Qt"
-if(!"name" in Qt)Qt.name="Qt"
-$desc=$collectedClasses.Qt
-if($desc instanceof Array)$desc=$desc[1]
-Qt.prototype=$desc
-function No(){}No.builtin$cls="No"
-if(!"name" in No)No.name="No"
-$desc=$collectedClasses.No
-if($desc instanceof Array)$desc=$desc[1]
-No.prototype=$desc
-function v5(S,SF,aA,wZ,ZB){this.S=S
-this.SF=SF
-this.aA=aA
-this.wZ=wZ
-this.ZB=ZB}v5.builtin$cls="v5"
-if(!"name" in v5)v5.name="v5"
-$desc=$collectedClasses.v5
-if($desc instanceof Array)$desc=$desc[1]
-v5.prototype=$desc
-function OO(TL){this.TL=TL}OO.builtin$cls="OO"
-if(!"name" in OO)OO.name="OO"
-$desc=$collectedClasses.OO
-if($desc instanceof Array)$desc=$desc[1]
-OO.prototype=$desc
-OO.prototype.gTL=function(){return this.TL}
-function OF(oc,mI,DF,nK,Ew,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.TL=TL}OF.builtin$cls="OF"
-if(!"name" in OF)OF.name="OF"
-$desc=$collectedClasses.OF
-if($desc instanceof Array)$desc=$desc[1]
-OF.prototype=$desc
-OF.prototype.goc=function(receiver){return this.oc}
-OF.prototype.gmI=function(){return this.mI}
-OF.prototype.gDF=function(){return this.DF}
-OF.prototype.gnK=function(){return this.nK}
-OF.prototype.gEw=function(){return this.Ew}
-function rM(oc,mI,DF,nK,Ew,ir,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.ir=ir
-this.TL=TL}rM.builtin$cls="rM"
-if(!"name" in rM)rM.name="rM"
-$desc=$collectedClasses.rM
-if($desc instanceof Array)$desc=$desc[1]
-rM.prototype=$desc
-rM.prototype.goc=function(receiver){return this.oc}
-rM.prototype.gmI=function(){return this.mI}
-rM.prototype.gDF=function(){return this.DF}
-rM.prototype.gnK=function(){return this.nK}
-rM.prototype.gEw=function(){return this.Ew}
-rM.prototype.gTL=function(){return this.ir}
-function IV(oc,mI,DF,nK,Ew,r9,TL){this.oc=oc
-this.mI=mI
-this.DF=DF
-this.nK=nK
-this.Ew=Ew
-this.r9=r9
-this.TL=TL}IV.builtin$cls="IV"
-if(!"name" in IV)IV.name="IV"
-$desc=$collectedClasses.IV
-if($desc instanceof Array)$desc=$desc[1]
-IV.prototype=$desc
-IV.prototype.goc=function(receiver){return this.oc}
-IV.prototype.gmI=function(){return this.mI}
-IV.prototype.gDF=function(){return this.DF}
-IV.prototype.gnK=function(){return this.nK}
-IV.prototype.gEw=function(){return this.Ew}
-IV.prototype.gTL=function(){return this.r9}
 function Zj(){}Zj.builtin$cls="Zj"
 if(!"name" in Zj)Zj.name="Zj"
 $desc=$collectedClasses.Zj
@@ -30199,27 +30495,27 @@
 $desc=$collectedClasses.MX
 if($desc instanceof Array)$desc=$desc[1]
 MX.prototype=$desc
-function w11(){}w11.builtin$cls="w11"
-if(!"name" in w11)w11.name="w11"
-$desc=$collectedClasses.w11
+function w9(){}w9.builtin$cls="w9"
+if(!"name" in w9)w9.name="w9"
+$desc=$collectedClasses.w9
 if($desc instanceof Array)$desc=$desc[1]
-w11.prototype=$desc
-function ppY(a){this.a=a}ppY.builtin$cls="ppY"
-if(!"name" in ppY)ppY.name="ppY"
-$desc=$collectedClasses.ppY
+w9.prototype=$desc
+function r3y(a){this.a=a}r3y.builtin$cls="r3y"
+if(!"name" in r3y)r3y.name="r3y"
+$desc=$collectedClasses.r3y
 if($desc instanceof Array)$desc=$desc[1]
-ppY.prototype=$desc
+r3y.prototype=$desc
 function yL(){}yL.builtin$cls="yL"
 if(!"name" in yL)yL.name="yL"
 $desc=$collectedClasses.yL
 if($desc instanceof Array)$desc=$desc[1]
 yL.prototype=$desc
-function zs(ZQ){this.ZQ=ZQ}zs.builtin$cls="zs"
+function zs(X0){this.X0=X0}zs.builtin$cls="zs"
 if(!"name" in zs)zs.name="zs"
 $desc=$collectedClasses.zs
 if($desc instanceof Array)$desc=$desc[1]
 zs.prototype=$desc
-zs.prototype.gKM=function(receiver){return receiver.ZQ}
+zs.prototype.gKM=function(receiver){return receiver.X0}
 zs.prototype.gKM.$reflectable=1
 function WC(a){this.a=a}WC.builtin$cls="WC"
 if(!"name" in WC)WC.name="WC"
@@ -30303,41 +30599,41 @@
 $desc=$collectedClasses.Bf
 if($desc instanceof Array)$desc=$desc[1]
 Bf.prototype=$desc
-function ir(AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.AP=AP
+function ir(AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}ir.builtin$cls="ir"
+this.X0=X0}ir.builtin$cls="ir"
 if(!"name" in ir)ir.name="ir"
 $desc=$collectedClasses.ir
 if($desc instanceof Array)$desc=$desc[1]
 ir.prototype=$desc
-function Sa(ZQ){this.ZQ=ZQ}Sa.builtin$cls="Sa"
-if(!"name" in Sa)Sa.name="Sa"
-$desc=$collectedClasses.Sa
+function jpR(X0){this.X0=X0}jpR.builtin$cls="jpR"
+if(!"name" in jpR)jpR.name="jpR"
+$desc=$collectedClasses.jpR
 if($desc instanceof Array)$desc=$desc[1]
-Sa.prototype=$desc
-zs.prototype.gKM=function(receiver){return receiver.ZQ}
+jpR.prototype=$desc
+zs.prototype.gKM=function(receiver){return receiver.X0}
 zs.prototype.gKM.$reflectable=1
-function Ao(){}Ao.builtin$cls="Ao"
-if(!"name" in Ao)Ao.name="Ao"
-$desc=$collectedClasses.Ao
+function GN(){}GN.builtin$cls="GN"
+if(!"name" in GN)GN.name="GN"
+$desc=$collectedClasses.GN
 if($desc instanceof Array)$desc=$desc[1]
-Ao.prototype=$desc
-function k8(jL,zZ){this.jL=jL
-this.zZ=zZ}k8.builtin$cls="k8"
-if(!"name" in k8)k8.name="k8"
-$desc=$collectedClasses.k8
+GN.prototype=$desc
+function bS(jL,zZ){this.jL=jL
+this.zZ=zZ}bS.builtin$cls="bS"
+if(!"name" in bS)bS.name="bS"
+$desc=$collectedClasses.bS
 if($desc instanceof Array)$desc=$desc[1]
-k8.prototype=$desc
-k8.prototype.gjL=function(receiver){return this.jL}
-k8.prototype.gzZ=function(receiver){return this.zZ}
-k8.prototype.szZ=function(receiver,v){return this.zZ=v}
+bS.prototype=$desc
+bS.prototype.gjL=function(receiver){return this.jL}
+bS.prototype.gzZ=function(receiver){return this.zZ}
+bS.prototype.szZ=function(receiver,v){return this.zZ=v}
 function HJ(nF){this.nF=nF}HJ.builtin$cls="HJ"
 if(!"name" in HJ)HJ.name="HJ"
 $desc=$collectedClasses.HJ
@@ -30399,26 +30695,26 @@
 $desc=$collectedClasses.pp
 if($desc instanceof Array)$desc=$desc[1]
 pp.prototype=$desc
-function Nq(){}Nq.builtin$cls="Nq"
-if(!"name" in Nq)Nq.name="Nq"
-$desc=$collectedClasses.Nq
-if($desc instanceof Array)$desc=$desc[1]
-Nq.prototype=$desc
 function nl(){}nl.builtin$cls="nl"
 if(!"name" in nl)nl.name="nl"
 $desc=$collectedClasses.nl
 if($desc instanceof Array)$desc=$desc[1]
 nl.prototype=$desc
-function mf(a){this.a=a}mf.builtin$cls="mf"
-if(!"name" in mf)mf.name="mf"
-$desc=$collectedClasses.mf
-if($desc instanceof Array)$desc=$desc[1]
-mf.prototype=$desc
 function ik(){}ik.builtin$cls="ik"
 if(!"name" in ik)ik.name="ik"
 $desc=$collectedClasses.ik
 if($desc instanceof Array)$desc=$desc[1]
 ik.prototype=$desc
+function mf(a){this.a=a}mf.builtin$cls="mf"
+if(!"name" in mf)mf.name="mf"
+$desc=$collectedClasses.mf
+if($desc instanceof Array)$desc=$desc[1]
+mf.prototype=$desc
+function LfS(){}LfS.builtin$cls="LfS"
+if(!"name" in LfS)LfS.name="LfS"
+$desc=$collectedClasses.LfS
+if($desc instanceof Array)$desc=$desc[1]
+LfS.prototype=$desc
 function HK(b){this.b=b}HK.builtin$cls="HK"
 if(!"name" in HK)HK.name="HK"
 $desc=$collectedClasses.HK
@@ -30446,11 +30742,11 @@
 $desc=$collectedClasses.Xy
 if($desc instanceof Array)$desc=$desc[1]
 Xy.prototype=$desc
-function uK(a){this.a=a}uK.builtin$cls="uK"
-if(!"name" in uK)uK.name="uK"
-$desc=$collectedClasses.uK
+function G0(a){this.a=a}G0.builtin$cls="G0"
+if(!"name" in G0)G0.name="G0"
+$desc=$collectedClasses.G0
 if($desc instanceof Array)$desc=$desc[1]
-uK.prototype=$desc
+G0.prototype=$desc
 function mY(a9,Cu,uI,Y7,AP,fn){this.a9=a9
 this.Cu=Cu
 this.uI=uI
@@ -30480,12 +30776,22 @@
 $desc=$collectedClasses.XF
 if($desc instanceof Array)$desc=$desc[1]
 XF.prototype=$desc
-function iH(a,b){this.a=a
-this.b=b}iH.builtin$cls="iH"
-if(!"name" in iH)iH.name="iH"
-$desc=$collectedClasses.iH
+function bX(a,b){this.a=a
+this.b=b}bX.builtin$cls="bX"
+if(!"name" in bX)bX.name="bX"
+$desc=$collectedClasses.bX
 if($desc instanceof Array)$desc=$desc[1]
-iH.prototype=$desc
+bX.prototype=$desc
+function lP(){}lP.builtin$cls="lP"
+if(!"name" in lP)lP.name="lP"
+$desc=$collectedClasses.lP
+if($desc instanceof Array)$desc=$desc[1]
+lP.prototype=$desc
+function Uf(){}Uf.builtin$cls="Uf"
+if(!"name" in Uf)Uf.name="Uf"
+$desc=$collectedClasses.Uf
+if($desc instanceof Array)$desc=$desc[1]
+Uf.prototype=$desc
 function Ra(){}Ra.builtin$cls="Ra"
 if(!"name" in Ra)Ra.name="Ra"
 $desc=$collectedClasses.Ra
@@ -30556,16 +30862,6 @@
 $desc=$collectedClasses.w7
 if($desc instanceof Array)$desc=$desc[1]
 w7.prototype=$desc
-function w9(){}w9.builtin$cls="w9"
-if(!"name" in w9)w9.name="w9"
-$desc=$collectedClasses.w9
-if($desc instanceof Array)$desc=$desc[1]
-w9.prototype=$desc
-function w10(){}w10.builtin$cls="w10"
-if(!"name" in w10)w10.name="w10"
-$desc=$collectedClasses.w10
-if($desc instanceof Array)$desc=$desc[1]
-w10.prototype=$desc
 function c4(a){this.a=a}c4.builtin$cls="c4"
 if(!"name" in c4)c4.name="c4"
 $desc=$collectedClasses.c4
@@ -30580,14 +30876,14 @@
 if($desc instanceof Array)$desc=$desc[1]
 z6.prototype=$desc
 z6.prototype.geT=function(receiver){return this.eT}
-function dE(bO,Lv){this.bO=bO
-this.Lv=Lv}dE.builtin$cls="dE"
-if(!"name" in dE)dE.name="dE"
-$desc=$collectedClasses.dE
+function Mb(bO,Lv){this.bO=bO
+this.Lv=Lv}Mb.builtin$cls="Mb"
+if(!"name" in Mb)Mb.name="Mb"
+$desc=$collectedClasses.Mb
 if($desc instanceof Array)$desc=$desc[1]
-dE.prototype=$desc
-dE.prototype.sbO=function(v){return this.bO=v}
-dE.prototype.gLv=function(){return this.Lv}
+Mb.prototype=$desc
+Mb.prototype.sbO=function(v){return this.bO=v}
+Mb.prototype.gLv=function(){return this.Lv}
 function Ed(Jd){this.Jd=Jd}Ed.builtin$cls="Ed"
 if(!"name" in Ed)Ed.name="Ed"
 $desc=$collectedClasses.Ed
@@ -30643,19 +30939,19 @@
 $desc=$collectedClasses.ID
 if($desc instanceof Array)$desc=$desc[1]
 ID.prototype=$desc
-function jV(G3,v4,KL,bO,tj,Lv,k6){this.G3=G3
+function qR(G3,v4,KL,bO,tj,Lv,k6){this.G3=G3
 this.v4=v4
 this.KL=KL
 this.bO=bO
 this.tj=tj
 this.Lv=Lv
-this.k6=k6}jV.builtin$cls="jV"
-if(!"name" in jV)jV.name="jV"
-$desc=$collectedClasses.jV
+this.k6=k6}qR.builtin$cls="qR"
+if(!"name" in qR)qR.name="qR"
+$desc=$collectedClasses.qR
 if($desc instanceof Array)$desc=$desc[1]
-jV.prototype=$desc
-jV.prototype.gG3=function(receiver){return this.G3}
-jV.prototype.gv4=function(){return this.v4}
+qR.prototype=$desc
+qR.prototype.gG3=function(receiver){return this.G3}
+qR.prototype.gv4=function(){return this.v4}
 function ek(KL,bO,tj,Lv,k6){this.KL=KL
 this.bO=bO
 this.tj=tj
@@ -30677,17 +30973,17 @@
 $desc=$collectedClasses.Xm
 if($desc instanceof Array)$desc=$desc[1]
 Xm.prototype=$desc
-function Jy(wz,KL,bO,tj,Lv,k6){this.wz=wz
+function mv(wz,KL,bO,tj,Lv,k6){this.wz=wz
 this.KL=KL
 this.bO=bO
 this.tj=tj
 this.Lv=Lv
-this.k6=k6}Jy.builtin$cls="Jy"
-if(!"name" in Jy)Jy.name="Jy"
-$desc=$collectedClasses.Jy
+this.k6=k6}mv.builtin$cls="mv"
+if(!"name" in mv)mv.name="mv"
+$desc=$collectedClasses.mv
 if($desc instanceof Array)$desc=$desc[1]
-Jy.prototype=$desc
-Jy.prototype.gwz=function(){return this.wz}
+mv.prototype=$desc
+mv.prototype.gwz=function(){return this.wz}
 function mG(Bb,T8,KL,bO,tj,Lv,k6){this.Bb=Bb
 this.T8=T8
 this.KL=KL
@@ -30699,8 +30995,8 @@
 $desc=$collectedClasses.mG
 if($desc instanceof Array)$desc=$desc[1]
 mG.prototype=$desc
-mG.prototype.gBb=function(receiver){return this.Bb}
-mG.prototype.gT8=function(receiver){return this.T8}
+mG.prototype.gBb=function(){return this.Bb}
+mG.prototype.gT8=function(){return this.T8}
 function uA(a,b){this.a=a
 this.b=b}uA.builtin$cls="uA"
 if(!"name" in uA)uA.name="uA"
@@ -30796,8 +31092,8 @@
 $desc=$collectedClasses.VA
 if($desc instanceof Array)$desc=$desc[1]
 VA.prototype=$desc
-VA.prototype.gBb=function(receiver){return this.Bb}
-VA.prototype.gT8=function(receiver){return this.T8}
+VA.prototype.gBb=function(){return this.Bb}
+VA.prototype.gT8=function(){return this.T8}
 function J1(a,b){this.a=a
 this.b=b}J1.builtin$cls="J1"
 if(!"name" in J1)J1.name="J1"
@@ -30884,16 +31180,16 @@
 if($desc instanceof Array)$desc=$desc[1]
 uk.prototype=$desc
 uk.prototype.gkp=function(receiver){return this.kp}
-uk.prototype.gBb=function(receiver){return this.Bb}
-uk.prototype.gT8=function(receiver){return this.T8}
+uk.prototype.gBb=function(){return this.Bb}
+uk.prototype.gT8=function(){return this.T8}
 function K9(Bb,T8){this.Bb=Bb
 this.T8=T8}K9.builtin$cls="K9"
 if(!"name" in K9)K9.name="K9"
 $desc=$collectedClasses.K9
 if($desc instanceof Array)$desc=$desc[1]
 K9.prototype=$desc
-K9.prototype.gBb=function(receiver){return this.Bb}
-K9.prototype.gT8=function(receiver){return this.T8}
+K9.prototype.gBb=function(){return this.Bb}
+K9.prototype.gT8=function(){return this.T8}
 function zX(hP,Jn){this.hP=hP
 this.Jn=Jn}zX.builtin$cls="zX"
 if(!"name" in zX)zX.name="zX"
@@ -30910,24 +31206,24 @@
 x9.prototype=$desc
 x9.prototype.ghP=function(){return this.hP}
 x9.prototype.goc=function(receiver){return this.oc}
-function RW(hP,bP,re){this.hP=hP
+function Jy(hP,bP,re){this.hP=hP
 this.bP=bP
-this.re=re}RW.builtin$cls="RW"
-if(!"name" in RW)RW.name="RW"
-$desc=$collectedClasses.RW
+this.re=re}Jy.builtin$cls="Jy"
+if(!"name" in Jy)Jy.name="Jy"
+$desc=$collectedClasses.Jy
 if($desc instanceof Array)$desc=$desc[1]
-RW.prototype=$desc
-RW.prototype.ghP=function(){return this.hP}
-RW.prototype.gbP=function(receiver){return this.bP}
-RW.prototype.gre=function(){return this.re}
+Jy.prototype=$desc
+Jy.prototype.ghP=function(){return this.hP}
+Jy.prototype.gbP=function(receiver){return this.bP}
+Jy.prototype.gre=function(){return this.re}
 function xs(){}xs.builtin$cls="xs"
 if(!"name" in xs)xs.name="xs"
 $desc=$collectedClasses.xs
 if($desc instanceof Array)$desc=$desc[1]
 xs.prototype=$desc
-function FX(Sk,ks,ku,fL){this.Sk=Sk
-this.ks=ks
-this.ku=ku
+function FX(Sk,GP,qM,fL){this.Sk=Sk
+this.GP=GP
+this.qM=qM
 this.fL=fL}FX.builtin$cls="FX"
 if(!"name" in FX)FX.name="FX"
 $desc=$collectedClasses.FX
@@ -30965,10 +31261,10 @@
 Pn.prototype.gfY=function(receiver){return this.fY}
 Pn.prototype.gP=function(receiver){return this.P}
 Pn.prototype.gG8=function(){return this.G8}
-function hc(MV,zy,jI,x0){this.MV=MV
+function hc(MV,zy,jI,VQ){this.MV=MV
 this.zy=zy
 this.jI=jI
-this.x0=x0}hc.builtin$cls="hc"
+this.VQ=VQ}hc.builtin$cls="hc"
 if(!"name" in hc)hc.name="hc"
 $desc=$collectedClasses.hc
 if($desc instanceof Array)$desc=$desc[1]
@@ -30984,30 +31280,34 @@
 $desc=$collectedClasses.fr
 if($desc instanceof Array)$desc=$desc[1]
 fr.prototype=$desc
-function a0(){}a0.builtin$cls="a0"
-if(!"name" in a0)a0.name="a0"
-$desc=$collectedClasses.a0
+function cfS(){}cfS.builtin$cls="cfS"
+if(!"name" in cfS)cfS.name="cfS"
+$desc=$collectedClasses.cfS
 if($desc instanceof Array)$desc=$desc[1]
-a0.prototype=$desc
-function NQ(hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.hm=hm
+cfS.prototype=$desc
+function JG(hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.hm=hm
 this.AP=AP
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}NQ.builtin$cls="NQ"
-if(!"name" in NQ)NQ.name="NQ"
-$desc=$collectedClasses.NQ
+this.X0=X0}JG.builtin$cls="JG"
+if(!"name" in JG)JG.name="JG"
+$desc=$collectedClasses.JG
 if($desc instanceof Array)$desc=$desc[1]
-NQ.prototype=$desc
-function knI(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+JG.prototype=$desc
+function knI(zw,AP,fn,tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.zw=zw
+this.AP=AP
+this.fn=fn
+this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31015,19 +31315,28 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}knI.builtin$cls="knI"
+this.X0=X0}knI.builtin$cls="knI"
 if(!"name" in knI)knI.name="knI"
 $desc=$collectedClasses.knI
 if($desc instanceof Array)$desc=$desc[1]
 knI.prototype=$desc
-function fI(Uz,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Uz=Uz
+knI.prototype.gzw=function(receiver){return receiver.zw}
+knI.prototype.gzw.$reflectable=1
+knI.prototype.szw=function(receiver,v){return receiver.zw=v}
+knI.prototype.szw.$reflectable=1
+function qe(){}qe.builtin$cls="qe"
+if(!"name" in qe)qe.name="qe"
+$desc=$collectedClasses.qe
+if($desc instanceof Array)$desc=$desc[1]
+qe.prototype=$desc
+function fI(Uz,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Uz=Uz
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31035,14 +31344,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}fI.builtin$cls="fI"
+this.X0=X0}fI.builtin$cls="fI"
 if(!"name" in fI)fI.name="fI"
 $desc=$collectedClasses.fI
 if($desc instanceof Array)$desc=$desc[1]
@@ -31051,11 +31360,11 @@
 fI.prototype.gUz.$reflectable=1
 fI.prototype.sUz=function(receiver,v){return receiver.Uz=v}
 fI.prototype.sUz.$reflectable=1
-function V12(){}V12.builtin$cls="V12"
-if(!"name" in V12)V12.name="V12"
-$desc=$collectedClasses.V12
+function V13(){}V13.builtin$cls="V13"
+if(!"name" in V13)V13.name="V13"
+$desc=$collectedClasses.V13
 if($desc instanceof Array)$desc=$desc[1]
-V12.prototype=$desc
+V13.prototype=$desc
 function qq(a,b){this.a=a
 this.b=b}qq.builtin$cls="qq"
 if(!"name" in qq)qq.name="qq"
@@ -31067,8 +31376,9 @@
 $desc=$collectedClasses.FC
 if($desc instanceof Array)$desc=$desc[1]
 FC.prototype=$desc
-function xI(tY,Pe,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.tY=tY
+function xI(tY,Pe,m0,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.tY=tY
 this.Pe=Pe
+this.m0=m0
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31076,14 +31386,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}xI.builtin$cls="xI"
+this.X0=X0}xI.builtin$cls="xI"
 if(!"name" in xI)xI.name="xI"
 $desc=$collectedClasses.xI
 if($desc instanceof Array)$desc=$desc[1]
@@ -31096,12 +31406,17 @@
 xI.prototype.gPe.$reflectable=1
 xI.prototype.sPe=function(receiver,v){return receiver.Pe=v}
 xI.prototype.sPe.$reflectable=1
+xI.prototype.gm0=function(receiver){return receiver.m0}
+xI.prototype.gm0.$reflectable=1
+xI.prototype.sm0=function(receiver,v){return receiver.m0=v}
+xI.prototype.sm0.$reflectable=1
 function Ds(){}Ds.builtin$cls="Ds"
 if(!"name" in Ds)Ds.name="Ds"
 $desc=$collectedClasses.Ds
 if($desc instanceof Array)$desc=$desc[1]
 Ds.prototype=$desc
-function nm(Va,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.Va=Va
+function nm(Va,Mt,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.Va=Va
+this.Mt=Mt
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31109,14 +31424,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}nm.builtin$cls="nm"
+this.X0=X0}nm.builtin$cls="nm"
 if(!"name" in nm)nm.name="nm"
 $desc=$collectedClasses.nm
 if($desc instanceof Array)$desc=$desc[1]
@@ -31125,12 +31440,16 @@
 nm.prototype.gVa.$reflectable=1
 nm.prototype.sVa=function(receiver,v){return receiver.Va=v}
 nm.prototype.sVa.$reflectable=1
-function V13(){}V13.builtin$cls="V13"
-if(!"name" in V13)V13.name="V13"
-$desc=$collectedClasses.V13
+nm.prototype.gMt=function(receiver){return receiver.Mt}
+nm.prototype.gMt.$reflectable=1
+nm.prototype.sMt=function(receiver,v){return receiver.Mt=v}
+nm.prototype.sMt.$reflectable=1
+function V14(){}V14.builtin$cls="V14"
+if(!"name" in V14)V14.name="V14"
+$desc=$collectedClasses.V14
 if($desc instanceof Array)$desc=$desc[1]
-V13.prototype=$desc
-function Vu(V4,AP,fn,hm,AP,fn,AP,fn,wV,Sa,Uk,oq,Wz,SO,B7,ZQ){this.V4=V4
+V14.prototype=$desc
+function Vu(V4,AP,fn,hm,AP,fn,AP,fn,dZ,Sa,Uk,oq,Wz,SO,B7,X0){this.V4=V4
 this.AP=AP
 this.fn=fn
 this.hm=hm
@@ -31138,14 +31457,14 @@
 this.fn=fn
 this.AP=AP
 this.fn=fn
-this.wV=wV
+this.dZ=dZ
 this.Sa=Sa
 this.Uk=Uk
 this.oq=oq
 this.Wz=Wz
 this.SO=SO
 this.B7=B7
-this.ZQ=ZQ}Vu.builtin$cls="Vu"
+this.X0=X0}Vu.builtin$cls="Vu"
 if(!"name" in Vu)Vu.name="Vu"
 $desc=$collectedClasses.Vu
 if($desc instanceof Array)$desc=$desc[1]
@@ -31154,11 +31473,21 @@
 Vu.prototype.gV4.$reflectable=1
 Vu.prototype.sV4=function(receiver,v){return receiver.V4=v}
 Vu.prototype.sV4.$reflectable=1
-function V14(){}V14.builtin$cls="V14"
-if(!"name" in V14)V14.name="V14"
-$desc=$collectedClasses.V14
+function V15(){}V15.builtin$cls="V15"
+if(!"name" in V15)V15.name="V15"
+$desc=$collectedClasses.V15
 if($desc instanceof Array)$desc=$desc[1]
-V14.prototype=$desc
+V15.prototype=$desc
+function At(a){this.a=a}At.builtin$cls="At"
+if(!"name" in At)At.name="At"
+$desc=$collectedClasses.At
+if($desc instanceof Array)$desc=$desc[1]
+At.prototype=$desc
+function Sb(){}Sb.builtin$cls="Sb"
+if(!"name" in Sb)Sb.name="Sb"
+$desc=$collectedClasses.Sb
+if($desc instanceof Array)$desc=$desc[1]
+Sb.prototype=$desc
 function V2(N1,mD,Ck){this.N1=N1
 this.mD=mD
 this.Ck=Ck}V2.builtin$cls="V2"
@@ -31193,21 +31522,21 @@
 $desc=$collectedClasses.H2
 if($desc instanceof Array)$desc=$desc[1]
 H2.prototype=$desc
-function lP(){}lP.builtin$cls="lP"
-if(!"name" in lP)lP.name="lP"
-$desc=$collectedClasses.lP
+function YJ(){}YJ.builtin$cls="YJ"
+if(!"name" in YJ)YJ.name="YJ"
+$desc=$collectedClasses.YJ
 if($desc instanceof Array)$desc=$desc[1]
-lP.prototype=$desc
-function LfS(a){this.a=a}LfS.builtin$cls="LfS"
-if(!"name" in LfS)LfS.name="LfS"
-$desc=$collectedClasses.LfS
-if($desc instanceof Array)$desc=$desc[1]
-LfS.prototype=$desc
-function fTP(b){this.b=b}fTP.builtin$cls="fTP"
+YJ.prototype=$desc
+function fTP(a){this.a=a}fTP.builtin$cls="fTP"
 if(!"name" in fTP)fTP.name="fTP"
 $desc=$collectedClasses.fTP
 if($desc instanceof Array)$desc=$desc[1]
 fTP.prototype=$desc
+function ppY(b){this.b=b}ppY.builtin$cls="ppY"
+if(!"name" in ppY)ppY.name="ppY"
+$desc=$collectedClasses.ppY
+if($desc instanceof Array)$desc=$desc[1]
+ppY.prototype=$desc
 function NP(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
 this.qP=qP
 this.ZY=ZY
@@ -31219,17 +31548,17 @@
 $desc=$collectedClasses.NP
 if($desc instanceof Array)$desc=$desc[1]
 NP.prototype=$desc
-function Vh(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
+function jt(Ca,qP,ZY,xS,PB,eS,ay){this.Ca=Ca
 this.qP=qP
 this.ZY=ZY
 this.xS=xS
 this.PB=PB
 this.eS=eS
-this.ay=ay}Vh.builtin$cls="Vh"
-if(!"name" in Vh)Vh.name="Vh"
-$desc=$collectedClasses.Vh
+this.ay=ay}jt.builtin$cls="jt"
+if(!"name" in jt)jt.name="jt"
+$desc=$collectedClasses.jt
 if($desc instanceof Array)$desc=$desc[1]
-Vh.prototype=$desc
+jt.prototype=$desc
 function r0(a){this.a=a}r0.builtin$cls="r0"
 if(!"name" in r0)r0.name="r0"
 $desc=$collectedClasses.r0
@@ -31304,10 +31633,10 @@
 $desc=$collectedClasses.ug
 if($desc instanceof Array)$desc=$desc[1]
 ug.prototype=$desc
-function DT(lr,xT,kr,Ds,QO,jH,mj,IT,dv,N1,mD,Ck){this.lr=lr
+function DT(lr,xT,kr,Mf,QO,jH,mj,IT,dv,N1,mD,Ck){this.lr=lr
 this.xT=xT
 this.kr=kr
-this.Ds=Ds
+this.Mf=Mf
 this.QO=QO
 this.jH=jH
 this.mj=mj
@@ -31332,11 +31661,11 @@
 $desc=$collectedClasses.OB
 if($desc instanceof Array)$desc=$desc[1]
 OB.prototype=$desc
-function Uf(){}Uf.builtin$cls="Uf"
-if(!"name" in Uf)Uf.name="Uf"
-$desc=$collectedClasses.Uf
+function DO(){}DO.builtin$cls="DO"
+if(!"name" in DO)DO.name="DO"
+$desc=$collectedClasses.DO
 if($desc instanceof Array)$desc=$desc[1]
-Uf.prototype=$desc
+DO.prototype=$desc
 function p8(ud,lr,eS,ay){this.ud=ud
 this.lr=lr
 this.eS=eS
@@ -31446,4 +31775,4 @@
 $desc=$collectedClasses.VD
 if($desc instanceof Array)$desc=$desc[1]
 VD.prototype=$desc
-return[qE,SV,Gh,rK,fY,Mr,zx,P2,Xk,W2,zJ,Az,QP,QW,n6,Nu,OM,QQ,BR,wT,d7,na,oJ,DG,vz,bY,n0,Em,rD,rV,K4,QF,hN,SL,rv,Nh,ac,cv,Fs,Ty,ea,D0,as,hH,QU,u5,Yu,W4,jP,Cz,tA,Cv,Uq,QH,So,X2,zU,wa,tX,Sg,pA,Mi,Gt,ttH,wP,eP,mF,Qj,cS,M6,El,zm,Y7,aB,fJ,BK,Rv,HO,rC,ZY,DD,la,Qb,PG,xe,Hw,bn,tH,oB,Aj,H9,o4,oU,ih,uH,yk,KY,G7,l9,Ql,Xp,bP,FH,SN,HD,ni,jg,qj,nC,KR,ew,fs,LY,BL,fe,By,j2,X4,lp,kd,I0,QR,Cp,Ta,Hd,Ul,G5,wb,fq,h4,qk,GI,Tb,tV,BT,yY,kJ,AE,xV,Dn,y6,RH,pU,OJ,Mf,dp,r4,aG,J6,u9,Bn,UL,rq,I1,kc,AK,dM,Nf,F2,VB,QV,Zv,Q7,hF,hr,Dh,ZJ,mU,NE,Fl,y5,jQ,Kg,ui,vO,DQ,Sm,LM,es,eG,lv,pf,NV,W1,HC,kK,hq,bb,NdT,lc,Xu,qM,tk,me,bO,nh,EI,MI,ca,zt,eW,kL,Fu,OE,N9,BA,zp,br,PIw,PQ,Jq,Yd,kN,lZ,Gr,XE,GH,Lx,NJ,Ue,vt,rQ,Lu,LR,GN,hy,mq,Ke,CG,Xe,y0,Rk4,Eo,tL,pyk,ZD,Rlr,wD,Wv,yz,Fi,Qr,zI,cB,uY,yR,GK,xJ,oI,Et,NC,nb,Zn,xt,tG,P0,xlX,SQ,qD,TM,I2,HY,Kq,Nn,Un,rF,Sb,UZ,yc,Aw,jx,F0,Lt,Gv,kn,PE,QI,FP,is,Q,NK,ZC,Jt,P,im,GW,vT,VP,BQ,O,Qe,PK,JO,f0,aX,cC,RA,IY,JH,jl,Iy4,Z6,Ua,ns,yo,Rd,Bj,NO,II,fP,X1,HU,oo,OW,hz,AP,yH,FA,Av,Zd,xQ,Q9,oH,LPe,bw,WT,jJ,XR,LI,Ny,IW,F3,FD,Cj,u8,Zr,W0,az,vV,Am,XO,dr,TL,KX,uZ,OQ,Tp,Bp,v,Ll,dN,GT,Pe,Eq,lb,tD,hJ,tu,fw,Zz,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,G6,Vf,kf,Ps,pv,CN,vc,Vfx,i6,Dsd,wJ,aL,nH,a7,i1,xy,MH,A8,U5,SO,kV,rR,H6,d5,U1,SJ,SU7,JJ,Iy,iK,GD,Sn,nI,TY,Lj,mb,mZ,cw,EE,Uz,NZ,IB,oP,YX,BI,vk,M2,iu,mg,bl,tB,Oo,Tc,Ax,Wf,HZT,Ei,U7,t0,Ld,Sz,Zk,fu,ng,TN,Ar,rh,jB,ye,O1,Oh,Xh,Ca,Ik,JI,Ks,dz,tK,OR,Bg,DL,b8,Ia,Zf,vs,da,xw,dm,rH,ZL,mi,jb,wB,Pu,qh,YJ,jv,LB,DO,lz,Rl,Jb,M4,Jp,h7,pr,eN,PI,uO,j4,i9,VV,Dy,lU,OC,UH,Z5,ii,ib,MO,ms,UO,Bc,vp,lk,q1,ZzD,ly,fE,O9,yU,nP,KA,Vo,qB,ez,lx,LV,DS,JF,ht,CR,Qk,dR,uR,QX,YR,fB,nO,t3,dq,tU,aY,zG,e4,JB,Id,WH,TF,K5,Cg,Hs,dv,pV,cc,pK,eM,Uez,W5,R8,k6,oi,ce,DJ,PL,Fq,jG,fG,EQ,YB,a1,ou,S9,ey,xd,v6,db,i5,N6,Rr,YO,oz,b6,ef,zQ,Yp,lN,mW,ar,lD,ZQ,Sw,o0,qv,jp,vX,Ba,An,bF,LD,S6B,OG,uM,DN,ZM,HW,JC,f1,Uk,wI,Zi,Ud,K8,by,pD,Cf,Sh,tF,z0,E3,Rw,GY,jZ,HB,CL,p4,a2,fR,iP,MF,Rq,Hn,Zl,B5,a6,P7,DW,Ge,LK,AT,bJ,Np,mp,ub,ds,lj,UV,VS,t7,HG,aE,eV,kM,EH,cX,Yl,Z0,L9,a,Od,MN,WU,Rn,wv,uq,iD,In,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,Mx,C9,kZ,JT,d9,rI,QZ,BV,E1,VG,wz,B1,M5,Jn,DM,RAp,ma,Kx,iO,bU,Yg,e7,nNL,ecX,kI,yoo,w1p,tJ,Zc,i7,nF,FK,Si,vf,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,hP,Gm,W9,vZ,dW,Dk,O7,E4,Xb,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,ej,NL,vr,D4,X9,Ms,tg,RS,RY,Ys,WS4,A2,U4,B8q,Nx,ue,GG,Y8,Bk,iY,C0A,RAK,FvP,tuj,Ir,Vct,m8,jM,D13,DKl,mk,WZq,NM,pva,bd,LS,aI,rG,yh,wO,Tm,rz,CA,YL,KC,xL,Ay,GE,rl,uQ,D7,hT,GS,pR,hx,cda,u7,fW,E7,waa,RR,EL,St,V0,vj,V4,LU,CX,V6,TJ,dG,qV,HV,em,Lb,PF,fA,tz,jA,Jo,c5,qT,Xd,V10,mL,Kf,qu,bv,eS,IQ,TI,pt,Ub,dY,vY,zZ,dS,dZ,us,DP,WAE,N8,kx,CM,xn,ct,hM,vu,Ja,c2,rj,R2,Q4,aJ,u4,pF,Q2,tb,Rb,F1,V11,uL,LP,Pi,z2,qI,J3,E5,o5,b5,u3,Zb,id,iV,DA,nd,vly,d3,X6,xh,wn,uF,cj,HA,qC,zT,Lo,WR,qL,Px,C4,Md,km,lI,u2,q7,Qt,No,v5,OO,OF,rM,IV,Zj,XP,q6,CK,LJ,ZG,Oc,MX,w11,ppY,yL,zs,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,Sa,Ao,k8,HJ,S0,V3,Bl,Fn,e3,pM,jh,W6,Lf,fT,pp,Nq,nl,mf,ik,HK,o8,ex,e9,Xy,uK,mY,GX,mB,XF,iH,Ra,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,w9,w10,c4,z6,dE,Ed,G1,Os,B8,Wh,x5,ev,ID,jV,ek,Qv,Xm,Jy,mG,uA,vl,Li,WK,iT,ja,zw,fa,WW,vQ,a9,VA,J1,fk,wL,B0,tc,hw,EZ,no,kB,ae,XC,w6,jK,uk,K9,zX,x9,RW,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,a0,NQ,knI,fI,V12,qq,FC,xI,Ds,nm,V13,Vu,V14,V2,D8,jY,H2,lP,LfS,fTP,NP,Vh,r0,jz,SA,hB,nv,ee,XI,hs,yp,ug,DT,OB,Uf,p8,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,wl,T4,TR,VD]}
\ No newline at end of file
+return[qE,SV,Gh,A0,na,Mr,zx,P2,Xk,W2,it,Az,QP,QW,jr,Ny,nx,QQ,BR,di,d7,yJ,He,vz,vHT,n0,Em,pt,rV,K4,QF,Aj,cm,Nh,wj,cv,Fs,Ty,ea,D0,as,hH,Aa,u5,h4,W4,jP,Hd,tA,wa,Uq,QH,Rt,X2,zU,pk,tX,Sg,pA,Mi,Gt,In,wP,eP,mF,Qj,cS,YI,El,zm,Y7,aB,fJ,BK,Rv,HO,Kk,ZY,DD,EeC,Qb,PG,xe,Hw,bn,Imr,Ve,Oq,H9,o4,oU,ih,KV,yk,KY,G7,l9,Ql,Xp,bP,FH,iL,HD,ni,jg,qj,nC,KR,ew,fs,LY,BL,fe,By,j2,X4,lp,pD,I0,QR,Cp,Ta,zD9,Ul,G5,bk,fq,Er,qk,GI,Tb,tV,BT,yY,kJ,AE,xV,Dn,y6,RH,ho,OJ,Mf,dp,vw,aG,J6,u9,Bn,hq,UL,tZ,kc,AK,ty,Nf,F2,VB,QV,Zv,Q7,hF,OF,Dh,ZJ,mU,NE,lC,y5,jQ,Kg,ui,mk,DQ,Sm,LM,es,eG,lv,pf,NV,W1,mCz,kK,n5,bb,NdT,lc,Xu,qM,tk,me,oB,nh,EI,MI,ca,um,eW,kL,Fu,QN,N9,BA,d0,zp,br,PIw,vd,Jq,Yd,kN,lZ,Gr,XE,GH,lo,NJ,Ue,vt,rQ,Lx,LR,d5,hy,mq,Ke,CG,Xe,y0,Rk4,Eo,tL,pyk,ZD,rD,wD,Wv,yz,Fi,Ja,mj,cB,Mh,yR,GK,xJ,Nn,Et,NC,nb,Zn,xt,wx,P0,xlX,SQ,qD,TM,WZ,rn,df,Hg,L3,xj,dE,Eb,dT,N2,eE,V6,Lt,Gv,kn,ht,QI,FP,is,Q,nM,ZC,Jt,P,im,GW,vT,VP,BQ,O,PK,JO,f0,aX,cC,RA,IY,JH,jl,Iy,Z6,Ua,ns,yo,NA,NO,II,fP,X1,HU,oo,OW,hz,iY,yH,FA,Av,ku,Zd,xQ,F0,oH,LPe,bw,WT,jJ,XR,LI,A2,IW,F3,FD,Cj,u8,Zr,W0,az,vV,Am,XO,dr,TL,KX,uZ,OQ,Tp,Bp,v,Ll,dN,GT,Pe,Eq,lb,tD,hJ,tu,fw,Zz,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,G6,Vf,Tg,Ps,pv,CN,vc,Vfx,i6,Dsd,wJ,aL,nH,a7,i1,xy,MH,A8,U5,SO,kV,rR,H6,wB,U1,SJ,SU7,Qr,w2Y,iK,GD,Sn,nI,TY,Lj,mb,am,cw,EE,Uz,uh,IB,oP,YX,BI,Un,M2,iu,mg,bl,tB,Oo,Tc,Ax,Wf,vk,Ei,U7,t0,Ld,Sz,Zk,fu,wt,ng,TN,Ar,rh,jB,ye,O1,Oh,Xh,Ca,Ik,JI,Ks,dz,tK,OR,Bg,DL,b8,Ia,Zf,vs,da,xw,dm,rH,ZL,rq,RW,RT,jZ,FZ,OM,qh,tG,jv,LB,zn,lz,Rl,Jb,M4,Jp,h7,pr,eN,PI,uO,j4,i9,VV,Dy,lU,OC,UH,Z5,ii,ib,MO,O9,oh,nP,KA,Vo,qB,ez,lx,LV,DS,JF,Je,CR,Qk,v1y,uR,Q0,YR,fB,nO,t3,dq,lO,aY,zG,e4,JB,Id,WH,TF,K5,Cg,Hs,dv,pV,uo,pK,eM,Uez,nU,R8,k6,oi,ce,DJ,PL,Fq,jG,fG,EQ,YB,a1,ou,S9,ey,xd,v6,db,i5,N6,Rr,YO,oz,b6,ef,zQ,Yp,lN,mW,ar,lD,ZQ,Sw,o0,qv,jp,vX,Ba,An,bF,LD,S6B,OG,uM,DN,ZM,HW,JC,f1,Uk,wI,Zi,Ud,K8,by,dI,Cf,Sh,tF,z0,E3,Rw,HB,CL,p4,a2,fR,iP,MF,Rq,Hn,Zl,B5,a6,P7,DW,Ge,LK,AT,bJ,Np,mp,ub,ds,lj,UV,VS,t7,HG,aE,eV,kM,EH,cX,Yl,Z0,L9,a,Od,MN,WU,Rn,wv,uq,iD,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,Mx,C9,kZ,JT,d9,rI,QZ,VG,wz,B1,M5,Jn,DM,RAp,Gb,Kx,iO,bU,Yg,e7,nNL,ecX,kI,yoo,w1p,tJ,Zc,i7,nF,FK,Si,vf,Iw,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,bO,Gm,Of,Qg,W9,vZ,dW,Dk,O7,IU,E4,Gn,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,ej,NL,vr,D4,X9,Ms,ac,RS,RY,Ys,WS4,Gj,U4,B8q,Nx,LZ,Dg,Ob,Ip,Pg,Nb,nA,Fv,tuj,E9,Vct,m8,Gk,D13,GG,yb,WZq,NM,pva,bd,LS,aI,rG,yh,wO,Tm,q1,CA,YL,KC,xL,As,GE,rl,uQ,D7,hT,GS,pR,T5,YE,we,hx,cda,u7,fW,qm,vO,E7,waa,RR,EL,St,V0,vj,V4,LU,T2,V10,TJ,dG,qV,HV,em,Lb,PF,fA,tz,jA,PO,c5,qT,Xd,V11,mL,Kf,qu,bv,eS,IQ,TI,yU,Ub,dY,vY,zZ,dS,dZ,Qe,DP,WAE,N8,Vi,kx,fx,CM,xn,vu,c2,rj,Nu,Q4,aJ,u4,pF,Q2,r1,Rb,Y2,XN,F1,V12,uL,LP,Pi,z2,qI,J3,E5,o5,b5,zI,Zb,id,iV,DA,nd,vly,d3,lS,xh,wn,Ay,Bj,HA,qC,zT,Lo,WR,qL,Px,C4,Md,km,Zj,XP,q6,CK,LJ,ZG,Oc,MX,w9,r3y,yL,zs,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,jpR,GN,bS,HJ,S0,V3,Bl,Fn,e3,pM,jh,W6,Lf,fT,pp,nl,ik,mf,LfS,HK,o8,ex,e9,Xy,G0,mY,GX,mB,XF,bX,lP,Uf,Ra,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,c4,z6,Mb,Ed,G1,Os,B8,Wh,x5,ev,ID,qR,ek,Qv,Xm,mv,mG,uA,vl,Li,WK,iT,ja,zw,fa,WW,vQ,a9,VA,J1,fk,wL,B0,tc,hw,EZ,no,kB,ae,XC,w6,jK,uk,K9,zX,x9,Jy,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,cfS,JG,knI,qe,fI,V13,qq,FC,xI,Ds,nm,V14,Vu,V15,At,Sb,V2,D8,jY,H2,YJ,fTP,ppY,NP,jt,r0,jz,SA,hB,nv,ee,XI,hs,yp,ug,DT,OB,DO,p8,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,wl,T4,TR,VD]}
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/observatory.dart b/runtime/bin/vmservice/client/lib/observatory.dart
index 8233fd3..f82d9af 100644
--- a/runtime/bin/vmservice/client/lib/observatory.dart
+++ b/runtime/bin/vmservice/client/lib/observatory.dart
@@ -15,3 +15,4 @@
 part 'src/observatory/location_manager.dart';
 part 'src/observatory/model.dart';
 part 'src/observatory/request_manager.dart';
+part 'src/observatory/view_model.dart';
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart b/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart
index d17700b..08c4da9 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart
@@ -8,7 +8,7 @@
 /// State for a running isolate.
 class Isolate extends Observable {
   static ObservatoryApplication _application;
-  
+
   @observable Profile profile;
   @observable final Map<String, Script> scripts =
       toObservable(new Map<String, Script>());
@@ -25,9 +25,9 @@
 
   @observable Map topFrame = null;
   @observable String fileAndLine = null;
-  
+
   Isolate.fromId(this.id) : name = '' {}
-  
+
   Isolate.fromMap(Map map)
       : id = map['id'], name = map['name'] {
   }
@@ -40,7 +40,7 @@
           Logger.root.severe('Error while updating isolate summary: $e\n$trace');
       });
   }
-  
+
   void update(Map map) {
     if (map['type'] != 'Isolate') {
       Logger.root.severe('Unexpected message type in Isolate.update: ${map["type"]}');
@@ -66,7 +66,6 @@
     map['timers'].forEach((timer) {
         timerMap[timer['name']] = timer['time'];
       });
-    print(timerMap);
     timers['total'] = timerMap['time_total_runtime'];
     timers['compile'] = timerMap['time_compilation'];
     timers['gc'] = 0.0;  // TODO(turnidge): Export this from VM.
@@ -88,6 +87,7 @@
         return codes[i];
       }
     }
+    return null;
   }
 
   Code findCodeByName(String name) {
@@ -96,6 +96,7 @@
         return codes[i];
       }
     }
+    return null;
   }
 
   void resetCodeTicks() {
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/model.dart b/runtime/bin/vmservice/client/lib/src/observatory/model.dart
index 9ecfbe9..4a6f3e4 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/model.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/model.dart
@@ -55,8 +55,15 @@
 
 class CodeTick {
   final int address;
-  final int ticks;
-  CodeTick(this.address, this.ticks);
+  final int exclusive_ticks;
+  final int inclusive_ticks;
+  CodeTick(this.address, this.exclusive_ticks, this.inclusive_ticks);
+}
+
+class CodeCallCount {
+  final Code code;
+  final int count;
+  CodeCallCount(this.code, this.count);
 }
 
 class Code extends Observable {
@@ -64,30 +71,143 @@
   final int startAddress;
   final int endAddress;
   final List<CodeTick> ticks = [];
+  final List<CodeCallCount> callers = [];
+  final List<CodeCallCount> callees = [];
   int inclusiveTicks = 0;
   int exclusiveTicks = 0;
   @observable final List<CodeInstruction> instructions = toObservable([]);
   @observable Map functionRef = toObservable({});
   @observable Map codeRef = toObservable({});
   @observable String name;
-  @observable String user_name;
+  @observable String userName;
 
   Code(this.kind, this.name, this.startAddress, this.endAddress);
 
-  Code.fromMap(Map m) :
+  Code.fromMap(Map map) :
     kind = CodeKind.Dart,
-    startAddress = int.parse(m['start'], radix:16),
-    endAddress = int.parse(m['end'], radix:16) {
-    functionRef = toObservable(m['function']);
-    codeRef = {
+    startAddress = int.parse(map['start'], radix: 16),
+    endAddress = int.parse(map['end'], radix: 16) {
+    functionRef = toObservable(map['function']);
+    codeRef = toObservable({
       'type': '@Code',
-      'id': m['id'],
-      'name': m['name'],
-      'user_name': m['user_name']
-    };
-    name = m['name'];
-    user_name = m['user_name'];
-    _loadInstructions(m['disassembly']);
+      'id': map['id'],
+      'name': map['name'],
+      'user_name': map['user_name']
+    });
+    name = map['name'];
+    userName = map['user_name'];
+    if (map['disassembly'] != null) {
+      _loadInstructions(map['disassembly']);
+    }
+  }
+
+  factory Code.fromProfileMap(Map map) {
+    var kind = CodeKind.fromString(map['kind']);
+    var startAddress;
+    var endAddress;
+    var name;
+    var userName;
+    var codeRef;
+    var functionRef;
+    // Initial extraction of startAddress, endAddress, and name depends on what
+    // kind of code this is and whether or not the code has been collected.
+    if (kind == CodeKind.Dart) {
+      var code = map['code'];
+      if (code != null) {
+        // Extract from Dart code.
+        startAddress = int.parse(code['start'], radix:16);
+        endAddress = int.parse(code['end'], radix:16);
+        name = code['name'];
+        userName = code['user_name'];
+        codeRef = toObservable({
+          'type': '@Code',
+          'id': code['id'],
+          'name': name,
+          'user_name': userName
+        });
+        functionRef = toObservable(code['function']);
+      }
+    }
+    if (startAddress == null) {
+      // Extract from Profile code.
+      // This is either a native or collected piece of code.
+      startAddress = int.parse(map['start'], radix:16);
+      endAddress = int.parse(map['end'], radix: 16);
+      name = map['name'];
+      userName = name;
+    }
+    var code = new Code(kind, name, startAddress, endAddress);
+    code.codeRef = codeRef;
+    code.functionRef = functionRef;
+    code.userName = userName;
+    if (map['disassembly'] != null) {
+      code._loadInstructions(map['disassembly']);
+    }
+    return code;
+  }
+
+  // Refresh tick counts, etc for a code object.
+  void _refresh(Map map) {
+    inclusiveTicks = int.parse(map['inclusive_ticks']);
+    exclusiveTicks = int.parse(map['exclusive_ticks']);
+    // Load address ticks.
+    var ticksList = map['ticks'];
+    if ((ticksList != null) && (ticksList.length > 0)) {
+      assert((ticks.length % 3) == 0);
+      for (var i = 0; i < ticksList.length; i += 3) {
+        var address = int.parse(ticksList[i], radix:16);
+        var inclusive_ticks = int.parse(ticksList[i + 1]);
+        var exclusive_ticks = int.parse(ticksList[i + 2]);
+        var codeTick = new CodeTick(address, exclusive_ticks, inclusive_ticks);
+        ticks.add(codeTick);
+      }
+    }
+  }
+
+  /// Sum all caller counts.
+  int sumCallersCount() => _sumCallCount(callers);
+  /// Specific caller count.
+  int callersCount(Code code) => _callCount(callers, code);
+  /// Sum of callees count.
+  int sumCalleesCount() => _sumCallCount(callees);
+  /// Specific callee count.
+  int calleesCount(Code code) => _callCount(callees, code);
+
+  int _sumCallCount(List<CodeCallCount> calls) {
+    var sum = 0;
+    for (CodeCallCount caller in calls) {
+      sum += caller.count;
+    }
+    return sum;
+  }
+
+  int _callCount(List<CodeCallCount> calls, Code code) {
+    for (CodeCallCount caller in calls) {
+      if (caller.code == code) {
+        return caller.count;
+      }
+    }
+    return 0;
+  }
+
+  void resolveCalls(Map code, List<Code> codes) {
+    _resolveCalls(callers, code['callers'], codes);
+    _resolveCalls(callees, code['callees'], codes);
+  }
+
+  void _resolveCalls(List<CodeCallCount> calls, List data, List<Code> codes) {
+    // Clear.
+    calls.clear();
+    // Resolve.
+    for (var i = 0; i < data.length; i += 2) {
+      var index = int.parse(data[i]);
+      var count = int.parse(data[i + 1]);
+      assert(index >= 0);
+      assert(index < codes.length);
+      calls.add(new CodeCallCount(codes[index], count));
+    }
+    // Sort to descending count order.
+    calls.sort((a, b) => b.count - a.count);
   }
 
   /// Resets all tick counts to 0.
@@ -136,12 +256,16 @@
 
 class Profile {
   final Isolate isolate;
+  final List<Code> _codeObjectsInImportOrder = new List<Code>();
+  int totalSamples = 0;
+
   Profile.fromMap(this.isolate, Map m) {
     var codes = m['codes'];
     totalSamples = m['samples'];
     Logger.root.info('Creating profile from ${totalSamples} samples '
                      'and ${codes.length} code objects.');
     isolate.resetCodeTicks();
+    _codeObjectsInImportOrder.clear();
     codes.forEach((code) {
       try {
         _processCode(code);
@@ -149,77 +273,39 @@
         Logger.root.warning('Error processing code object. $e $st', e, st);
       }
     });
-  }
-  int totalSamples = 0;
-
-  Code _processDartCode(Map dartCode) {
-    var codeObject = dartCode['code'];
-    if ((codeObject == null)) {
-      // Detached code objects are handled like 'other' code.
-      return _processOtherCode(CodeKind.Dart, dartCode);
+    // Now that code objects have been loaded, post-process them
+    // and resolve callers and callees.
+    assert(_codeObjectsInImportOrder.length == codes.length);
+    for (var i = 0; i < codes.length; i++) {
+      Code code = _codeObjectsInImportOrder[i];
+      code.resolveCalls(codes[i], _codeObjectsInImportOrder);
     }
-    var code = new Code.fromMap(codeObject);
-    return code;
+    _codeObjectsInImportOrder.clear();
   }
 
-  Code _processOtherCode(CodeKind kind, Map otherCode) {
-    var startAddress = int.parse(otherCode['start'], radix:16);
-    var endAddress = int.parse(otherCode['end'], radix: 16);
-    var name = otherCode['name'];
-    assert(name != null);
-    return new Code(kind, name, startAddress, endAddress);
+  int _extractCodeStartAddress(Map code) {
+    var kind = CodeKind.fromString(code['kind']);
+    if ((kind == CodeKind.Dart) && (code['code'] != null)) {
+      // Start address is inside the dart code map.
+      return int.parse(code['code']['start'], radix:16);
+    }
+    // Start address is inside the profile code map.
+    return int.parse(code['start'], radix:16);
   }
 
   void _processCode(Map profileCode) {
     if (profileCode['type'] != 'ProfileCode') {
       return;
     }
-    var kind = CodeKind.fromString(profileCode['kind']);
-    var address;
-    if (kind == CodeKind.Dart) {
-      if (profileCode['code'] != null) {
-        address = int.parse(profileCode['code']['start'], radix:16);
-      } else {
-        address = int.parse(profileCode['start'], radix:16);
-      }
-    } else {
-      address = int.parse(profileCode['start'], radix:16);
-    }
-    assert(address != null);
+    int address = _extractCodeStartAddress(profileCode);
     var code = isolate.findCodeByAddress(address);
     if (code == null) {
-      if (kind == CodeKind.Dart) {
-        code = _processDartCode(profileCode);
-      } else {
-        code = _processOtherCode(kind, profileCode);
-      }
-      assert(code != null);
+      // Never seen a code object at this address before, create a new one.
+      code = new Code.fromProfileMap(profileCode);
       isolate.codes.add(code);
     }
-    // Load code object tick counts and set them.
-    var inclusive = int.parse(profileCode['inclusive_ticks']);
-    var exclusive = int.parse(profileCode['exclusive_ticks']);
-    code.inclusiveTicks = inclusive;
-    code.exclusiveTicks = exclusive;
-    // Load address specific ticks.
-    List ticksList = profileCode['ticks'];
-    if (ticksList != null && (ticksList.length > 0)) {
-      for (var i = 0; i < ticksList.length; i += 2) {
-        var address = int.parse(ticksList[i], radix:16);
-        var ticks = int.parse(ticksList[i + 1]);
-        var codeTick = new CodeTick(address, ticks);
-        code.ticks.add(codeTick);
-      }
-    }
-    if ((code.ticks.length > 0) && (code.instructions.length > 0)) {
-      // Apply address ticks to instruction stream.
-      code.ticks.forEach((CodeTick tick) {
-        code.tick(tick.address, tick.ticks);
-      });
-      code.instructions.forEach((i) {
-        i.updateTickString(code);
-      });
-    }
+    code._refresh(profileCode);
+    _codeObjectsInImportOrder.add(code);
   }
 
   List<Code> topExclusive(int count) {
@@ -232,17 +318,6 @@
     }
     return exclusive.sublist(0, count);
   }
-
-  List<Code> topInclusive(int count) {
-    List<Code> inclusive = isolate.codes;
-    inclusive.sort((Code a, Code b) {
-      return b.inclusiveTicks - a.inclusiveTicks;
-    });
-    if ((inclusive.length < count) || (count == 0)) {
-      return inclusive;
-    }
-    return inclusive.sublist(0, count);
-  }
 }
 
 class ScriptLine extends Observable {
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart b/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
index 376aa1a..c90fe9b 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
@@ -233,6 +233,9 @@
   Future<String> request(String requestString);
 
   Future<Map> requestMap(String requestString) {
+    if (requestString.startsWith('#')) {
+      requestString = requestString.substring(1);
+    }
     return request(requestString).then((response) {
       try {
         var m = JSON.decode(response);
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/view_model.dart b/runtime/bin/vmservice/client/lib/src/observatory/view_model.dart
new file mode 100644
index 0000000..1fa12e6
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory/view_model.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of observatory;
+
+abstract class TableTreeRow extends Observable {
+  final TableTreeRow parent;
+  @observable final int depth;
+  @observable final List<TableTreeRow> children = new List<TableTreeRow>();
+  @observable final List<String> columns = [];
+
+  TableTreeRow(TableTreeRow parent) :
+      parent = parent,
+      depth = parent != null ? parent.depth+1 : 0;
+
+  bool _expanded = false;
+  bool get expanded => _expanded;
+  set expanded(bool expanded) {
+    var changed = _expanded != expanded;
+    _expanded = expanded;
+    if (changed) {
+      // If the state has changed, fire callbacks.
+      if (_expanded) {
+        onShow();
+      } else {
+        onHide();
+      }
+    }
+  }
+
+  bool toggle() {
+    expanded = !expanded;
+    return expanded;
+  }
+
+  /// Fired when the tree row is expanded. Add children rows here.
+  void onShow();
+
+  /// Fired when the tree row is collapsed.
+  void onHide();
+}
+
+class TableTree extends Observable {
+  final List<String> columnHeaders = [];
+  @observable final List<TableTreeRow> rows = toObservable([]);
+
+  /// Create a table tree with column [headers].
+  TableTree(List<String> headers) {
+    columnHeaders.addAll(headers);
+  }
+
+  /// Initialize the table tree with the list of root children.
+  void initialize(List<TableTreeRow> children) {
+    rows.clear();
+    rows.addAll(children);
+  }
+
+  /// Toggle expansion of row at [rowIndex].
+  void toggle(int rowIndex) {
+    assert(rowIndex >= 0);
+    assert(rowIndex < rows.length);
+    print(rowIndex);
+    print(rows.length);
+    var row = rows[rowIndex];
+    if (row.toggle()) {
+      _expand(row);
+    } else {
+      _collapse(row);
+    }
+    print('e');
+  }
+
+  int _index(TableTreeRow row) => rows.indexOf(row);
+
+  void _insertRow(int index, TableTreeRow row) {
+    if (index == -1) {
+      rows.add(row);
+    } else {
+      rows.insert(index, row);
+    }
+  }
+
+  void _expand(TableTreeRow row) {
+    int index = _index(row);
+    assert(index != -1);
+    for (var i = 0; i < row.children.length; i++) {
+      _insertRow(index + i + 1, row.children[i]);
+    }
+  }
+
+  void _collapse(TableTreeRow row) {
+    var childCount = row.children.length;
+    if (childCount == 0) {
+      return;
+    }
+    for (var i = 0; i < childCount; i++) {
+      // Close all inner rows.
+      if (row.children[i].expanded) {
+        _collapse(row.children[i]);
+      }
+    }
+    // Collapse this row.
+    row.expanded = false;
+    // Remove all children.
+    int index = _index(row);
+    for (var i = 0; i < childCount; i++) {
+      rows.removeAt(index + 1);
+    }
+  }
+}
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart
index db78b94..ca1b5bf 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart
@@ -4,7 +4,6 @@
 
 library heap_profile_element;
 
-import 'dart:async';
 import 'dart:html';
 import 'package:logging/logging.dart';
 import 'package:polymer/polymer.dart';
@@ -133,6 +132,7 @@
       case 8:
         return v['old'][LIVE_AFTER_GC_SIZE];
     }
+    return null;
   }
 
   void refreshData(Event e, var detail, Node target) {
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.dart
index 7f5368f..ec99c73 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.dart
@@ -4,6 +4,7 @@
 
 library instance_ref_element;
 
+import 'package:logging/logging.dart';
 import 'package:polymer/polymer.dart';
 import 'service_ref.dart';
 
@@ -11,10 +12,29 @@
 class InstanceRefElement extends ServiceRefElement {
   InstanceRefElement.created() : super.created();
 
+  @published bool expanded = false;
+
   String get name {
     if (ref == null) {
       return super.name;
     }
     return ref['preview'];
   }
-}
\ No newline at end of file
+
+  void toggleExpand(var a, var b, var c) {
+    if (expanded) {
+      ref['fields'] = null;
+      ref['elements'] = null;
+      expanded = false;
+    } else {
+      app.requestManager.requestMap(url).then((map) {
+          ref['fields'] = map['fields'];
+          ref['elements'] = map['elements'];
+          ref['length'] = map['length'];
+          expanded = true;
+      }).catchError((e, trace) {
+          Logger.root.severe('Error while expanding instance-ref: $e\n$trace');
+      });
+    }
+  }
+}
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.html
index ecf3f06..ce1ce3d 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_ref.html
@@ -1,20 +1,75 @@
 <head>
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="service_ref.html">
+  <link rel="import" href="observatory_element.html">
+  <link rel="import" href="service_ref.html">
 </head>
 <polymer-element name="instance-ref" extends="service-ref">
-<template>
-<div>
-  <template if="{{ (ref['type'] == 'null') }}">
-    unexpected null
+  <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
+    <div>
+      <template if="{{ isUnexpectedRef(ref['type']) }}">
+        unexpected reference type &lt;{{ ref['type'] }}&gt;
+      </template>
+
+      <template if="{{ isNullRef(ref['type']) }}">
+        {{ name }}
+      </template>
+
+      <template if="{{ (isStringRef(ref['type']) ||
+                        isBoolRef(ref['type']) ||
+                        isIntRef(ref['type'])) }}">
+        <a href="{{ url }}">{{ name }}</a>
+      </template>
+
+      <template if="{{ isClosureRef(ref['type']) }}">
+        <a href="{{ url }}">
+          {{ ref['closureFunc']['user_name'] }}
+        </a>
+      </template>
+
+      <template if="{{ isInstanceRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em></a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tr template repeat="{{ field in ref['fields'] }}">
+
+              <td class="member">{{ field['decl']['user_name'] }}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </table>
+        </template>
+        }
+      </template>
+
+      <template if="{{ isListRef(ref['type']) }}">
+        <a href="{{ url }}"><em>{{ ref['class']['user_name'] }}</em> ({{ ref['length']}})</a> {
+        <a on-click="{{ toggleExpand }}">...</a>
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tr template repeat="{{ element in ref['elements'] }}">
+              <td class="member">[{{ element['index']}}]</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ element['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </table>
+        </template>
+        }
+      </template>
+
+    </div>
   </template>
-  <template if="{{ (ref['type'] == '@Null') }}">
-    {{ name }}
-  </template>
-  <template if="{{ (ref['type'] != 'null') && ref['type'] != '@Null' }}">
-    <a href="{{ url }}">{{ name }} </a>
-  </template>
- </div>
-</template>
-<script type="application/dart" src="instance_ref.dart"></script>
+  <script type="application/dart" src="instance_ref.dart"></script>
 </polymer-element>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_view.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_view.html
index 09e8865..2b98ed2 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_view.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/instance_view.html
@@ -27,7 +27,7 @@
             <table class="table table-hover">
              <tbody>
                 <tr template repeat="{{ field in instance['fields'] }}">
-                  <td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
+                  <td><field-ref app="{{ app }}" ref="{{ field['decl'] }}"></field-ref></td>
                   <td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
                 </tr>
               </tbody>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart
index d271ec2..c5287a2 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart
@@ -6,17 +6,62 @@
 
 import 'dart:html';
 import 'package:logging/logging.dart';
+import 'package:observatory/observatory.dart';
 import 'package:polymer/polymer.dart';
 import 'observatory_element.dart';
 
+class ProfileCallerTreeRow extends TableTreeRow {
+  final Isolate isolate;
+  @observable final Code code;
+
+  static String formatPercent(num a, num total) {
+    var percent = 100.0 * (a / total);
+    return '${percent.toStringAsFixed(2)}%';
+  }
+
+  ProfileCallerTreeRow(this.isolate, this.code, ProfileCallerTreeRow parent) :
+      super(parent) {
+    // When the row is created, fill out the columns.
+    columns.add(
+        formatPercent(code.exclusiveTicks, isolate.profile.totalSamples));
+    if (parent == null) {
+      // Fill with dummy data.
+      columns.add('');
+    } else {
+      var totalAttributedCalls = parent.code.callersCount(code);
+      var totalParentCalls = parent.code.sumCallersCount();
+      columns.add(formatPercent(totalAttributedCalls, totalParentCalls));
+    }
+    columns.add(
+        formatPercent(code.inclusiveTicks, isolate.profile.totalSamples));
+  }
+
+  void onShow() {
+    if (children.length > 0) {
+      // Child rows already created.
+      return;
+    }
+    // Create child rows on demand.
+    code.callers.forEach((CodeCallCount codeCaller) {
+      var row =
+          new ProfileCallerTreeRow(isolate, codeCaller.code, this);
+      children.add(row);
+    });
+  }
+
+  void onHide() {
+  }
+}
+
 /// Displays an IsolateProfile
 @CustomTag('isolate-profile')
 class IsolateProfileElement extends ObservatoryElement {
   IsolateProfileElement.created() : super.created();
   @observable int methodCountSelected = 0;
   final List methodCounts = [10, 20, 50];
-  @observable List topInclusiveCodes = toObservable([]);
   @observable List topExclusiveCodes = toObservable([]);
+  final _id = '#tableTree';
+  TableTree tree;
 
   void enteredView() {
     var isolateId = app.locationManager.currentIsolateId();
@@ -24,7 +69,8 @@
     if (isolate == null) {
       return;
     }
-    _refreshTopMethods(isolate);
+    tree = new TableTree(['Method', 'Exclusive', 'Caller', 'Inclusive']);
+    _refresh(isolate);
   }
 
   void _startRequest() {
@@ -35,13 +81,13 @@
     // TODO(johnmccutchan): Indicate visually.
   }
 
-  methodCountSelectedChanged(oldValue) {;
+  methodCountSelectedChanged(oldValue) {
     var isolateId = app.locationManager.currentIsolateId();
     var isolate = app.isolateManager.getIsolate(isolateId);
     if (isolate == null) {
       return;
     }
-    _refreshTopMethods(isolate);
+    _refresh(isolate);
   }
 
   void refreshData(Event e, var detail, Node target) {
@@ -66,48 +112,50 @@
 
   void _loadProfileData(Isolate isolate, int totalSamples, Map response) {
     isolate.profile = new Profile.fromMap(isolate, response);
-    _refreshTopMethods(isolate);
+    _refresh(isolate);
   }
 
+  void _refresh(Isolate isolate) {
+    _refreshTopMethods(isolate);
+    _refreshTree(isolate);
+  }
+
+  void _refreshTree(Isolate isolate) {
+    var rootChildren = [];
+    for (var code in topExclusiveCodes) {
+      var row = new ProfileCallerTreeRow(isolate, code, null);
+      rootChildren.add(row);
+    }
+    tree.initialize(rootChildren);
+    notifyPropertyChange(#tree, null, tree);
+  }
+
+
   void _refreshTopMethods(Isolate isolate) {
     topExclusiveCodes.clear();
-    topInclusiveCodes.clear();
     if ((isolate == null) || (isolate.profile == null)) {
       return;
     }
     var count = methodCounts[methodCountSelected];
     var topExclusive = isolate.profile.topExclusive(count);
     topExclusiveCodes.addAll(topExclusive);
-    var topInclusive = isolate.profile.topInclusive(count);
-    topInclusiveCodes.addAll(topInclusive);
-
   }
 
-  String codeTicks(Code code, bool inclusive) {
-    if (code == null) {
-      return '';
-    }
-    return inclusive ? '${code.inclusiveTicks}' : '${code.exclusiveTicks}';
+  @observable String padding(TableTreeRow row) {
+    return 'padding-left: ${row.depth * 16}px;';
   }
 
-  String codePercent(Code code, bool inclusive) {
-    if (code == null) {
-      return '';
-    }
-    var isolateId = app.locationManager.currentIsolateId();
-    var isolate = app.isolateManager.getIsolate(isolateId);
-    if (isolate == null) {
-      return '';
-    }
-    var ticks = inclusive ? code.inclusiveTicks : code.exclusiveTicks;
-    var total = ticks / isolate.profile.totalSamples;
-    return (total * 100.0).toStringAsFixed(2);
+  @observable String coloring(TableTreeRow row) {
+    const colors = const ['active', 'success', 'warning', 'danger', 'info'];
+    var index = row.depth % colors.length;
+    return colors[index];
   }
 
-  String codeName(Code code) {
-    if ((code == null) || (code.name == null)) {
-      return '';
+  @observable void toggleExpanded(Event e, var detail, Element target) {
+    var row = target.parent;
+    if (row is TableRowElement) {
+      // Subtract 1 to get 0 based indexing.
+      tree.toggle(row.rowIndex - 1);
     }
-    return code.name;
   }
 }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.html
index f8e4328..d9009e9 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.html
@@ -4,33 +4,35 @@
 </head>
 <polymer-element name="isolate-profile" extends="observatory-element">
   <template>
-    <p> P R O F I L E </p>
     <div>
       <button type="button" on-click="{{refreshData}}">Refresh profile data</button>
       <span>Top</span>
       <select selectedIndex="{{methodCountSelected}}" value="{{methodCounts[methodCountSelected]}}">
         <option template repeat="{{count in methodCounts}}">{{count}}</option>
       </select>
-      <span>methods</span>
+      <span>exclusive methods</span>
     </div>
-    <blockquote><strong>Top Exclusive</strong></blockquote>
-    <table class="table table-hover">
+    <table id="tableTree" class="table table-hover">
       <thead>
         <tr>
-          <th>Ticks</th>
-          <th>Percent</th>
           <th>Method</th>
+          <th>Exclusive</th>
+          <th>Caller</th>
+          <th>Inclusive</th>
         </tr>
       </thead>
       <tbody>
-        <tr template repeat="{{ code in topExclusiveCodes }}">
-            <td>{{ codeTicks(code, false) }}</td>
-            <td>{{ codePercent(code, false) }}</td>
-            <td>
-            <span>{{ codeName(code) }}</span>
-            <code-ref app="{{ app }}" ref="{{ code.codeRef }}"></code-ref>
-            </td>
+        <tr template repeat="{{row in tree.rows }}" style="{{}}">
+          <td on-click="{{toggleExpanded}}"
+              class="{{ coloring(row) }}"
+              style="{{ padding(row) }}">
+            <code-ref app="{{ app }}" ref="{{ row.code.codeRef }}"></code-ref>
+          </td>
+          <td class="{{ coloring(row) }}">{{row.columns[0]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[1]}}</td>
+          <td class="{{ coloring(row) }}">{{row.columns[2]}}</td>
         </tr>
+      </tbody>
     </table>
   </template>
   <script type="application/dart" src="isolate_profile.dart"></script>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_summary.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_summary.html
index d56d00d..957aa9c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_summary.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_summary.html
@@ -1,5 +1,7 @@
 <head>
+  <link rel="import" href="function_ref.html">
   <link rel="import" href="observatory_element.html">
+  <link rel="import" href="script_ref.html">
 </head>
 <polymer-element name="isolate-summary" extends="observatory-element">
   <template>
@@ -81,12 +83,11 @@
       </div>
       <div class="col-md-6">
         <template if="{{ isolate.topFrame != null }}">
-          <a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['function']['id']) }}">
-            {{ isolate.topFrame['function']['user_name'] }}
-          </a>
-          (<a href="{{ app.locationManager.relativeLink(isolate.id, isolate.topFrame['script']['id']) }}">
-            {{ isolate.topFrame | fileAndLine }}
-          </a>)
+          <function-ref app="{{ app }}" isolate="{{ isolate }}"
+                        ref="{{ isolate.topFrame['function'] }}"></function-ref>
+          (<script-ref app="{{ app }}" isolate="{{ isolate }}"
+                       ref="{{ isolate.topFrame['script'] }}"
+                       line="{{ isolate.topFrame['line'] }}"></script-ref>)
           <br>
           <pre>{{ isolate.topFrame['line'] }} &nbsp; {{ isolate.topFrame['lineString'] }}</pre>
         </template>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
index 130dba6..581abf8c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
@@ -43,6 +43,9 @@
     <template if="{{ messageType == 'Field' }}">
       <field-view app="{{ app }}" field="{{ message }}"></field-view>
     </template>
+    <template if="{{ messageType == 'Closure' }}">
+      <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
+    </template>
     <template if="{{ messageType == 'Instance' }}">
       <instance-view app="{{ app }}" instance="{{ message }}"></instance-view>
     </template>
@@ -79,4 +82,4 @@
     <!-- Add new views and message types in the future here. -->
   </template>
   <script type="application/dart" src="message_viewer.dart"></script>
-</polymer-element>
\ No newline at end of file
+</polymer-element>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/observatory_element.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/observatory_element.dart
index 90ff72a..74db7e0 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/observatory_element.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/observatory_element.dart
@@ -94,4 +94,48 @@
     var shortFile = file.substring(file.lastIndexOf('/') + 1);
     return "${shortFile}:${frame['line']}";    
   }
+
+  bool isNullRef(String type) {
+    return type == '@Null';
+  }
+
+  bool isIntRef(String type) {
+    return (type == '@Smi' ||
+            type == '@Mint' ||
+            type == '@Bigint');
+  }
+
+  bool isBoolRef(String type) {
+    return type == '@Bool';
+  }
+
+  bool isStringRef(String type) {
+    return type == '@String';
+  }
+
+  bool isInstanceRef(String type) {
+    return type == '@Instance';
+  }
+
+  bool isClosureRef(String type) {
+    return type == '@Closure';
+  }
+
+  bool isListRef(String type) {
+    return (type == '@GrowableObjectArray' ||
+            type == '@Array');
+  }
+
+  bool isUnexpectedRef(String type) {
+    return (!['@Null',
+              '@Smi',
+              '@Mint',
+              '@Biginit',
+              '@Bool',
+              '@String',
+              '@Closure',
+              '@Instance',
+              '@GrowableObjectArray',
+              '@Array'].contains(type));
+  }
 }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.dart
index bf6e00b..05bf87a 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.dart
@@ -9,5 +9,43 @@
 
 @CustomTag('script-ref')
 class ScriptRefElement extends ServiceRefElement {
+  @published int line = -1;
+
+  String get url {
+    if ((app != null) && (ref != null)) {
+      var baseUrl = relativeLink(ref['id']);
+      if (line < 0) {
+        return baseUrl;
+      } else {
+        return '$baseUrl?line=$line';
+      }
+    }
+    return '';
+  }
+
+  String get hoverText {
+    if (ref == null) {
+      return '';
+    }
+    if (line < 0) {
+      return ref['user_name'];
+    } else {
+      return "${ref['user_name']}:$line";
+    }
+  }
+
+  String get name {
+    if (ref == null) {
+      return '';
+    }
+    var scriptUrl = ref['user_name'];
+    var shortScriptUrl = scriptUrl.substring(scriptUrl.lastIndexOf('/') + 1);
+    if (line < 0) {
+      return shortScriptUrl;
+    } else {
+      return "$shortScriptUrl:$line";
+    }
+  }
+
   ScriptRefElement.created() : super.created();
 }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.html
index 11e73e9..659d21e 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_ref.html
@@ -4,7 +4,7 @@
 </head>
 <polymer-element name="script-ref" extends="service-ref">
 <template>
-  <a href="{{ url }}">{{ name }}</a>
+  <a title="{{ hoverText }}" href="{{ url }}">{{ name }}</a>
 </template>
 <script type="application/dart" src="script_ref.dart"></script>
-</polymer-element>
\ No newline at end of file
+</polymer-element>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.html
index ac3f919..6212830 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.html
@@ -16,7 +16,7 @@
           <tr template repeat="{{ line in script.linesForDisplay }}">
             <td style="{{ hitsStyle(line) }}">  </td>
             <td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{line.line}}</td>
-            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;">{{line.text}}</td>
+            <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{line.text}}</td>
           </tr>
           </tbody>
         </table>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/service_ref.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/service_ref.dart
index ed30a02..349532f 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/service_ref.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/service_ref.dart
@@ -11,6 +11,7 @@
 class ServiceRefElement extends ObservatoryElement {
   @published Map ref;
   @published bool internal = false;
+  @published Isolate isolate = null;
   ServiceRefElement.created() : super.created();
 
   void refChanged(oldValue) {
@@ -20,8 +21,8 @@
   }
 
   String get url {
-    if ((app != null) && (ref != null)) {
-      return app.locationManager.currentIsolateRelativeLink(ref['id']);
+    if (ref != null) {
+      return relativeLink(ref['id']);
     }
     return '';
   }
@@ -47,4 +48,19 @@
     }
     return '';
   }
+
+  void isolateChanged(oldValue) {
+    notifyPropertyChange(#relativeLink, 0, 1);
+  }
+
+  @observable
+  String relativeLink(String link) {
+    if (app == null) {
+      return '';
+    } else if (isolate == null) {
+      return app.locationManager.currentIsolateRelativeLink(link);
+    } else {
+      return app.locationManager.relativeLink(isolate.id, link);
+    }
+  }
 }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.dart
index 551b160..31d6f333 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.dart
@@ -10,6 +10,11 @@
 @CustomTag('stack-frame')
 class StackFrameElement extends ObservatoryElement {
   @published Map frame = toObservable({});
+  @published bool expanded = false;
 
   StackFrameElement.created() : super.created();
-}
\ No newline at end of file
+
+  void toggleExpand(var a, var b, var c) {
+    expanded = !expanded;
+  }
+}
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.html
index 0001a44..6eeb18c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_frame.html
@@ -6,6 +6,17 @@
 </head>
 <polymer-element name="stack-frame" extends="observatory-element">
   <template>
+    <style>
+      .memberList {
+          margin-left: 3em;
+          border-spacing: 0;
+          border-collapse: collapse;
+      }
+      .member {
+          vertical-align: top;
+          padding: 0 1em;
+      }
+    </style>
     <div class="row">
       <div class="col-md-1"></div>
       <div class="col-md-1">
@@ -13,23 +24,26 @@
       </div>
       <div class="col-md-9">
         <function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref>
-        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref>:{{ frame['line'] }} )
+        ( <script-ref app="{{ app }}" ref="{{ frame['script'] }}" line="{{ frame['line'] }}">
+        </script-ref> ) {
+        <a on-click="{{ toggleExpand }}">...</a>
+
+        <template if="{{ expanded }}">
+          <table class="memberList">
+            <tr template repeat="{{ v in frame['vars'] }}">
+              <td class="member">{{ v['name']}}</td>
+              <td class="member">
+                <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
+              </td>
+            </tr>
+          </table>
+        </template>
+        }
+
       </div>
       <div class="col-md-1"></div>
     </div>
 
-    <template repeat="{{ v in frame['vars'] }}">
-      <div class="row">
-        <div class="col-md-3"></div>
-        <div class="col-md-1">
-          {{ v['name'] }}
-        </div>
-        <div class="col-md-6">
-          <instance-ref app="{{ app }}" ref="{{ v['value'] }}"></instance-ref>
-        </div>
-        <div class="col-md-2"></div>
-      </div>
-    </template>
 
   </template>
   <script type="application/dart" src="stack_frame.dart"></script>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.dart
index 4992831..7bc0e2c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.dart
@@ -4,7 +4,9 @@
 
 library stack_trace_element;
 
+import 'dart:html';
 import 'observatory_element.dart';
+import 'package:logging/logging.dart';
 import 'package:polymer/polymer.dart';
 
 @CustomTag('stack-trace')
@@ -12,4 +14,13 @@
   @published Map trace = toObservable({});
 
   StackTraceElement.created() : super.created();
-}
\ No newline at end of file
+
+  void refresh(Event e, var detail, Node target) {
+    var url = app.locationManager.currentIsolateRelativeLink('stacktrace');
+    app.requestManager.requestMap(url).then((map) {
+        trace = map;
+    }).catchError((e, trace) {
+        Logger.root.severe('Error while reloading stack trace: $e\n$trace');
+    });
+  }
+}
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.html
index c7fc27d..0ad6cfb 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/stack_trace.html
@@ -4,6 +4,7 @@
 </head>
 <polymer-element name="stack-trace" extends="observatory-element">
   <template>
+    <button type="button" on-click="{{refresh}}">Refresh</button>
     <template if="{{ trace['members'].isEmpty }}">
       <div class="col-md-1"></div>
       <div class="col-md-11">
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index b35c67e..b3b6e36 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -9,7 +9,9 @@
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/isolate_data.h"
+#include "bin/platform.h"
 #include "bin/thread.h"
+#include "platform/json.h"
 
 namespace dart {
 namespace bin {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 2cc3de7..90ecac1 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2091,12 +2091,22 @@
 DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args);
 
 /**
- * Gets the native instance field of the native argument at some index.
+ * Gets all the native fields of the native argument at some index.
+ * \param args Native arguments structure.
+ * \param arg_index Index of the desired argument in the structure above.
+ * \param num_fields size of the intptr_t array 'field_values' passed in.
+ * \param field_values intptr_t array in which native field values are returned.
+ * \return Success if the native fields where copied in successfully. Otherwise
+ *   returns an error handle. On success the native field values are copied
+ *   into the 'field_values' array, if the argument at 'arg_index' is a
+ *   null object then 0 is copied as the native field values into the
+ *   'field_values' array.
  */
-DART_EXPORT Dart_Handle Dart_GetNativeFieldOfArgument(Dart_NativeArguments args,
-                                                      int arg_index,
-                                                      int fld_index,
-                                                      intptr_t* value);
+DART_EXPORT Dart_Handle Dart_GetNativeFieldsOfArgument(
+    Dart_NativeArguments args,
+    int arg_index,
+    int num_fields,
+    intptr_t* field_values);
 
 /**
  * Gets the native field of the receiver.
@@ -2465,4 +2475,78 @@
 DART_EXPORT Dart_Isolate Dart_GetServiceIsolate(void* callback_data);
 
 
+/**
+ * Returns true if the service is enabled. False otherwise.
+ *
+ *  \return Returns true if service is running.
+ */
+DART_EXPORT bool Dart_IsServiceRunning();
+
+
+/**
+ * A service request callback function.
+ *
+ * These callbacks, registered by the embedder, are called when the VM receives
+ * a service request it can't handle and the service request command name
+ * matches one of the embedder registered handlers.
+ *
+ * \param name The service request command name. Always the first entry
+ *   in the arguments array. Will match the name the callback was
+ *   registered with.
+ * \param arguments The service request command arguments. Incoming service
+ *   request paths are split like file system paths and flattened into an array
+ *   (e.g. /foo/bar becomes the array ["foo", "bar"].
+ * \param num_arguments The length of the arguments array.
+ * \param option_keys Service requests can have options key-value pairs. The
+ *   keys and values are flattened and stored in arrays.
+ * \param option_values The values associated with the keys.
+ * \param num_options The length of the option_keys and option_values array.
+ * \param user_data The user_data pointer registered with this handler.
+ *
+ * \return Returns a C string containing a valid JSON object. The returned
+ * pointer will be freed by the VM by calling free.
+ */
+typedef const char* (*Dart_ServiceRequestCallback)(
+    const char* name,
+    const char** arguments,
+    intptr_t num_arguments,
+    const char** option_keys,
+    const char** option_values,
+    intptr_t num_options,
+    void* user_data);
+
+/**
+ * Register a Dart_ServiceRequestCallback to be called to handle requests
+ * with name on a specific isolate. The callback will be invoked with the
+ * current isolate set to the request target.
+ *
+ * \param name The name of the command that this callback is responsible for.
+ * \param callback The callback to invoke.
+ * \param user_data The user data passed to the callback.
+ *
+ * NOTE: If multiple callbacks with the same name are registered, only the
+ * last callback registered will be remembered.
+ */
+DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data);
+
+/**
+ * Register a Dart_ServiceRequestCallback to be called to handle requests
+ * with name. The callback will be invoked without a current isolate.
+ *
+ * \param name The name of the command that this callback is responsible for.
+ * \param callback The callback to invoke.
+ * \param user_data The user data passed to the callback.
+ *
+ * NOTE: If multiple callbacks with the same name are registered, only the
+ * last callback registered will be remembered.
+ */
+DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data);
+
+
 #endif  /* INCLUDE_DART_API_H_ */  /* NOLINT */
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 7b9e0d9..788113b 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -27,12 +27,12 @@
 
   void insert(int index, E element) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot insert into a fixed-length list");
   }
 
   void insertAll(int index, Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot insert into a fixed-length list");
   }
 
   void setAll(int index, Iterable<E> iterable) {
@@ -41,22 +41,22 @@
 
   E removeAt(int index) {
     throw new UnsupportedError(
-        "Cannot remove element of a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   bool remove(Object element) {
     throw new UnsupportedError(
-        "Cannot remove element of a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   void removeWhere(bool test(E element)) {
     throw new UnsupportedError(
-        "Cannot remove element of a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   void retainWhere(bool test(E element)) {
     throw new UnsupportedError(
-        "Cannot remove element of a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   Iterable<E> getRange(int start, [int end]) {
@@ -95,12 +95,12 @@
 
   void removeRange(int start, int end) {
     throw new UnsupportedError(
-        "Cannot remove range of a non-extendable array");
+        "Cannot remove range from a fixed-length list");
   }
 
   void replaceRange(int start, int end, Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot remove range of a non-extendable array");
+        "Cannot remove range from a fixed-length list");
   }
 
   void fillRange(int start, int end, [E fillValue]) {
@@ -223,27 +223,27 @@
 
   void add(E element) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot add to a fixed-length list");
   }
 
   void addAll(Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot add to a fixed-length list");
   }
 
   void clear() {
     throw new UnsupportedError(
-        "Cannot clear a non-extendable array");
+        "Cannot clear a fixed-length list");
   }
 
   void set length(int length) {
     throw new UnsupportedError(
-        "Cannot change the length of a non-extendable array");
+        "Cannot resize a fixed-length list");
   }
 
   E removeLast() {
     throw new UnsupportedError(
-        "Cannot remove in a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   E get first {
@@ -509,7 +509,7 @@
 
   E removeLast() {
     throw new UnsupportedError(
-        "Cannot remove in a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   E get first {
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 31de11d..5a117c7 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -212,11 +212,15 @@
     var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) &
          _InvocationMirror._CALL_MASK;
     var type_str =
-        (const ["method", "getter", "setter", "getter or setter"])[type];
+        (const ["method", "getter", "setter", "getter or setter", "variable"])[type];
     var args_message = args_mismatch ? " with matching arguments" : "";
     var msg;
     var memberName =
         (_memberName == null) ? "" : internal.Symbol.getName(_memberName);
+
+    if (type == _InvocationMirror._LOCAL_VAR) {
+      return "cannot assign to final variable '$memberName'.\n\n";
+    }
     switch (level) {
       case _InvocationMirror._DYNAMIC: {
         if (_receiver == null) {
@@ -294,9 +298,13 @@
     }
     var memberName =
         (_memberName == null) ? "" : internal.Symbol.getName(_memberName);
-    if (!args_mismatch) {
+    var type = _invocation_type & _InvocationMirror._TYPE_MASK;
+    if (type == _InvocationMirror._LOCAL_VAR) {
       msg_buf.write(
-          "NoSuchMethodError : method not found: '$memberName'\n"
+          "NoSuchMethodError: cannot assign to final variable '$memberName'");
+    } else if (!args_mismatch) {
+      msg_buf.write(
+          "NoSuchMethodError: method not found: '$memberName'\n"
           "Receiver: $receiver_str\n"
           "Arguments: [$actual_buf]");
     } else {
diff --git a/runtime/lib/growable_array.cc b/runtime/lib/growable_array.cc
index 5cbf585..75efffc 100644
--- a/runtime/lib/growable_array.cc
+++ b/runtime/lib/growable_array.cc
@@ -91,4 +91,11 @@
   return Object::null();
 }
 
+
+DEFINE_NATIVE_ENTRY(Internal_makeListFixedLength, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray, array,
+                               arguments->NativeArgAt(0));
+  return Array::MakeArray(array);
+}
+
 }  // namespace dart
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index c4618bc..e1915c5 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -1,3 +1,6 @@
 // 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.
+
+patch List makeListFixedLength(List growableList)
+    native "Internal_makeListFixedLength";
diff --git a/runtime/lib/invocation_mirror.h b/runtime/lib/invocation_mirror.h
index 6e0a75b..78d1ba4 100644
--- a/runtime/lib/invocation_mirror.h
+++ b/runtime/lib/invocation_mirror.h
@@ -21,8 +21,9 @@
     kGetter = 1,
     kSetter = 2,
     kField  = 3,
+    kLocalVar = 4,
     kTypeShift = 0,
-    kTypeBits = 2,
+    kTypeBits = 3,
     kTypeMask = (1 << kTypeBits) - 1
   };
 
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 5b86660..e06c531 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -9,8 +9,9 @@
   static const int _GETTER = 1;
   static const int _SETTER = 2;
   static const int _FIELD = 3;
+  static const int _LOCAL_VAR = 4;
   static const int _TYPE_SHIFT = 0;
-  static const int _TYPE_BITS = 2;
+  static const int _TYPE_BITS = 3;
   static const int _TYPE_MASK = (1 << _TYPE_BITS) - 1;
 
   // These values, except _DYNAMIC and _SUPER, are only used when throwing
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index a5955a9..87a8024 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -227,7 +227,8 @@
 
 patch class Isolate {
   /* patch */ static Future<Isolate> spawn(
-      void entryPoint(message), var message) {
+      void entryPoint(message), var message, { bool paused: false }) {
+    // `paused` isn't handled yet.
     try {
       // The VM will invoke [_startIsolate] with entryPoint as argument.
       SendPort controlPort = _spawnFunction(entryPoint);
@@ -246,7 +247,8 @@
   }
 
   /* patch */ static Future<Isolate> spawnUri(
-      Uri uri, List<String> args, var message) {
+      Uri uri, List<String> args, var message, { bool paused: false }) {
+    // `paused` isn't handled yet.
     try {
       // The VM will invoke [_startIsolate] and not `main`.
       SendPort controlPort = _spawnUri(uri.toString());
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 3e1c86e..94cda1b 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -82,7 +82,7 @@
   // Parameter 4 (named arguments): We omit this parameters since we cannot
   // invoke functions with named parameters reflectively (using mirrors).
   if (!function.IsNull()) {
-    const int total_num_parameters = function.NumParameters();
+    const intptr_t total_num_parameters = function.NumParameters();
     const Array& array = Array::Handle(Array::New(total_num_parameters));
     String& param_name = String::Handle();
     for (int i = 0; i < total_num_parameters; i++) {
@@ -433,7 +433,7 @@
   const GrowableObjectArray& libraries =
       GrowableObjectArray::Handle(isolate->object_store()->libraries());
 
-  const int num_libraries = libraries.Length();
+  const intptr_t num_libraries = libraries.Length();
   const Array& library_mirrors = Array::Handle(Array::New(num_libraries));
   Library& library = Library::Handle();
   Instance& library_mirror = Instance::Handle();
@@ -1481,7 +1481,7 @@
   const bool callable = closure.IsCallable(&function, NULL);
   ASSERT(callable);
 
-  const int parts_len = lookup_parts.Length();
+  const intptr_t parts_len = lookup_parts.Length();
   // Lookup name is always the last part.
   const String& lookup_name = String::Handle(String::RawCast(
       lookup_parts.At(parts_len - 1)));
@@ -1587,7 +1587,7 @@
         UNREACHABLE();
       }
       // Make room for the closure (receiver) in the argument list.
-      int numArgs = args.Length();
+      intptr_t numArgs = args.Length();
       const Array& call_args = Array::Handle(Array::New(numArgs + 1));
       Object& temp = Object::Handle();
       for (int i = 0; i < numArgs; i++) {
@@ -1883,7 +1883,7 @@
         UNREACHABLE();
       }
       // Make room for the closure (receiver) in arguments.
-      int numArgs = args.Length();
+      intptr_t numArgs = args.Length();
       const Array& call_args = Array::Handle(Array::New(numArgs + 1));
       Object& temp = Object::Handle();
       for (int i = 0; i < numArgs; i++) {
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 3836838..1162ab4 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -87,7 +87,7 @@
       }
     }
     if (!function.IsNull()) {
-      const int total_num_parameters = function.NumParameters();
+      const intptr_t total_num_parameters = function.NumParameters();
       const Array& array = Array::Handle(Array::New(total_num_parameters - 1));
       // Skip receiver.
       for (int i = 1; i < total_num_parameters; i++) {
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 4a66276..47a82ed 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -73,15 +73,17 @@
     intptr_t value = Smi::Cast(index_object).Value();
     if (Utf::IsOutOfRange(value)) {
       Exceptions::ThrowByType(Exceptions::kArgument, Object::empty_array());
-    } else {
-      if (!Utf::IsLatin1(value)) {
-        is_one_byte_string = false;
-        if (Utf::IsSupplementary(value)) {
-          utf16_len += 1;
-        }
+      UNREACHABLE();
+    }
+    // Now it is safe to cast the value.
+    int32_t value32 = static_cast<int32_t>(value);
+    if (!Utf::IsLatin1(value32)) {
+      is_one_byte_string = false;
+      if (Utf::IsSupplementary(value32)) {
+        utf16_len += 1;
       }
     }
-    utf32_array[i] = value;
+    utf32_array[i] = value32;
   }
   if (is_one_byte_string) {
     return OneByteString::New(utf32_array, array_len, Heap::kNew);
@@ -237,7 +239,7 @@
 static int32_t StringValueAt(const String& str, const Integer& index) {
   if (index.IsSmi()) {
     const Smi& smi = Smi::Cast(index);
-    int32_t index = smi.Value();
+    intptr_t index = smi.Value();
     if ((index < 0) || (index >= str.Length())) {
       const Array& args = Array::Handle(Array::New(1));
       args.SetAt(0, smi);
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 2604cb8..1bececf 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -302,6 +302,37 @@
     }
   }
 
+  String operator*(int times) {
+    if (times <= 0) return "";
+    if (times == 1) return this;
+    StringBuffer buffer = new StringBuffer(this);
+    for (int i = 1; i < times; i++) {
+      buffer.write(this);
+    }
+    return buffer.toString();
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    StringBuffer buffer = new StringBuffer();
+    for (int i = 0; i < delta; i++) {
+      buffer.write(padding);
+    }
+    buffer.write(this);
+    return buffer.toString();
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    StringBuffer buffer = new StringBuffer(this);
+    for (int i = 0; i < delta; i++) {
+      buffer.write(padding);
+    }
+    return buffer.toString();
+  }
+
   bool contains(Pattern pattern, [int startIndex = 0]) {
     if (pattern is String) {
       if (startIndex < 0 || startIndex > this.length) {
@@ -632,6 +663,83 @@
     return super.contains(pattern, start);
   }
 
+  String operator*(int times) {
+    if (times <= 0) return "";
+    if (times == 1) return this;
+    int length = this.length;
+    if (this.isEmpty) return this;  // Don't clone empty string.
+    _OneByteString result = _OneByteString._allocate(length * times);
+    int index = 0;
+    for (int i = 0; i < times; i ++) {
+      for (int j = 0; j < length; j++) {
+        result._setAt(index++, this.codeUnitAt(j));
+      }
+    }
+    return result;
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    int padCid = padding._cid;
+    if (padCid != _OneByteString._classId &&
+        padCid != _ExternalOneByteString._classId) {
+      return super.padLeft(width, padding);
+    }
+    int length = this.length;
+    int delta = width - length;
+    if (delta <= 0) return this;
+    int padLength = padding.length;
+    int resultLength = padLength * delta + length;
+    _OneByteString result = _OneByteString._allocate(resultLength);
+    int index = 0;
+    if (padLength == 1) {
+      int padChar = padding.codeUnitAt(0);
+      for (int i = 0; i < delta; i++) {
+        result._setAt(index++, padChar);
+      }
+    } else {
+      for (int i = 0; i < delta; i++) {
+        for (int j = 0; j < padLength; j++) {
+          result._setAt(index++, padding.codeUnitAt(j));
+        }
+      }
+    }
+    for (int i = 0; i < length; i++) {
+      result._setAt(index++, this.codeUnitAt(i));
+    }
+    return result;
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    int padCid = padding._cid;
+    if (padCid != _OneByteString._classId &&
+        padCid != _ExternalOneByteString._classId) {
+      return super.padRight(width, padding);
+    }
+    int length = this.length;
+    int delta = width - length;
+    if (delta <= 0) return this;
+    int padLength = padding.length;
+    int resultLength = length + padLength * delta;
+    _OneByteString result = _OneByteString._allocate(resultLength);
+    int index = 0;
+    for (int i = 0; i < length; i++) {
+      result._setAt(index++, this.codeUnitAt(i));
+    }
+    if (padLength == 1) {
+      int padChar = padding.codeUnitAt(0);
+      for (int i = 0; i < delta; i++) {
+        result._setAt(index++, padChar);
+      }
+    } else {
+      for (int i = 0; i < delta; i++) {
+        for (int j = 0; j < padLength; j++) {
+          result._setAt(index++, padding.codeUnitAt(j));
+        }
+      }
+    }
+    return result;
+  }
+
   // Allocates a string of given length, expecting its content to be
   // set using _setAt.
   static _OneByteString _allocate(int length) native "OneByteString_allocate";
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 7430819..49c8b20 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -408,27 +408,27 @@
 
   set length(newLength) {
     throw new UnsupportedError(
-        "Cannot resize a non-extendable array");
+        "Cannot resize a fixed-length list");
   }
 
   void add(value) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot add to a fixed-length list");
   }
 
   void addAll(Iterable value) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot add to a fixed-length list");
   }
 
   void insert(int index, value) {
     throw new UnsupportedError(
-        "Cannot insert into a non-extendable array");
+        "Cannot insert into a fixed-length list");
   }
 
   void insertAll(int index, Iterable values) {
     throw new UnsupportedError(
-        "Cannot insert into a non-extendable array");
+        "Cannot insert into a fixed-length list");
   }
 
   void sort([int compare(a, b)]) {
@@ -449,32 +449,32 @@
 
   void clear() {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   int removeLast() {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   bool remove(Object element) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   bool removeAt(int index) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   void removeWhere(bool test(element)) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   void retainWhere(bool test(element)) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   dynamic get first {
@@ -495,12 +495,12 @@
 
   void removeRange(int start, int end) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   void replaceRange(int start, int end, Iterable iterable) {
     throw new UnsupportedError(
-        "Cannot remove from a non-extendable array");
+        "Cannot remove from a fixed-length list");
   }
 
   List toList({bool growable: true}) {
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index b35c4f5..78693ad 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -481,7 +481,7 @@
     ({ intptr_t __result;                                                      \
        do {                                                                    \
          __result = (expression);                                              \
-       } while (__result == -1L && errno == EINTR);                            \
+       } while ((__result == -1L) && (errno == EINTR));                        \
        __result; })
 #endif  // !defined(TEMP_FAILURE_RETRY)
 
diff --git a/runtime/platform/json.cc b/runtime/platform/json.cc
index 31ad418..a406e7a 100644
--- a/runtime/platform/json.cc
+++ b/runtime/platform/json.cc
@@ -510,6 +510,15 @@
 }
 
 
+const char* TextBuffer::Steal() {
+  const char* r = buf_;
+  buf_ = NULL;
+  buf_size_ = 0;
+  msg_len_ = 0;
+  return r;
+}
+
+
 void TextBuffer::AddChar(char ch) {
   EnsureCapacity(sizeof(ch));
   buf_[msg_len_] = ch;
diff --git a/runtime/platform/json.h b/runtime/platform/json.h
index a793cb8..36c7d5d 100644
--- a/runtime/platform/json.h
+++ b/runtime/platform/json.h
@@ -136,6 +136,10 @@
   char* buf() { return buf_; }
   intptr_t length() { return msg_len_; }
 
+  // Steal ownership of the buffer pointer.
+  // NOTE: TextBuffer is empty afterwards.
+  const char* Steal();
+
  private:
   void EnsureCapacity(intptr_t len);
   char* buf_;
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 543b950..0dd2ef4 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -8,13 +8,16 @@
 
 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
 // figure 3-3, page 48, where the function is called clp2.
-uint32_t Utils::RoundUpToPowerOfTwo(uint32_t x) {
+uintptr_t Utils::RoundUpToPowerOfTwo(uintptr_t x) {
   x = x - 1;
   x = x | (x >> 1);
   x = x | (x >> 2);
   x = x | (x >> 4);
   x = x | (x >> 8);
   x = x | (x >> 16);
+#if defined(ARCH_IS_64_BIT)
+  x = x | (x >> 32);
+#endif  // defined(ARCH_IS_64_BIT)
   return x + 1;
 }
 
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 4359a4b..953cf10 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -76,7 +76,7 @@
     return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n));
   }
 
-  static uint32_t RoundUpToPowerOfTwo(uint32_t x);
+  static uintptr_t RoundUpToPowerOfTwo(uintptr_t x);
   static int CountOneBits(uint32_t x);
 
   static int HighestBit(int64_t v);
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 7f9933d..cd02b44 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/assembler.h"
+#include "vm/cpu.h"
 #include "vm/longjump.h"
 #include "vm/runtime_entry.h"
 #include "vm/simulator.h"
@@ -22,97 +23,6 @@
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
 DECLARE_FLAG(bool, inline_alloc);
 
-bool CPUFeatures::integer_division_supported_ = false;
-bool CPUFeatures::neon_supported_ = false;
-#if defined(DEBUG)
-bool CPUFeatures::initialized_ = false;
-#endif
-
-
-bool CPUFeatures::integer_division_supported() {
-  DEBUG_ASSERT(initialized_);
-  return integer_division_supported_;
-}
-
-
-bool CPUFeatures::neon_supported() {
-  DEBUG_ASSERT(initialized_);
-  return neon_supported_;
-}
-
-
-// If we are using the simulator, allow tests to enable/disable support for
-// integer division.
-#if defined(USING_SIMULATOR)
-void CPUFeatures::set_integer_division_supported(bool supported) {
-  integer_division_supported_ = supported;
-}
-
-
-void CPUFeatures::set_neon_supported(bool supported) {
-  neon_supported_ = supported;
-}
-#endif
-
-
-// Probe /proc/cpuinfo for features of the ARM processor.
-#if !defined(USING_SIMULATOR)
-static bool CPUInfoContainsString(const char* search_string) {
-  const char* file_name = "/proc/cpuinfo";
-  // This is written as a straight shot one pass parser
-  // and not using STL string and ifstream because,
-  // on Linux, it's reading from a (non-mmap-able)
-  // character special device.
-  FILE* f = NULL;
-  const char* what = search_string;
-
-  if (NULL == (f = fopen(file_name, "r")))
-    return false;
-
-  int k;
-  while (EOF != (k = fgetc(f))) {
-    if (k == *what) {
-      ++what;
-      while ((*what != '\0') && (*what == fgetc(f))) {
-        ++what;
-      }
-      if (*what == '\0') {
-        fclose(f);
-        return true;
-      } else {
-        what = search_string;
-      }
-    }
-  }
-  fclose(f);
-
-  // Did not find string in the proc file.
-  return false;
-}
-#endif
-
-
-void CPUFeatures::InitOnce() {
-#if defined(USING_SIMULATOR)
-  integer_division_supported_ = true;
-  neon_supported_ = true;
-#else
-  ASSERT(CPUInfoContainsString("ARMv7"));  // Implements ARMv7.
-  ASSERT(CPUInfoContainsString("vfp"));  // Has floating point unit.
-  // Has integer division.
-  if (CPUInfoContainsString("QCT APQ8064")) {
-    // Special case for Qualcomm Krait CPUs in Nexus 4 and 7.
-    integer_division_supported_ = true;
-  } else {
-    integer_division_supported_ = CPUInfoContainsString("idiva");
-  }
-  neon_supported_ = CPUInfoContainsString("neon");
-#endif  // defined(USING_SIMULATOR)
-#if defined(DEBUG)
-  initialized_ = true;
-#endif
-}
-
 
 // Instruction encoding bits.
 enum {
@@ -549,7 +459,7 @@
 
 void Assembler::EmitDivOp(Condition cond, int32_t opcode,
                           Register rd, Register rn, Register rm) {
-  ASSERT(CPUFeatures::integer_division_supported());
+  ASSERT(TargetCPUFeatures::integer_division_supported());
   ASSERT(rd != kNoRegister);
   ASSERT(rn != kNoRegister);
   ASSERT(rm != kNoRegister);
@@ -2457,7 +2367,7 @@
 void Assembler::IntegerDivide(Register result, Register left, Register right,
                               DRegister tmpl, DRegister tmpr) {
   ASSERT(tmpl != tmpr);
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     sdiv(result, left, right);
   } else {
     SRegister stmpl = static_cast<SRegister>(2 * tmpl);
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 87046cc..10d9a7f 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -63,26 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(Label);
 };
 
-
-class CPUFeatures : public AllStatic {
- public:
-  static void InitOnce();
-  static bool double_truncate_round_supported() { return false; }
-  static bool integer_division_supported();
-  static bool neon_supported();
-#if defined(USING_SIMULATOR)
-  static void set_integer_division_supported(bool supported);
-  static void set_neon_supported(bool supported);
-#endif
- private:
-  static bool integer_division_supported_;
-  static bool neon_supported_;
-#if defined(DEBUG)
-  static bool initialized_;
-#endif
-};
-
-
 // Encodes Addressing Mode 1 - Data-processing operands.
 class ShifterOperand : public ValueObject {
  public:
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index c09075f..f4f4887 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/assembler.h"
+#include "vm/cpu.h"
 #include "vm/os.h"
 #include "vm/unit_test.h"
 #include "vm/virtual_memory.h"
@@ -1457,7 +1458,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Udiv, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ mov(R0, ShifterOperand(27));
     __ mov(R1, ShifterOperand(9));
     __ udiv(R2, R0, R1);
@@ -1477,7 +1478,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sdiv, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ mov(R0, ShifterOperand(27));
     __ LoadImmediate(R1, -9);
     __ sdiv(R2, R0, R1);
@@ -1497,7 +1498,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Udiv_zero, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ mov(R0, ShifterOperand(27));
     __ mov(R1, ShifterOperand(0));
     __ udiv(R2, R0, R1);
@@ -1517,7 +1518,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sdiv_zero, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ mov(R0, ShifterOperand(27));
     __ mov(R1, ShifterOperand(0));
     __ udiv(R2, R0, R1);
@@ -1537,7 +1538,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Udiv_corner, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ LoadImmediate(R0, 0x80000000);
     __ LoadImmediate(R1, 0xffffffff);
     __ udiv(R2, R0, R1);
@@ -1557,7 +1558,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sdiv_corner, assembler) {
-  if (CPUFeatures::integer_division_supported()) {
+  if (TargetCPUFeatures::integer_division_supported()) {
     __ LoadImmediate(R0, 0x80000000);
     __ LoadImmediate(R1, 0xffffffff);
     __ sdiv(R2, R0, R1);
@@ -1579,12 +1580,12 @@
 
 ASSEMBLER_TEST_GENERATE(IntDiv_supported, assembler) {
 #if defined(USING_SIMULATOR)
-  bool orig = CPUFeatures::integer_division_supported();
-  CPUFeatures::set_integer_division_supported(true);
+  bool orig = TargetCPUFeatures::integer_division_supported();
+  HostCPUFeatures::set_integer_division_supported(true);
   __ mov(R0, ShifterOperand(27));
   __ mov(R1, ShifterOperand(9));
   __ IntegerDivide(R0, R0, R1, D0, D1);
-  CPUFeatures::set_integer_division_supported(orig);
+  HostCPUFeatures::set_integer_division_supported(orig);
   __ bx(LR);
 #else
   __ mov(R0, ShifterOperand(27));
@@ -1604,12 +1605,12 @@
 
 ASSEMBLER_TEST_GENERATE(IntDiv_unsupported, assembler) {
 #if defined(USING_SIMULATOR)
-  bool orig = CPUFeatures::integer_division_supported();
-  CPUFeatures::set_integer_division_supported(false);
+  bool orig = TargetCPUFeatures::integer_division_supported();
+  HostCPUFeatures::set_integer_division_supported(false);
   __ mov(R0, ShifterOperand(27));
   __ mov(R1, ShifterOperand(9));
   __ IntegerDivide(R0, R0, R1, D0, D1);
-  CPUFeatures::set_integer_division_supported(orig);
+  HostCPUFeatures::set_integer_division_supported(orig);
   __ bx(LR);
 #else
   __ mov(R0, ShifterOperand(27));
@@ -1644,7 +1645,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vaddqi8, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1688,7 +1689,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vaddqi16, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1732,7 +1733,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vaddqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1776,7 +1777,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vaddqi64, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1808,7 +1809,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vsubqi8, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1852,7 +1853,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vsubqi16, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1896,7 +1897,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vsubqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1940,7 +1941,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vsubqi64, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -1972,7 +1973,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmulqi8, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2016,7 +2017,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmulqi16, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2060,7 +2061,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmulqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2104,7 +2105,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vaddqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -2139,7 +2140,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vsubqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -2174,7 +2175,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmulqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -2209,7 +2210,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(VtblX, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Index.
     __ LoadImmediate(R0, 0x03020100);
     __ vmovsr(S0, R0);
@@ -2252,7 +2253,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(VtblY, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Index.
     __ LoadImmediate(R0, 0x07060504);
     __ vmovsr(S0, R0);
@@ -2295,7 +2296,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(VtblZ, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Index.
     __ LoadImmediate(R0, 0x0b0a0908);
     __ vmovsr(S0, R0);
@@ -2338,7 +2339,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(VtblW, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Index.
     __ LoadImmediate(R0, 0x0f0e0d0c);
     __ vmovsr(S0, R0);
@@ -2381,7 +2382,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Veorq, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Q0
     __ LoadImmediate(R0, 0xaaaaaaab);
     __ vmovsr(S0, R0);
@@ -2423,7 +2424,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vornq, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Q0
     __ LoadImmediate(R0, 0xfffffff0);
     __ vmovsr(S0, R0);
@@ -2465,7 +2466,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vorrq, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Q0
     __ LoadImmediate(R0, 0xaaaaaaaa);
     __ vmovsr(S0, R0);
@@ -2507,7 +2508,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vandq, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Q0
     __ LoadImmediate(R0, 0xaaaaaaab);
     __ vmovsr(S0, R0);
@@ -2549,7 +2550,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmovq, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     // Q0
     __ LoadSImmediate(S0, 1.0);
     __ vmovs(S1, S0);
@@ -2587,7 +2588,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vdupb, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadImmediate(R0, 0x00000000);
     __ LoadImmediate(R1, 0x00ff0000);
     __ vmovsr(S4, R0);
@@ -2620,7 +2621,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vduph, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadImmediate(R0, 0xffff0000);
     __ LoadImmediate(R1, 0x00000000);
     __ vmovsr(S4, R0);
@@ -2653,7 +2654,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vdupw, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadImmediate(R0, 0x00000000);
     __ LoadImmediate(R1, 0xffffffff);
     __ vmovsr(S4, R0);
@@ -2686,7 +2687,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vzipqw, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 0.0);
     __ LoadSImmediate(S1, 1.0);
     __ LoadSImmediate(S2, 2.0);
@@ -2720,7 +2721,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vceqqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2764,7 +2765,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vceqqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -2800,7 +2801,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcgeqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2844,7 +2845,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcugeqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2888,7 +2889,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcgeqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -2924,7 +2925,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcgtqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -2968,7 +2969,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcugtqi32, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ mov(R0, ShifterOperand(1));
     __ vmovsr(S0, R0);
     __ mov(R0, ShifterOperand(2));
@@ -3012,7 +3013,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vcgtqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -3048,7 +3049,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vminqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -3083,7 +3084,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vmaxqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S0, 1.0);
     __ LoadSImmediate(S1, 2.0);
     __ LoadSImmediate(S2, 3.0);
@@ -3153,7 +3154,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 147.0);
     __ vmovs(S5, S4);
     __ vmovs(S6, S4);
@@ -3178,7 +3179,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vrecpsqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 5.0);
     __ LoadSImmediate(S5, 2.0);
     __ LoadSImmediate(S6, 3.0);
@@ -3208,7 +3209,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Reciprocal, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 147000.0);
     __ vmovs(S5, S4);
     __ vmovs(S6, S4);
@@ -3290,7 +3291,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 147.0);
     __ vmovs(S5, S4);
     __ vmovs(S6, S4);
@@ -3315,7 +3316,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vrsqrtsqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 5.0);
     __ LoadSImmediate(S5, 2.0);
     __ LoadSImmediate(S6, 3.0);
@@ -3345,7 +3346,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 147000.0);
     __ vmovs(S5, S4);
     __ vmovs(S6, S4);
@@ -3380,7 +3381,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 147000.0);
     __ vmovs(S5, S4);
     __ vmovs(S6, S4);
@@ -3425,7 +3426,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(SIMDSqrt2, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 1.0);
     __ LoadSImmediate(S5, 4.0);
     __ LoadSImmediate(S6, 9.0);
@@ -3474,7 +3475,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(SIMDDiv, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 1.0);
     __ LoadSImmediate(S5, 4.0);
     __ LoadSImmediate(S6, 9.0);
@@ -3515,7 +3516,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vabsqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 1.0);
     __ LoadSImmediate(S5, -1.0);
     __ LoadSImmediate(S6, 1.0);
@@ -3544,7 +3545,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Vnegqs, assembler) {
-  if (CPUFeatures::neon_supported()) {
+  if (TargetCPUFeatures::neon_supported()) {
     __ LoadSImmediate(S4, 1.0);
     __ LoadSImmediate(S5, -2.0);
     __ LoadSImmediate(S6, 1.0);
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 67b62df..e1a4658 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -7,6 +7,7 @@
 
 #include "vm/assembler.h"
 #include "vm/code_generator.h"
+#include "vm/cpu.h"
 #include "vm/heap.h"
 #include "vm/memory_region.h"
 #include "vm/runtime_entry.h"
@@ -16,62 +17,9 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
 DECLARE_FLAG(bool, inline_alloc);
 
 
-bool CPUFeatures::sse2_supported_ = false;
-bool CPUFeatures::sse4_1_supported_ = false;
-#ifdef DEBUG
-bool CPUFeatures::initialized_ = false;
-#endif
-
-
-bool CPUFeatures::sse2_supported() {
-  DEBUG_ASSERT(initialized_);
-  return sse2_supported_;
-}
-
-
-bool CPUFeatures::sse4_1_supported() {
-  DEBUG_ASSERT(initialized_);
-  return sse4_1_supported_ && FLAG_use_sse41;
-}
-
-
-#define __ assembler.
-
-void CPUFeatures::InitOnce() {
-  Assembler assembler;
-  __ pushl(EBP);
-  __ pushl(EBX);
-  __ movl(EBP, ESP);
-  // Get feature information in ECX:EDX and return it in EDX:EAX.
-  __ movl(EAX, Immediate(1));
-  __ cpuid();
-  __ movl(EAX, EDX);
-  __ movl(EDX, ECX);
-  __ movl(ESP, EBP);
-  __ popl(EBX);
-  __ popl(EBP);
-  __ ret();
-
-  const Code& code =
-      Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler));
-  Instructions& instructions = Instructions::Handle(code.instructions());
-  typedef uint64_t (*DetectCPUFeatures)();
-  uint64_t features =
-      reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())();
-  sse2_supported_ = (features & kSSE2BitMask) != 0;
-  sse4_1_supported_ = (features & kSSE4_1BitMask) != 0;
-#ifdef DEBUG
-  initialized_ = true;
-#endif
-}
-
-#undef __
-
-
 class DirectCallRelocation : public AssemblerFixup {
  public:
   void Process(const MemoryRegion& region, intptr_t position) {
@@ -1222,7 +1170,7 @@
 
 
 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) {
-  ASSERT(CPUFeatures::sse4_1_supported());
+  ASSERT(TargetCPUFeatures::sse4_1_supported());
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x66);
   EmitUint8(0x0F);
@@ -1235,7 +1183,7 @@
 
 
 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) {
-  ASSERT(CPUFeatures::sse4_1_supported());
+  ASSERT(TargetCPUFeatures::sse4_1_supported());
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x66);
   EmitUint8(0x0F);
@@ -1246,7 +1194,7 @@
 
 
 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) {
-  ASSERT(CPUFeatures::sse4_1_supported());
+  ASSERT(TargetCPUFeatures::sse4_1_supported());
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x66);
   EmitUint8(0x0F);
@@ -1266,7 +1214,7 @@
 
 
 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) {
-  ASSERT(CPUFeatures::sse4_1_supported());
+  ASSERT(TargetCPUFeatures::sse4_1_supported());
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x66);
   EmitUint8(0x0F);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index cfff9a9..d3d3dbe 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -286,25 +286,6 @@
 };
 
 
-class CPUFeatures : public AllStatic {
- public:
-  static void InitOnce();
-  static bool sse2_supported();
-  static bool sse4_1_supported();
-  static bool double_truncate_round_supported() { return sse4_1_supported(); }
-
- private:
-  static const uint64_t kSSE2BitMask = static_cast<uint64_t>(1) << 26;
-  static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
-
-  static bool sse2_supported_;
-  static bool sse4_1_supported_;
-#ifdef DEBUG
-  static bool initialized_;
-#endif
-};
-
-
 class Assembler : public ValueObject {
  public:
   explicit Assembler(bool use_far_branches = false)
diff --git a/runtime/vm/assembler_ia32_test.cc b/runtime/vm/assembler_ia32_test.cc
index bf3377e..a652b8f 100644
--- a/runtime/vm/assembler_ia32_test.cc
+++ b/runtime/vm/assembler_ia32_test.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/assembler.h"
+#include "vm/cpu.h"
 #include "vm/os.h"
 #include "vm/unit_test.h"
 #include "vm/virtual_memory.h"
@@ -2808,7 +2809,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     __ movsd(XMM0, Address(ESP, kWordSize));
     __ pextrd(EAX, XMM0, Immediate(0));
   }
@@ -2817,7 +2818,7 @@
 
 
 ASSEMBLER_TEST_RUN(Pextrd0, test) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     typedef int32_t (*PextrdCode0)(double d);
     int32_t res = reinterpret_cast<PextrdCode0>(test->entry())(123456789);
     EXPECT_EQ(0x54000000, res);
@@ -2826,7 +2827,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     __ movsd(XMM0, Address(ESP, kWordSize));
     __ pextrd(EAX, XMM0, Immediate(1));
   }
@@ -2835,7 +2836,7 @@
 
 
 ASSEMBLER_TEST_RUN(Pextrd1, test) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     typedef int32_t (*PextrdCode1)(double d);
     int32_t res = reinterpret_cast<PextrdCode1>(test->entry())(123456789);
     EXPECT_EQ(0x419d6f34, res);
@@ -2844,7 +2845,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     __ movsd(XMM0, Address(ESP, kWordSize));
     __ pmovsxdq(XMM0, XMM0);
     __ pextrd(EAX, XMM0, Immediate(1));
@@ -2854,7 +2855,7 @@
 
 
 ASSEMBLER_TEST_RUN(Pmovsxdq, test) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     typedef int32_t (*PmovsxdqCode)(double d);
     int32_t res = reinterpret_cast<PmovsxdqCode>(test->entry())(123456789);
     EXPECT_EQ(0, res);
@@ -2863,7 +2864,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     __ movsd(XMM0, Address(ESP, kWordSize));
     __ xorpd(XMM1, XMM1);
     __ pcmpeqq(XMM0, XMM1);
@@ -2874,7 +2875,7 @@
 
 
 ASSEMBLER_TEST_RUN(Pcmpeqq, test) {
-  if (CPUFeatures::sse4_1_supported()) {
+  if (TargetCPUFeatures::sse4_1_supported()) {
     typedef int32_t (*PcmpeqqCode)(double d);
     int32_t res = reinterpret_cast<PcmpeqqCode>(test->entry())(0);
     EXPECT_EQ(-1, res);
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index d80baee..e0de57b 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -135,15 +135,6 @@
 };
 
 
-class CPUFeatures : public AllStatic {
- public:
-  static void InitOnce() { }
-  static bool double_truncate_round_supported() {
-    return false;
-  }
-};
-
-
 class Assembler : public ValueObject {
  public:
   explicit Assembler(bool use_far_branches = false)
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index d293395..f2c075d 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_MIPS)
 
 #include "vm/assembler.h"
+#include "vm/cpu.h"
 #include "vm/os.h"
 #include "vm/unit_test.h"
 #include "vm/virtual_memory.h"
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index b1de19d..a3bc9eb 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/assembler.h"
+#include "vm/cpu.h"
 #include "vm/heap.h"
 #include "vm/memory_region.h"
 #include "vm/runtime_entry.h"
@@ -15,56 +16,9 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
 DECLARE_FLAG(bool, inline_alloc);
 
 
-bool CPUFeatures::sse4_1_supported_ = false;
-#ifdef DEBUG
-bool CPUFeatures::initialized_ = false;
-#endif
-
-bool CPUFeatures::sse4_1_supported() {
-  DEBUG_ASSERT(initialized_);
-  return sse4_1_supported_ && FLAG_use_sse41;
-}
-
-
-#define __ assembler.
-
-void CPUFeatures::InitOnce() {
-  Assembler assembler;
-  __ pushq(RBP);
-  __ pushq(RBX);
-  __ movq(RBP, RSP);
-  // Get feature information in ECX:EDX and return it in RAX.
-  // Note that cpuid operates the same in 64-bit and 32-bit mode.
-  __ movq(RAX, Immediate(1));
-  __ cpuid();
-  __ movl(RAX, RCX);  // Zero extended.
-  __ shlq(RAX, Immediate(32));
-  __ movl(RCX, RDX);  // Zero extended.
-  __ orq(RAX, RCX);
-  __ movq(RSP, RBP);
-  __ popq(RBX);
-  __ popq(RBP);
-  __ ret();
-
-  const Code& code =
-      Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler));
-  Instructions& instructions = Instructions::Handle(code.instructions());
-  typedef uint64_t (*DetectCPUFeatures)();
-  uint64_t features =
-      reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())();
-  sse4_1_supported_ = (features & kSSE4_1BitMask) != 0;
-#ifdef DEBUG
-  initialized_ = true;
-#endif
-}
-
-#undef __
-
-
 Assembler::Assembler(bool use_far_branches)
     : buffer_(),
       object_pool_(GrowableObjectArray::Handle()),
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 1fb9c2e..1b12f5f 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -317,24 +317,6 @@
 };
 
 
-class CPUFeatures : public AllStatic {
- public:
-  static void InitOnce();
-  // x64 always has at least SSE2.
-  static bool sse2_supported() { return true; }
-  static bool sse4_1_supported();
-  static bool double_truncate_round_supported() { return sse4_1_supported(); }
-
- private:
-  static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
-
-  static bool sse4_1_supported_;
-#ifdef DEBUG
-  static bool initialized_;
-#endif
-};
-
-
 class Assembler : public ValueObject {
  public:
   explicit Assembler(bool use_far_branches = false);
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index c82340f..9ac20a5 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -346,7 +346,7 @@
 
 
 void AstPrinter::VisitNativeBodyNode(NativeBodyNode* node) {
-  OS::Print("(%s \"%s\" (%d args))",
+  OS::Print("(%s \"%s\" (%" Pd " args))",
             node->PrettyName(),
             node->native_c_function_name().ToCString(),
             NativeArguments::ParameterCountForResolution(node->function()));
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index a278799..4682e98 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -75,6 +75,10 @@
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
 
+  library = Library::InternalLibrary();
+  ASSERT(!library.IsNull());
+  library.set_native_entry_resolver(resolver);
+
   library = Library::IsolateLibrary();
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index c5e5b85..d1418c1 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -339,6 +339,7 @@
   V(GrowableList_getCapacity, 1)                                               \
   V(GrowableList_setLength, 2)                                                 \
   V(GrowableList_setData, 2)                                                   \
+  V(Internal_makeListFixedLength, 1)                                           \
   V(WeakProperty_new, 2)                                                       \
   V(WeakProperty_getKey, 1)                                                    \
   V(WeakProperty_getValue, 1)                                                  \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index ac95aee..de90c6d 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -305,7 +305,6 @@
     OS::Print("Resolving redirecting factory: %s\n",
               String::Handle(factory.name()).ToCString());
   }
-  ResolveType(cls, type);
   type ^= FinalizeType(cls, type, kCanonicalize);
   factory.SetRedirectionType(type);
   if (type.IsMalformedOrMalbounded()) {
@@ -461,16 +460,21 @@
 
 
 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) {
-  // TODO(regis): Add a kResolved bit in type_state_ for efficiency.
-  if (type.IsFinalized() || type.IsResolved()) {
+  if (type.IsResolved()) {
     return;
   }
+  ASSERT(type.IsType());
   if (FLAG_trace_type_finalization) {
     OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
   }
-
   ResolveTypeClass(cls, type);
-
+  if (type.IsMalformed()) {
+    ASSERT(type.IsResolved());
+    return;
+  }
+  // Mark type as resolved before resolving its type arguments in order to avoid
+  // repeating resolution of recursive types.
+  Type::Cast(type).set_is_resolved();
   // Resolve type arguments, if any.
   const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
   if (!arguments.IsNull()) {
@@ -768,7 +772,7 @@
     return TypeRef::New(type);
   }
 
-  ASSERT(type.IsResolved());
+  ResolveType(cls, type);
   if (FLAG_trace_type_finalization) {
     OS::Print("Finalizing type '%s' for class '%s'\n",
               String::Handle(type.Name()).ToCString(),
@@ -990,7 +994,6 @@
   AbstractType& type = AbstractType::Handle(function.result_type());
   // It is not a compile time error if this name does not resolve to a class or
   // interface.
-  ResolveType(cls, type);
   type = FinalizeType(cls, type, kCanonicalize);
   // The result type may be malformed or malbounded.
   function.set_result_type(type);
@@ -998,7 +1001,6 @@
   const intptr_t num_parameters = function.NumParameters();
   for (intptr_t i = 0; i < num_parameters; i++) {
     type = function.ParameterTypeAt(i);
-    ResolveType(cls, type);
     type = FinalizeType(cls, type, kCanonicalize);
     // The parameter type may be malformed or malbounded.
     function.SetParameterTypeAt(i, type);
@@ -1127,7 +1129,6 @@
   for (intptr_t i = 0; i < num_fields; i++) {
     field ^= array.At(i);
     type = field.type();
-    ResolveType(cls, type);
     type = FinalizeType(cls, type, kCanonicalize);
     field.set_type(type);
     name = field.name();
@@ -1407,12 +1408,12 @@
   // The mixin class cannot be Object and this was checked earlier.
   ASSERT(!mixin_class.IsObjectClass());
 
-  // Add the mixin type to the interfaces that the mixin application
-  // class implements. This is necessary so that type tests work.
-  const Array& interfaces = Array::Handle(isolate, Array::New(1));
-  interfaces.SetAt(0, mixin_type);
-  ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
-  mixin_app_class.set_interfaces(interfaces);
+  // The mixin type (in raw form) should have been added to the interfaces
+  // implemented by the mixin application class. This is necessary so that cycle
+  // check works at compile time (type arguments are ignored) and so that
+  // type tests work at runtime (by then, type arguments will have been set, see
+  // below).
+  ASSERT(mixin_app_class.interfaces() != Object::empty_array().raw());
 
   // If both the super type and the mixin type are non generic, the mixin
   // application class is non generic as well and we can skip type parameter
@@ -1675,7 +1676,16 @@
                   Object::null_type_arguments(),
                   aliased_mixin_type.token_pos()));
     inserted_class.set_mixin(generic_mixin_type);
-    // The interface will be set in CloneMixinAppTypeParameters.
+    // Add the mixin type to the list of interfaces that the mixin application
+    // class implements. This is necessary so that cycle check work at
+    // compile time (type arguments are ignored by that check).
+    const Array& interfaces = Array::Handle(Array::New(1));
+    interfaces.SetAt(0, generic_mixin_type);
+    ASSERT(inserted_class.interfaces() == Object::empty_array().raw());
+    inserted_class.set_interfaces(interfaces);
+    // The type arguments of the interface, if any, will be set in
+    // CloneMixinAppTypeParameters, which is called indirectly from
+    // FinalizeTypesInClass below.
   }
 
   // Finalize the types and call CloneMixinAppTypeParameters.
@@ -2453,6 +2463,13 @@
                                      Object::null_type_arguments(),
                                      mixin_type.token_pos());
       mixin_app_class.set_mixin(generic_mixin_type);
+      // Add the mixin type to the list of interfaces that the mixin application
+      // class implements. This is necessary so that cycle check work at
+      // compile time (type arguments are ignored by that check).
+      const Array& interfaces = Array::Handle(Array::New(1));
+      interfaces.SetAt(0, generic_mixin_type);
+      ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
+      mixin_app_class.set_interfaces(interfaces);
       mixin_app_class.set_is_synthesized_class();
       library.AddClass(mixin_app_class);
 
@@ -2501,6 +2518,9 @@
 // we found a loop.
 void ClassFinalizer::ResolveSuperTypeAndInterfaces(
     const Class& cls, GrowableArray<intptr_t>* visited) {
+  if (cls.is_cycle_free()) {
+    return;
+  }
   ASSERT(visited != NULL);
   if (FLAG_trace_class_finalization) {
     OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
@@ -2524,10 +2544,15 @@
   Array& super_interfaces = Array::Handle(cls.interfaces());
   if ((super_type.IsNull() || super_type.IsObjectType()) &&
       (super_interfaces.Length() == 0)) {
+    cls.set_is_cycle_free();
     return;
   }
 
   if (super_type.IsMixinAppType()) {
+    // For the cycle check below to work, ResolveMixinAppType needs to set
+    // the mixin interfaces in the super classes, even if only in raw form.
+    // It is indeed too early to set the correct type arguments, which is not
+    // a problem since they are ignored in the cycle check.
     const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type);
     super_type = ResolveMixinAppType(cls, mixin_app_type);
     cls.set_super_type(super_type);
@@ -2671,6 +2696,7 @@
     ResolveSuperTypeAndInterfaces(interface_class, visited);
   }
   visited->RemoveLast();
+  cls.set_is_cycle_free();
 }
 
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 638e571..f0d8061 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -100,9 +100,6 @@
   // Resolve the class of the type, but not the type's type arguments.
   static void ResolveTypeClass(const Class& cls, const AbstractType& type);
 
-  // Resolve the class of the type and the class of the type's type arguments.
-  static void ResolveType(const Class& cls, const AbstractType& type);
-
   // Resolve the type and target of the redirecting factory.
   static void ResolveRedirectingFactory(const Class& cls,
                                         const Function& factory);
@@ -123,6 +120,7 @@
   static void CheckForLegalConstClass(const Class& cls);
   static RawClass* ResolveClass(const Class& cls,
                                 const UnresolvedClass& unresolved_class);
+  static void ResolveType(const Class& cls, const AbstractType& type);
   static void ResolveRedirectingFactoryTarget(
       const Class& cls,
       const Function& factory,
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index cc90af3..48dfacc 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -114,9 +114,8 @@
 // Allocate a new object.
 // Arg0: class of the object that needs to be allocated.
 // Arg1: type arguments of the object that needs to be allocated.
-// Arg2: type arguments of the instantiator or kNoInstantiator.
 // Return value: newly allocated object.
-DEFINE_RUNTIME_ENTRY(AllocateObject, 3) {
+DEFINE_RUNTIME_ENTRY(AllocateObject, 2) {
   const Class& cls = Class::CheckedHandle(arguments.ArgAt(0));
   const Instance& instance = Instance::Handle(Instance::New(cls));
   arguments.SetReturn(instance);
@@ -127,48 +126,12 @@
   }
   TypeArguments& type_arguments =
       TypeArguments::CheckedHandle(arguments.ArgAt(1));
-  // If no instantiator is provided, set the type arguments and return.
-  if (Object::Handle(arguments.ArgAt(2)).IsSmi()) {
-    ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() ==
-           StubCode::kNoInstantiator);
-    // Unless null (for a raw type), the type argument vector may be longer than
-    // necessary due to a type optimization reusing the type argument vector of
-    // the instantiator.
-    ASSERT(type_arguments.IsNull() ||
-           (type_arguments.IsInstantiated() &&
-            (type_arguments.Length() >= cls.NumTypeArguments())));
-    instance.SetTypeArguments(type_arguments);  // May be null.
-    return;
-  }
-  // A still uninstantiated type argument vector must have the correct length.
-  ASSERT(!type_arguments.IsInstantiated() &&
-         (type_arguments.Length() == cls.NumTypeArguments()));
-  const TypeArguments& instantiator =
-      TypeArguments::CheckedHandle(arguments.ArgAt(2));
-  ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
-  // Code inlined in the caller should have optimized the case where the
-  // instantiator can be reused as type argument vector.
-  ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
-  if (FLAG_enable_type_checks) {
-    Error& bound_error = Error::Handle();
-    type_arguments =
-        type_arguments.InstantiateAndCanonicalizeFrom(instantiator,
-                                                      &bound_error);
-    if (!bound_error.IsNull()) {
-      // Throw a dynamic type error.
-      const intptr_t location = GetCallerLocation();
-      String& bound_error_message =  String::Handle(
-          String::New(bound_error.ToErrorCString()));
-      Exceptions::CreateAndThrowTypeError(
-          location, Symbols::Empty(), Symbols::Empty(),
-          Symbols::Empty(), bound_error_message);
-      UNREACHABLE();
-    }
-  } else {
-    type_arguments =
-        type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL);
-  }
-  ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
+  // Unless null (for a raw type), the type argument vector may be longer than
+  // necessary due to a type optimization reusing the type argument vector of
+  // the instantiator.
+  ASSERT(type_arguments.IsNull() ||
+         (type_arguments.IsInstantiated() &&
+          (type_arguments.Length() >= cls.NumTypeArguments())));
   instance.SetTypeArguments(type_arguments);
 }
 
@@ -219,13 +182,32 @@
   // Code inlined in the caller should have optimized the case where the
   // instantiator can be reused as type argument vector.
   ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
-  type_arguments =
-      type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL);
+  if (FLAG_enable_type_checks) {
+    Error& bound_error = Error::Handle();
+    type_arguments =
+        type_arguments.InstantiateAndCanonicalizeFrom(instantiator,
+                                                      &bound_error);
+    if (!bound_error.IsNull()) {
+      // Throw a dynamic type error.
+      const intptr_t location = GetCallerLocation();
+      String& bound_error_message =  String::Handle(
+          String::New(bound_error.ToErrorCString()));
+      Exceptions::CreateAndThrowTypeError(
+          location, Symbols::Empty(), Symbols::Empty(),
+          Symbols::Empty(), bound_error_message);
+      UNREACHABLE();
+    }
+  } else {
+    type_arguments =
+        type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL);
+  }
   ASSERT(type_arguments.IsInstantiated());
   arguments.SetReturn(type_arguments);
 }
 
 
+// TODO(regis): Not used anymore. Delete.
+
 // Allocate a new closure.
 // The type argument vector of a closure is always the vector of type parameters
 // of its signature class, i.e. an uninstantiated identity vector. Therefore,
@@ -1222,8 +1204,8 @@
     isolate->message_handler()->HandleOOBMessages();
   }
   if (interrupt_bits & Isolate::kApiInterrupt) {
-    // Signal isolate interrupt  event.
-    Debugger::SignalIsolateEvent(Debugger::kIsolateInterrupted);
+    // Signal isolate interrupt event.
+    Debugger::SignalIsolateInterrupted();
 
     Dart_IsolateInterruptCallback callback = isolate->InterruptCallback();
     if (callback) {
diff --git a/runtime/vm/code_patcher.cc b/runtime/vm/code_patcher.cc
index f2b325d..46f8a4d 100644
--- a/runtime/vm/code_patcher.cc
+++ b/runtime/vm/code_patcher.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, write_protect_code, false, "Write protect jitted code");
+DEFINE_FLAG(bool, write_protect_code, true, "Write protect jitted code");
 
 
 WritableInstructionsScope::WritableInstructionsScope(uword address,
diff --git a/runtime/vm/cpu.h b/runtime/vm/cpu.h
index c8f5e9c..9546f17 100644
--- a/runtime/vm/cpu.h
+++ b/runtime/vm/cpu.h
@@ -5,6 +5,7 @@
 #ifndef VM_CPU_H_
 #define VM_CPU_H_
 
+#include "vm/globals.h"
 #include "vm/allocation.h"
 
 namespace dart {
@@ -22,4 +23,16 @@
 
 }  // namespace dart
 
+#if defined(TARGET_ARCH_IA32)
+#include "vm/cpu_ia32.h"
+#elif defined(TARGET_ARCH_X64)
+#include "vm/cpu_x64.h"
+#elif defined(TARGET_ARCH_ARM)
+#include "vm/cpu_arm.h"
+#elif defined(TARGET_ARCH_MIPS)
+#include "vm/cpu_mips.h"
+#else
+#error Unknown architecture.
+#endif
+
 #endif  // VM_CPU_H_
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 2807cee..1100c26 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -6,13 +6,15 @@
 
 #if defined(TARGET_ARCH_ARM)
 
+#include "vm/cpu.h"
+#include "vm/cpuinfo.h"
+#include "vm/simulator.h"
+
 #if defined(HOST_ARCH_ARM)
 #include <sys/syscall.h>  /* NOLINT */
 #include <unistd.h>  /* NOLINT */
 #endif
 
-#include "vm/cpu.h"
-
 namespace dart {
 
 void CPU::FlushICache(uword start, uword size) {
@@ -48,6 +50,75 @@
   "arm";
 }
 
+
+bool HostCPUFeatures::integer_division_supported_ = false;
+bool HostCPUFeatures::neon_supported_ = false;
+const char* HostCPUFeatures::hardware_ = NULL;
+#if defined(DEBUG)
+bool HostCPUFeatures::initialized_ = false;
+#endif
+
+
+#if defined(HOST_ARCH_ARM)
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+  hardware_ = CpuInfo::GetCpuModel();
+  // Implements ARMv7.
+  ASSERT(CpuInfo::FieldContains(kCpuInfoProcessor, "ARMv7"));
+  // Has floating point unit.
+  ASSERT(CpuInfo::FieldContains(kCpuInfoFeatures, "vfp"));
+  // Has integer division.
+  bool is_krait = CpuInfo::FieldContains(kCpuInfoModel, "QCT APQ8064");
+  if (is_krait) {
+    // Special case for Qualcomm Krait CPUs in Nexus 4 and 7.
+    integer_division_supported_ = true;
+  } else {
+    integer_division_supported_ =
+        CpuInfo::FieldContains(kCpuInfoFeatures, "idiva");
+  }
+  neon_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "neon");
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+
+#else
+
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+  hardware_ = CpuInfo::GetCpuModel();
+  integer_division_supported_ = true;
+  neon_supported_ = true;
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+#endif  // defined(HOST_ARCH_ARM)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/cpu_arm.h b/runtime/vm/cpu_arm.h
new file mode 100644
index 0000000..cbcac11
--- /dev/null
+++ b/runtime/vm/cpu_arm.h
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef VM_CPU_ARM_H_
+#define VM_CPU_ARM_H_
+
+#include "vm/allocation.h"
+#include "vm/simulator.h"
+
+namespace dart {
+
+// TargetCPUFeatures gives CPU features for the architecture that we are
+// generating code for. HostCPUFeatures gives the CPU features for the
+// architecture that we are actually running on. When the architectures
+// are the same, TargetCPUFeatures will query HostCPUFeatures. When they are
+// different (i.e. we are running in a simulator), HostCPUFeatures will
+// additionally mock the options needed for the target architecture so that
+// they may be altered for testing.
+
+class HostCPUFeatures: public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+  static const char* hardware() {
+    DEBUG_ASSERT(initialized_);
+    return hardware_;
+  }
+  static bool integer_division_supported() {
+    DEBUG_ASSERT(initialized_);
+    return integer_division_supported_;
+  }
+  static bool neon_supported() {
+    DEBUG_ASSERT(initialized_);
+    return neon_supported_;
+  }
+
+#if !defined(HOST_ARCH_ARM)
+  static void set_integer_division_supported(bool supported) {
+    DEBUG_ASSERT(initialized_);
+    integer_division_supported_ = supported;
+  }
+  static void set_neon_supported(bool supported) {
+    DEBUG_ASSERT(initialized_);
+    neon_supported_ = supported;
+  }
+#endif  // !defined(HOST_ARCH_ARM)
+
+ private:
+  static const char* hardware_;
+  static bool integer_division_supported_;
+  static bool neon_supported_;
+#if defined(DEBUG)
+  static bool initialized_;
+#endif
+};
+
+class TargetCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce() {
+    HostCPUFeatures::InitOnce();
+  }
+  static void Cleanup() {
+    HostCPUFeatures::Cleanup();
+  }
+  static bool double_truncate_round_supported() {
+    return false;
+  }
+  static bool integer_division_supported() {
+    return HostCPUFeatures::integer_division_supported();
+  }
+  static bool neon_supported() {
+    return HostCPUFeatures::neon_supported();
+  }
+  static const char* hardware() {
+    return HostCPUFeatures::hardware();
+  }
+};
+
+}  // namespace dart
+
+#endif  // VM_CPU_ARM_H_
diff --git a/runtime/vm/cpu_ia32.cc b/runtime/vm/cpu_ia32.cc
index 8f3fae1..8158e3a 100644
--- a/runtime/vm/cpu_ia32.cc
+++ b/runtime/vm/cpu_ia32.cc
@@ -3,18 +3,22 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
-
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/cpu.h"
 
+#include "vm/assembler.h"
 #include "vm/constants_ia32.h"
+#include "vm/cpuinfo.h"
 #include "vm/heap.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
+#include "vm/thread.h"
 
 namespace dart {
 
+DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
+
 void CPU::FlushICache(uword start, uword size) {
   // Nothing to be done here.
 }
@@ -24,6 +28,40 @@
   return "ia32";
 }
 
+
+bool HostCPUFeatures::sse2_supported_ = false;
+bool HostCPUFeatures::sse4_1_supported_ = false;
+const char* HostCPUFeatures::hardware_ = NULL;
+#if defined(DEBUG)
+bool HostCPUFeatures::initialized_ = false;
+#endif
+
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+
+  hardware_ = CpuInfo::GetCpuModel();
+  sse2_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "sse2");
+  sse4_1_supported_ =
+      CpuInfo::FieldContains(kCpuInfoFeatures, "sse4_1") ||
+      CpuInfo::FieldContains(kCpuInfoFeatures, "sse4.1");
+
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/cpu_ia32.h b/runtime/vm/cpu_ia32.h
new file mode 100644
index 0000000..66f4724
--- /dev/null
+++ b/runtime/vm/cpu_ia32.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef VM_CPU_IA32_H_
+#define VM_CPU_IA32_H_
+
+#include "vm/allocation.h"
+#include "vm/flags.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, use_sse41);
+
+class HostCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+  static const char* hardware() {
+    DEBUG_ASSERT(initialized_);
+    return hardware_;
+  }
+  static bool sse2_supported() {
+    DEBUG_ASSERT(initialized_);
+    return sse2_supported_;
+  }
+  static bool sse4_1_supported() {
+    DEBUG_ASSERT(initialized_);
+    return sse4_1_supported_ && FLAG_use_sse41;
+  }
+
+ private:
+  static const uint64_t kSSE2BitMask = static_cast<uint64_t>(1) << 26;
+  static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
+  static const char* hardware_;
+  static bool sse2_supported_;
+  static bool sse4_1_supported_;
+#if defined(DEBUG)
+  static bool initialized_;
+#endif
+};
+
+class TargetCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce() {
+    HostCPUFeatures::InitOnce();
+  }
+  static void Cleanup() {
+    HostCPUFeatures::Cleanup();
+  }
+  static const char* hardware() {
+    return HostCPUFeatures::hardware();
+  }
+  static bool sse2_supported() {
+    return HostCPUFeatures::sse2_supported();
+  }
+  static bool sse4_1_supported() {
+    return HostCPUFeatures::sse4_1_supported();
+  }
+  static bool double_truncate_round_supported() {
+    return sse4_1_supported();
+  }
+};
+
+}  // namespace dart
+
+#endif  // VM_CPU_IA32_H_
diff --git a/runtime/vm/cpu_mips.cc b/runtime/vm/cpu_mips.cc
index 095ec4c..3d26cd6 100644
--- a/runtime/vm/cpu_mips.cc
+++ b/runtime/vm/cpu_mips.cc
@@ -6,14 +6,16 @@
 
 #if defined(TARGET_ARCH_MIPS)
 
+#include "vm/cpu.h"
+#include "vm/cpuinfo.h"
+#include "vm/simulator.h"
+
 #if defined(HOST_ARCH_MIPS)
 #include <asm/cachectl.h> /* NOLINT */
 #include <sys/syscall.h>  /* NOLINT */
 #include <unistd.h>  /* NOLINT */
 #endif
 
-#include "vm/cpu.h"
-
 namespace dart {
 
 void CPU::FlushICache(uword start, uword size) {
@@ -37,6 +39,59 @@
   "mips";
 }
 
+
+const char* HostCPUFeatures::hardware_ = NULL;
+#if defined(DEBUG)
+bool HostCPUFeatures::initialized_ = false;
+#endif
+
+
+#if defined(HOST_ARCH_MIPS)
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+  hardware_ = CpuInfo::GetCpuModel();
+  // Has a floating point unit.
+  ASSERT(CpuInfo::FieldContains(kCpuInfoModel, "FPU"));
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+
+#else
+
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+  hardware_ = CpuInfo::GetCpuModel();
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+#endif  // defined(HOST_ARCH_MIPS)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/cpu_mips.h b/runtime/vm/cpu_mips.h
new file mode 100644
index 0000000..e6c8f19
--- /dev/null
+++ b/runtime/vm/cpu_mips.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef VM_CPU_MIPS_H_
+#define VM_CPU_MIPS_H_
+
+#include "vm/allocation.h"
+
+namespace dart {
+
+// TargetCPUFeatures gives CPU features for the architecture that we are
+// generating code for. HostCPUFeatures gives the CPU features for the
+// architecture that we are actually running on. When the architectures
+// are the same, TargetCPUFeatures will query HostCPUFeatures. When they are
+// different (i.e. we are running in a simulator), HostCPUFeatures will
+// additionally mock the options needed for the target architecture so that
+// they may be altered for testing.
+
+class HostCPUFeatures: public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+  static const char* hardware() {
+    DEBUG_ASSERT(initialized_);
+    return hardware_;
+  }
+
+ private:
+  static const char* hardware_;
+#if defined(DEBUG)
+  static bool initialized_;
+#endif
+};
+
+class TargetCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce() {
+    HostCPUFeatures::InitOnce();
+  }
+  static void Cleanup() {
+    HostCPUFeatures::Cleanup();
+  }
+  static const char* hardware() {
+    return HostCPUFeatures::hardware();
+  }
+  static bool double_truncate_round_supported() {
+    return false;
+  }
+};
+
+}  // namespace dart
+
+#endif  // VM_CPU_MIPS_H_
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc
index 295a2e6..31c4ec7 100644
--- a/runtime/vm/cpu_x64.cc
+++ b/runtime/vm/cpu_x64.cc
@@ -8,13 +8,18 @@
 
 #include "vm/cpu.h"
 
+#include "vm/assembler.h"
 #include "vm/constants_x64.h"
+#include "vm/cpuinfo.h"
 #include "vm/heap.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 
 namespace dart {
 
+DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
+
+
 void CPU::FlushICache(uword start, uword size) {
   // Nothing to be done here.
 }
@@ -24,6 +29,38 @@
   return "x64";
 }
 
+
+bool HostCPUFeatures::sse2_supported_ = true;
+bool HostCPUFeatures::sse4_1_supported_ = false;
+const char* HostCPUFeatures::hardware_ = NULL;
+#if defined(DEBUG)
+bool HostCPUFeatures::initialized_ = false;
+#endif
+
+void HostCPUFeatures::InitOnce() {
+  CpuInfo::InitOnce();
+  hardware_ = CpuInfo::GetCpuModel();
+  sse4_1_supported_ =
+      CpuInfo::FieldContains(kCpuInfoFeatures, "sse4_1") ||
+      CpuInfo::FieldContains(kCpuInfoFeatures, "sse4.1");
+
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+  DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+  initialized_ = false;
+#endif
+  ASSERT(hardware_ != NULL);
+  delete[] hardware_;
+  hardware_ = NULL;
+  CpuInfo::Cleanup();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/cpu_x64.h b/runtime/vm/cpu_x64.h
new file mode 100644
index 0000000..579650a
--- /dev/null
+++ b/runtime/vm/cpu_x64.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef VM_CPU_X64_H_
+#define VM_CPU_X64_H_
+
+#include "vm/allocation.h"
+#include "vm/flags.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, use_sse41);
+
+class HostCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+  static const char* hardware() {
+    DEBUG_ASSERT(initialized_);
+    return hardware_;
+  }
+  static bool sse2_supported() {
+    DEBUG_ASSERT(initialized_);
+    return sse2_supported_;
+  }
+  static bool sse4_1_supported() {
+    DEBUG_ASSERT(initialized_);
+    return sse4_1_supported_ && FLAG_use_sse41;
+  }
+
+ private:
+  static const uint64_t kSSE2BitMask = static_cast<uint64_t>(1) << 26;
+  static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
+  static const char* hardware_;
+  static bool sse2_supported_;
+  static bool sse4_1_supported_;
+#if defined(DEBUG)
+  static bool initialized_;
+#endif
+};
+
+class TargetCPUFeatures : public AllStatic {
+ public:
+  static void InitOnce() {
+    HostCPUFeatures::InitOnce();
+  }
+  static void Cleanup() {
+    HostCPUFeatures::Cleanup();
+  }
+  static const char* hardware() {
+    return HostCPUFeatures::hardware();
+  }
+  static bool sse2_supported() {
+    return HostCPUFeatures::sse2_supported();
+  }
+  static bool sse4_1_supported() {
+    return HostCPUFeatures::sse4_1_supported();
+  }
+  static bool double_truncate_round_supported() {
+    return false;
+  }
+};
+
+}  // namespace dart
+
+#endif  // VM_CPU_X64_H_
diff --git a/runtime/vm/cpuid.cc b/runtime/vm/cpuid.cc
new file mode 100644
index 0000000..45499b4
--- /dev/null
+++ b/runtime/vm/cpuid.cc
@@ -0,0 +1,116 @@
+// 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.
+
+#include "vm/globals.h"
+#if !defined(TARGET_OS_MACOS)
+#include "vm/cpuid.h"
+
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+// GetCpuId() on Windows, __get_cpuid() on Linux
+#if defined(TARGET_OS_WINDOWS)
+#include <intrin.h>  // NOLINT
+#else
+#include <cpuid.h>  // NOLINT
+#endif
+#endif
+
+namespace dart {
+
+bool CpuId::sse2_ = false;
+bool CpuId::sse41_ = false;
+const char* CpuId::id_string_ = NULL;
+const char* CpuId::brand_string_ = NULL;
+
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+
+void CpuId::GetCpuId(int32_t level, uint32_t info[4]) {
+#if defined(TARGET_OS_WINDOWS)
+  // The documentation for __cpuid is at:
+  // http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx
+  __cpuid(reinterpret_cast<int*>(info), level);
+#else
+  __get_cpuid(level, &info[0], &info[1], &info[2], &info[3]);
+#endif
+}
+
+
+void CpuId::InitOnce() {
+  uint32_t info[4] = {-1};
+
+  GetCpuId(0, info);
+  char* id_string = new char[3 * sizeof(int32_t)];
+  // Yes, these are supposed to be out of order.
+  *reinterpret_cast<uint32_t*>(id_string) = info[1];
+  *reinterpret_cast<uint32_t*>(id_string + 4) = info[3];
+  *reinterpret_cast<uint32_t*>(id_string + 8) = info[2];
+  CpuId::id_string_ = id_string;
+
+  GetCpuId(1, info);
+  CpuId::sse41_ = (info[2] & (1 << 19)) != 0;
+  CpuId::sse2_ = (info[3] & (1 << 26)) != 0;
+
+  char* brand_string = new char[3 * 4 * sizeof(uint32_t)];
+  for (uint32_t i = 0x80000002; i <= 0x80000004; i++) {
+    uint32_t off = (i - 0x80000002U) * 4 * sizeof(uint32_t);
+    GetCpuId(i, info);
+    *reinterpret_cast<int32_t*>(brand_string + off) = info[0];
+    *reinterpret_cast<int32_t*>(brand_string + off + 4) = info[1];
+    *reinterpret_cast<int32_t*>(brand_string + off + 8) = info[2];
+    *reinterpret_cast<int32_t*>(brand_string + off + 12) = info[3];
+  }
+  CpuId::brand_string_ = brand_string;
+}
+
+
+void CpuId::Cleanup() {
+  ASSERT(id_string_ != NULL);
+  delete[] id_string_;
+  id_string_ = NULL;
+
+  ASSERT(brand_string_ != NULL);
+  delete[] brand_string_;
+  brand_string_ = NULL;
+}
+
+
+const char* CpuId::id_string() {
+  return strdup(id_string_);
+}
+
+
+const char* CpuId::brand_string() {
+  return strdup(brand_string_);
+}
+
+
+const char* CpuId::field(CpuInfoIndices idx) {
+  switch (idx) {
+    case kCpuInfoProcessor:
+      return id_string();
+    case kCpuInfoModel:
+      return brand_string();
+    case kCpuInfoHardware:
+      return brand_string();
+    case kCpuInfoFeatures: {
+      if (sse2() && sse41()) {
+        return strdup("sse2 sse4.1");
+      } else if (sse2()) {
+        return strdup("sse2");
+      } else if (sse41()) {
+        return strdup("sse4.1");
+      } else {
+        return strdup("");
+      }
+    }
+    default: {
+      UNREACHABLE();
+      return NULL;
+    }
+  }
+}
+
+#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+}  // namespace dart
+
+#endif  // !defined(TARGET_OS_MACOS)
diff --git a/runtime/vm/cpuid.h b/runtime/vm/cpuid.h
new file mode 100644
index 0000000..b9d193a
--- /dev/null
+++ b/runtime/vm/cpuid.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef VM_CPUID_H_
+#define VM_CPUID_H_
+
+#include "vm/globals.h"
+#if !defined(TARGET_OS_MACOS)
+#include "vm/allocation.h"
+#include "vm/cpuinfo.h"
+
+namespace dart {
+
+class CpuId : public AllStatic {
+ public:
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+  static void InitOnce();
+  static void Cleanup();
+
+  // Caller must free the result of field.
+  static const char* field(CpuInfoIndices idx);
+#else
+  static void InitOnce() {}
+  static void Cleanup() {}
+  static const char* field(CpuInfoIndices idx) { return NULL; }
+#endif
+
+  static bool sse2() { return sse2_; }
+  static bool sse41() { return sse41_; }
+
+  // Caller must free the result of id_string and brand_string.
+  static const char* id_string();
+  static const char* brand_string();
+
+ private:
+  static bool sse2_;
+  static bool sse41_;
+  static const char* id_string_;
+  static const char* brand_string_;
+
+  static void GetCpuId(int32_t level, uint32_t info[4]);
+};
+
+}  // namespace dart
+
+#endif  // !defined(TARGET_OS_MACOS)
+#endif  // VM_CPUID_H_
diff --git a/runtime/vm/cpuinfo.h b/runtime/vm/cpuinfo.h
new file mode 100644
index 0000000..f0f73b5
--- /dev/null
+++ b/runtime/vm/cpuinfo.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef VM_CPUINFO_H_
+#define VM_CPUINFO_H_
+
+#include "platform/assert.h"
+#include "vm/allocation.h"
+
+namespace dart {
+
+// Indices into cpuinfo field name arrays.
+enum CpuInfoIndices {
+  kCpuInfoProcessor = 0,
+  kCpuInfoModel = 1,
+  kCpuInfoHardware = 2,
+  kCpuInfoFeatures = 3,
+  kCpuInfoMax = 4,
+};
+
+// For Intel architectures, the method to use to get CPU information.
+enum CpuInfoMethod {
+  // Use the cpuid instruction.
+  kCpuInfoCpuId,
+
+  // Use system calls.
+  kCpuInfoSystem,
+
+  // Use whatever the default is for a particular OS:
+  // Linux, Windows -> CpuId,
+  // Android, MacOS -> System.
+  kCpuInfoDefault,
+};
+
+class CpuInfo : public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+
+  static const char* FieldName(CpuInfoIndices idx) {
+    ASSERT((idx >= 0) && (idx < kCpuInfoMax));
+    return fields_[idx];
+  }
+
+  // Returns true if the cpuinfo field contains the string.
+  static bool FieldContains(CpuInfoIndices idx, const char* search_string);
+  static bool FieldContainsByString(
+      const char* field, const char* search_string);
+
+  // Returns true if the cpuinfo field [field] exists and is non-empty.
+  static bool HasField(const char* field);
+
+  // Returns the field. Caller is responsible for freeing the result.
+  static const char* ExtractField(CpuInfoIndices idx);
+  static const char* ExtractFieldByString(const char* field);
+
+  // Returns the field describing the CPU model. Caller is responsible for
+  // freeing the result.
+  static const char* GetCpuModel() {
+    ASSERT(HasField(FieldName(kCpuInfoModel)));
+    return ExtractField(kCpuInfoModel);
+  }
+
+ private:
+  // The method to use to acquire info about the CPU.
+  static CpuInfoMethod method_;
+
+  // Cpuinfo field names.
+  static const char* fields_[kCpuInfoMax];
+};
+
+}  // namespace dart
+
+#endif  // VM_CPUINFO_H_
diff --git a/runtime/vm/cpuinfo_android.cc b/runtime/vm/cpuinfo_android.cc
new file mode 100644
index 0000000..ba90d25
--- /dev/null
+++ b/runtime/vm/cpuinfo_android.cc
@@ -0,0 +1,81 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_ANDROID)
+
+#include "vm/cpuinfo.h"
+#include "vm/proccpuinfo.h"
+
+#include "platform/assert.h"
+
+namespace dart {
+
+CpuInfoMethod CpuInfo::method_ = kCpuInfoDefault;
+const char* CpuInfo::fields_[kCpuInfoMax] = {0};
+
+void CpuInfo::InitOnce() {
+  // Initialize our read from /proc/cpuinfo.
+  method_ = kCpuInfoSystem;
+  ProcCpuInfo::InitOnce();
+
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+  fields_[kCpuInfoProcessor] = "vendor_id";
+  fields_[kCpuInfoModel] = "model name";
+  fields_[kCpuInfoHardware] = "model name";
+  fields_[kCpuInfoFeatures] = "flags";
+#elif defined(HOST_ARCH_ARM)
+  fields_[kCpuInfoProcessor] = "Processor";
+  fields_[kCpuInfoModel] = "Hardware";
+  fields_[kCpuInfoHardware] = "Hardware";
+  fields_[kCpuInfoFeatures] = "Features";
+#elif defined(HOST_ARCH_MIPS)
+  fields_[kCpuInfoProcessor] = "system type";
+  fields_[kCpuInfoModel] = "cpu model";
+  fields_[kCpuInfoHardware] = "cpu model";
+  fields_[kCpuInfoFeatures] = "ASEs implemented";
+#else
+#error Unrecognized target architecture
+#endif
+}
+
+
+void CpuInfo::Cleanup() {
+  ProcCpuInfo::Cleanup();
+}
+
+
+bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ProcCpuInfo::FieldContains(FieldName(idx), search_string);
+}
+
+
+bool CpuInfo::FieldContainsByString(const char* field,
+                                    const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ProcCpuInfo::FieldContains(field, search_string);
+}
+
+
+const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ProcCpuInfo::ExtractField(FieldName(idx));
+}
+
+
+const char* CpuInfo::ExtractFieldByString(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ProcCpuInfo::ExtractField(field);
+}
+
+
+bool CpuInfo::HasField(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ProcCpuInfo::HasField(field);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/vm/cpuinfo_linux.cc b/runtime/vm/cpuinfo_linux.cc
new file mode 100644
index 0000000..8e80ab9
--- /dev/null
+++ b/runtime/vm/cpuinfo_linux.cc
@@ -0,0 +1,128 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_LINUX)
+
+#include "vm/cpuinfo.h"
+#include "vm/cpuid.h"
+#include "vm/proccpuinfo.h"
+
+#include "platform/assert.h"
+
+// As with Windows, on IA32 and X64, we use the cpuid instruction.
+// The analogous instruction is privileged on ARM and MIPS, so we resort to
+// reading from /proc/cpuinfo.
+
+namespace dart {
+
+CpuInfoMethod CpuInfo::method_ = kCpuInfoDefault;
+const char* CpuInfo::fields_[kCpuInfoMax] = {0};
+
+void CpuInfo::InitOnce() {
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+  fields_[kCpuInfoProcessor] = "vendor_id";
+  fields_[kCpuInfoModel] = "model name";
+  fields_[kCpuInfoHardware] = "model name";
+  fields_[kCpuInfoFeatures] = "flags";
+  method_ = kCpuInfoCpuId;
+  CpuId::InitOnce();
+#elif defined(HOST_ARCH_ARM)
+  fields_[kCpuInfoProcessor] = "Processor";
+  fields_[kCpuInfoModel] = "Hardware";
+  fields_[kCpuInfoHardware] = "Hardware";
+  fields_[kCpuInfoFeatures] = "Features";
+  method_ = kCpuInfoSystem;
+  ProcCpuInfo::InitOnce();
+#elif defined(HOST_ARCH_MIPS)
+  fields_[kCpuInfoProcessor] = "system type";
+  fields_[kCpuInfoModel] = "cpu model";
+  fields_[kCpuInfoHardware] = "cpu model";
+  fields_[kCpuInfoFeatures] = "ASEs implemented";
+  method_ = kCpuInfoSystem;
+  ProcCpuInfo::InitOnce();
+#else
+#error Unrecognized target architecture
+#endif
+}
+
+
+void CpuInfo::Cleanup() {
+  if (method_ == kCpuInfoCpuId) {
+    CpuId::Cleanup();
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    ProcCpuInfo::Cleanup();
+  }
+}
+
+
+bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
+  if (method_ == kCpuInfoCpuId) {
+    return strstr(CpuId::field(idx), search_string);
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    return ProcCpuInfo::FieldContains(FieldName(idx), search_string);
+  }
+}
+
+
+bool CpuInfo::FieldContainsByString(const char* field,
+                                    const char* search_string) {
+  if (method_ == kCpuInfoCpuId) {
+    for (int i = 0; i < kCpuInfoMax; i++) {
+      if (strcmp(field, fields_[i]) == 0) {
+        return FieldContains(static_cast<CpuInfoIndices>(i), search_string);
+      }
+    }
+    UNIMPLEMENTED();
+    return false;
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    return ProcCpuInfo::FieldContains(field, search_string);
+  }
+}
+
+
+const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
+  if (method_ == kCpuInfoCpuId) {
+    return CpuId::field(idx);
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    return ProcCpuInfo::ExtractField(FieldName(idx));
+  }
+}
+
+
+const char* CpuInfo::ExtractFieldByString(const char* field) {
+  if (method_ == kCpuInfoCpuId) {
+    for (int i = 0; i < kCpuInfoMax; i++) {
+      if (strcmp(field, fields_[i]) == 0) {
+        return ExtractField(static_cast<CpuInfoIndices>(i));
+      }
+    }
+    UNIMPLEMENTED();
+    return NULL;
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    return ProcCpuInfo::ExtractField(field);
+  }
+}
+
+
+bool CpuInfo::HasField(const char* field) {
+  if (method_ == kCpuInfoCpuId) {
+    return (strcmp(field, fields_[kCpuInfoProcessor]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoModel]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoHardware]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoFeatures]) == 0);
+  } else {
+    ASSERT(method_ == kCpuInfoSystem);
+    return ProcCpuInfo::HasField(field);
+  }
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/vm/cpuinfo_macos.cc b/runtime/vm/cpuinfo_macos.cc
new file mode 100644
index 0000000..6300d7c
--- /dev/null
+++ b/runtime/vm/cpuinfo_macos.cc
@@ -0,0 +1,93 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_MACOS)
+
+#include "vm/cpuinfo.h"
+
+#include <errno.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <sys/sysctl.h>  // NOLINT
+
+#include "platform/assert.h"
+
+namespace dart {
+
+CpuInfoMethod CpuInfo::method_ = kCpuInfoDefault;
+const char* CpuInfo::fields_[kCpuInfoMax] = {0};
+
+void CpuInfo::InitOnce() {
+  method_ = kCpuInfoSystem;
+
+  fields_[kCpuInfoProcessor] = "machdep.cpu.vendor";
+  fields_[kCpuInfoModel] = "machdep.cpu.brand_string";
+  fields_[kCpuInfoHardware] = "machdep.cpu.brand_string";
+  fields_[kCpuInfoFeatures] = "machdep.cpu.features";
+}
+
+
+void CpuInfo::Cleanup() {}
+
+
+bool CpuInfo::FieldContainsByString(const char* field,
+                                    const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  ASSERT(search_string != NULL);
+  char dest[1024];
+  size_t dest_len = 1024;
+
+  ASSERT(HasField(field));
+  if (sysctlbyname(field, dest, &dest_len, NULL, 0) != 0) {
+    UNREACHABLE();
+    return false;
+  }
+
+  return (strcasestr(dest, search_string) != NULL);
+}
+
+
+bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return FieldContainsByString(FieldName(idx), search_string);
+}
+
+
+const char* CpuInfo::ExtractFieldByString(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  ASSERT(field != NULL);
+  size_t result_len;
+
+  ASSERT(HasField(field));
+  if (sysctlbyname(field, NULL, &result_len, NULL, 0) != 0) {
+    UNREACHABLE();
+    return 0;
+  }
+
+  char* result = new char[result_len];
+  if (sysctlbyname(field, result, &result_len, NULL, 0) != 0) {
+    UNREACHABLE();
+    return 0;
+  }
+
+  return result;
+}
+
+
+const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return ExtractFieldByString(FieldName(idx));
+}
+
+
+bool CpuInfo::HasField(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  ASSERT(field != NULL);
+  int ret = sysctlbyname(field, NULL, NULL, NULL, 0);
+  return (ret != ENOENT);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/vm/cpuinfo_test.cc b/runtime/vm/cpuinfo_test.cc
new file mode 100644
index 0000000..e717d28
--- /dev/null
+++ b/runtime/vm/cpuinfo_test.cc
@@ -0,0 +1,19 @@
+// 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.
+
+#include "platform/assert.h"
+#include "vm/cpuinfo.h"
+#include "vm/globals.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+UNIT_TEST_CASE(GetCpuModelTest) {
+  CpuInfo::InitOnce();
+  const char* cpumodel = CpuInfo::GetCpuModel();
+  EXPECT_NE(strlen(cpumodel), 0UL);
+  CpuInfo::Cleanup();
+}
+
+}  // namespace dart
diff --git a/runtime/vm/cpuinfo_win.cc b/runtime/vm/cpuinfo_win.cc
new file mode 100644
index 0000000..b648566
--- /dev/null
+++ b/runtime/vm/cpuinfo_win.cc
@@ -0,0 +1,87 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_WINDOWS)
+
+#include "vm/cpuinfo.h"
+#include "vm/cpuid.h"
+
+// __cpuid()
+#include <intrin.h>  // NOLINT
+#include <string.h>  // NOLINT
+
+#include "platform/assert.h"
+
+namespace dart {
+
+CpuInfoMethod CpuInfo::method_ = kCpuInfoDefault;
+const char* CpuInfo::fields_[kCpuInfoMax] = {0};
+
+void CpuInfo::InitOnce() {
+  method_ = kCpuInfoCpuId;
+
+  // Initialize the CpuId information.
+  CpuId::InitOnce();
+
+  fields_[kCpuInfoProcessor] = "Processor";
+  fields_[kCpuInfoModel] = "Hardware";
+  fields_[kCpuInfoHardware] = "Hardware";
+  fields_[kCpuInfoFeatures] = "Features";
+}
+
+
+void CpuInfo::Cleanup() {
+  CpuId::Cleanup();
+}
+
+
+bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return strstr(CpuId::field(idx), search_string);
+}
+
+
+bool CpuInfo::FieldContainsByString(const char* field,
+                                    const char* search_string) {
+  ASSERT(method_ != kCpuInfoDefault);
+  for (int i = 0; i < kCpuInfoMax; i++) {
+    if (strcmp(field, fields_[i]) == 0) {
+      return FieldContains(static_cast<CpuInfoIndices>(i), search_string);
+    }
+  }
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return CpuId::field(idx);
+}
+
+
+const char* CpuInfo::ExtractFieldByString(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  for (int i = 0; i < kCpuInfoMax; i++) {
+    if (strcmp(field, fields_[i]) == 0) {
+      return ExtractField(static_cast<CpuInfoIndices>(i));
+    }
+  }
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+bool CpuInfo::HasField(const char* field) {
+  ASSERT(method_ != kCpuInfoDefault);
+  return (strcmp(field, fields_[kCpuInfoProcessor]) == 0) ||
+         (strcmp(field, fields_[kCpuInfoModel]) == 0) ||
+         (strcmp(field, fields_[kCpuInfoHardware]) == 0) ||
+         (strcmp(field, fields_[kCpuInfoFeatures]) == 0);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 3639ffa..45f51e3 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -5,6 +5,7 @@
 #include "vm/dart.h"
 
 #include "vm/code_observers.h"
+#include "vm/cpu.h"
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/flags.h"
@@ -123,10 +124,10 @@
     Symbols::InitOnce(vm_isolate_);
     Scanner::InitOnce();
     Object::CreateInternalMetaData();
-    CPUFeatures::InitOnce();
+    TargetCPUFeatures::InitOnce();
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
     // Dart VM requires at least SSE2.
-    if (!CPUFeatures::sse2_supported()) {
+    if (!TargetCPUFeatures::sse2_supported()) {
       return "SSE2 is required.";
     }
 #endif
@@ -178,6 +179,7 @@
 
   Profiler::Shutdown();
   CodeObservers::DeleteAll();
+  TargetCPUFeatures::Cleanup();
 
   return NULL;
 }
@@ -216,7 +218,7 @@
     const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer);
     ASSERT(snapshot->kind() == Snapshot::kFull);
     if (FLAG_trace_isolates) {
-      OS::Print("Size of isolate snapshot = %d\n", snapshot->length());
+      OS::Print("Size of isolate snapshot = %" Pd64 "\n", snapshot->length());
     }
     SnapshotReader reader(snapshot->content(), snapshot->length(),
                           Snapshot::kFull, isolate);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 17c7f33..b0c575e 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -3779,7 +3779,7 @@
         "%s: invalid index %d passed in to access native instance field",
         CURRENT_FUNC, index);
   }
-  *value = instance.GetNativeField(isolate, index);
+  *value = instance.GetNativeField(index);
   return Api::Success();
 }
 
@@ -3831,38 +3831,43 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_GetNativeFieldOfArgument(Dart_NativeArguments args,
-                                                      int arg_index,
-                                                      int fld_index,
-                                                      intptr_t* value) {
+DART_EXPORT Dart_Handle Dart_GetNativeFieldsOfArgument(
+    Dart_NativeArguments args,
+    int arg_index,
+    int num_fields,
+    intptr_t* field_values) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((arg_index < 0) || (arg_index >= arguments->NativeArgCount())) {
     return Api::NewError(
         "%s: argument 'arg_index' out of range. Expected 0..%d but saw %d.",
         CURRENT_FUNC, arguments->NativeArgCount() - 1, arg_index);
   }
+  if (field_values == NULL) {
+    RETURN_NULL_ERROR(field_values);
+  }
   Isolate* isolate = arguments->isolate();
   DARTSCOPE(isolate);
-  const Object& obj = Object::Handle(isolate,
-                                     arguments->NativeArgAt(arg_index));
+  ReusableObjectHandleScope reused_obj_handle(isolate);
+  Object& obj = reused_obj_handle.Handle();
+  obj = arguments->NativeArgAt(arg_index);
+  if (obj.IsNull()) {
+    for (intptr_t i = 0; i < num_fields; i++) {
+      field_values[i] = 0;
+    }
+    return Api::Success();
+  }
   if (!obj.IsInstance()) {
     return Api::NewError("%s expects argument at index '%d' to be of"
                          " type Instance.", CURRENT_FUNC, arg_index);
   }
-  if (obj.IsNull()) {
-    return Api::NewError("%s expects argument at index '%d' to be non-null.",
-                         CURRENT_FUNC, arg_index);
-  }
   const Instance& instance = Instance::Cast(obj);
-  if (!instance.IsValidNativeIndex(fld_index)) {
+  uint16_t field_count = instance.NumNativeFields();
+  if (num_fields != field_count) {
     return Api::NewError(
-        "%s: invalid index %d passed in to access native instance field",
-        CURRENT_FUNC, fld_index);
+        "%s: invalid 'field_values' array specified for returning field values",
+        CURRENT_FUNC);
   }
-  if (value == NULL) {
-    RETURN_NULL_ERROR(value);
-  }
-  *value = instance.GetNativeField(isolate, fld_index);
+  instance.GetNativeFields(num_fields, field_values);
   return Api::Success();
 }
 
@@ -4175,8 +4180,8 @@
                          " snapshot.", CURRENT_FUNC);
   }
   if (snapshot->length() != buffer_len) {
-    return Api::NewError("%s: 'buffer_len' of %" Pd " is not equal to %d which"
-                         " is the expected length in the snapshot.",
+    return Api::NewError("%s: 'buffer_len' of %" Pd " is not equal to %" Pd64
+                         " which is the expected length in the snapshot.",
                          CURRENT_FUNC, buffer_len, snapshot->length());
   }
   Library& library =
@@ -4555,4 +4560,25 @@
   return Api::CastIsolate(Service::GetServiceIsolate(callback_data));
 }
 
+
+DART_EXPORT bool Dart_IsServiceRunning() {
+  return Service::IsRunning();
+}
+
+
+DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  Service::RegisterIsolateEmbedderCallback(name, callback, user_data);
+}
+
+
+DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  Service::RegisterRootEmbedderCallback(name, callback, user_data);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 4a7642e..9f4c55f 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3785,6 +3785,87 @@
 }
 
 
+static const int kTestNumNativeFields = 2;
+static const intptr_t kNativeField1Value = 30;
+static const intptr_t kNativeField2Value = 40;
+
+void TestNativeFieldsAccess_init(Dart_NativeArguments args) {
+  Dart_Handle receiver = Dart_GetNativeArgument(args, 0);
+  Dart_SetNativeInstanceField(receiver, 0, kNativeField1Value);
+  Dart_SetNativeInstanceField(receiver, 1, kNativeField2Value);
+}
+
+
+void TestNativeFieldsAccess_access(Dart_NativeArguments args) {
+  intptr_t field_values[kTestNumNativeFields];
+  Dart_Handle result = Dart_GetNativeFieldsOfArgument(args,
+                                                      0,
+                                                      kTestNumNativeFields,
+                                                      field_values);
+  EXPECT_VALID(result);
+  EXPECT_EQ(kNativeField1Value, field_values[0]);
+  EXPECT_EQ(kNativeField2Value, field_values[1]);
+  result = Dart_GetNativeFieldsOfArgument(args,
+                                          1,
+                                          kTestNumNativeFields,
+                                          field_values);
+  EXPECT_VALID(result);
+  EXPECT_EQ(0, field_values[0]);
+  EXPECT_EQ(0, field_values[1]);
+}
+
+
+static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name,
+                                                         int argument_count,
+                                                         bool* auto_scope) {
+  ASSERT(auto_scope != NULL);
+  *auto_scope = true;
+  const Object& obj = Object::Handle(Api::UnwrapHandle(name));
+  if (!obj.IsString()) {
+    return NULL;
+  }
+  const char* function_name = obj.ToCString();
+  ASSERT(function_name != NULL);
+  if (!strcmp(function_name, "TestNativeFieldsAccess_init")) {
+    return reinterpret_cast<Dart_NativeFunction>(&TestNativeFieldsAccess_init);
+  } else if (!strcmp(function_name, "TestNativeFieldsAccess_access")) {
+    return reinterpret_cast<Dart_NativeFunction>(
+        &TestNativeFieldsAccess_access);
+  } else {
+    return NULL;
+  }
+}
+
+
+TEST_CASE(TestNativeFieldsAccess) {
+  const char* kScriptChars =
+      "import 'dart:nativewrappers';"
+      "class NativeFields extends NativeFieldWrapperClass2 {\n"
+      "  NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+      "  int fld1;\n"
+      "  final int fld2;\n"
+      "  static int fld3;\n"
+      "  static const int fld4 = 10;\n"
+      "  int initNativeFlds() native 'TestNativeFieldsAccess_init';\n"
+      "  int accessNativeFlds(int i) native 'TestNativeFieldsAccess_access';\n"
+      "}\n"
+      "NativeFields testMain() {\n"
+      "  NativeFields obj = new NativeFields(10, 20);\n"
+      "  obj.initNativeFlds();\n"
+      "  obj.accessNativeFlds(null);\n"
+      "  return obj;\n"
+      "}\n";
+
+  // Load up a test script in the test library.
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars,
+                                             TestNativeFieldsAccess_lookup);
+
+  // Invoke a function which returns an object of type NativeFields.
+  Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
+  EXPECT_VALID(result);
+}
+
+
 TEST_CASE(InjectNativeFieldsSuperClass) {
   const char* kScriptChars =
       "import 'dart:nativewrappers';"
@@ -6022,7 +6103,8 @@
   EXPECT_VALID(result);
 
   EXPECT_ERROR(Dart_Invoke(type, NewString("baz"), 0, NULL),
-               "native function 'SomeNativeFunction3' cannot be found");
+               "native function 'SomeNativeFunction3' (0 arguments) "
+               "cannot be found");
 }
 
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index a858a5f..1b829bf 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -187,20 +187,18 @@
 
 void Debugger::SignalIsolateEvent(EventType type) {
   if (event_handler_ != NULL) {
-    Debugger* debugger = Isolate::Current()->debugger();
-    ASSERT(debugger != NULL);
     DebuggerEvent event(type);
-    event.isolate_id = debugger->GetIsolateId();
+    event.isolate_id = isolate_id_;
     ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID);
     if (type == kIsolateInterrupted) {
-      DebuggerStackTrace* stack_trace = debugger->CollectStackTrace();
-      ASSERT(stack_trace->Length() > 0);
-      ASSERT(debugger->stack_trace_ == NULL);
-      debugger->stack_trace_ = stack_trace;
-      debugger->Pause(&event);
-      debugger->stack_trace_ = NULL;
-      // TODO(asiva): Need some work here to be able to single step after
-      // an interrupt.
+      DebuggerStackTrace* trace = CollectStackTrace();
+      ASSERT(trace->Length() > 0);
+      ASSERT(stack_trace_ == NULL);
+      stack_trace_ = trace;
+      resume_action_ = kContinue;
+      Pause(&event);
+      HandleSteppingRequest(trace);
+      stack_trace_ = NULL;
     } else {
       (*event_handler_)(&event);
     }
@@ -208,6 +206,15 @@
 }
 
 
+void Debugger::SignalIsolateInterrupted() {
+  if (event_handler_ != NULL) {
+    Debugger* debugger = Isolate::Current()->debugger();
+    ASSERT(debugger != NULL);
+    debugger->SignalIsolateEvent(kIsolateInterrupted);
+  }
+}
+
+
 const char* Debugger::QualifiedFunctionName(const Function& func) {
   const String& func_name = String::Handle(func.name());
   Class& func_class = Class::Handle(func.Owner());
@@ -432,12 +439,6 @@
 
 
 RawContext* ActivationFrame::GetSavedEntryContext() {
-  if (ctx_.IsNull()) {
-    // We have bailed on providing a context for this frame.  Bail for
-    // the caller as well.
-    return Context::null();
-  }
-
   // Attempt to find a saved context.
   GetVarDescriptors();
   intptr_t var_desc_len = var_descriptors_.Length();
@@ -466,6 +467,7 @@
       return GetLocalContextVar(var_info.index);
     }
   }
+  UNREACHABLE();
   return Context::null();
 }
 
@@ -611,9 +613,15 @@
 RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) {
   Object& context = Object::Handle(GetLocalVar(slot_index));
   if (context.IsContext()) {
+    // We found a saved context.
     return Context::Cast(context).raw();
+  } else if (context.raw() == Symbols::OptimizedOut().raw()) {
+    // The optimizing compiler has eliminated the saved context.
+    return Context::null();
+  } else {
+    UNREACHABLE();
+    return Context::null();
   }
-  return Context::null();
 }
 
 
@@ -638,9 +646,14 @@
     *value = GetLocalInstanceVar(var_info.index);
   } else {
     ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar);
+    if (ctx_.IsNull()) {
+      // The context has been removed by the optimizing compiler.
+      *value = Symbols::OptimizedOut().raw();
+      return;
+    }
+
     // The context level at the PC/token index of this activation frame.
     intptr_t frame_ctx_level = ContextLevel();
-    ASSERT(!ctx_.IsNull());
 
     // The context level of the variable.
     intptr_t var_ctx_level = var_info.scope_id;
@@ -1063,6 +1076,7 @@
   if (callee_activation == NULL) {
     // No callee.  Use incoming entry context.  Could be from
     // isolate's top context or from an entry frame.
+    ASSERT(!entry_ctx.IsNull());
     activation->SetContext(entry_ctx);
 
   } else if (callee_activation->function().IsClosureFunction()) {
@@ -1077,6 +1091,9 @@
     // Use the context provided by our callee.  This is either the
     // callee's context or a context that was saved in the callee's
     // frame.
+    //
+    // The callee's saved context may be NULL if it was eliminated by
+    // the optimizing compiler.
     const Context& callee_ctx =
         Context::Handle(isolate, callee_activation->GetSavedEntryContext());
     activation->SetContext(callee_ctx);
@@ -1916,6 +1933,28 @@
 }
 
 
+void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) {
+  stepping_fp_ = 0;
+  if (resume_action_ == kSingleStep) {
+    isolate_->set_single_step(true);
+  } else if (resume_action_ == kStepOver) {
+    isolate_->set_single_step(true);
+    ASSERT(stack_trace->Length() > 0);
+    stepping_fp_ = stack_trace->FrameAt(0)->fp();
+  } else if (resume_action_ == kStepOut) {
+    isolate_->set_single_step(true);
+    // Find topmost caller that is debuggable.
+    for (intptr_t i = 1; i < stack_trace->Length(); i++) {
+      ActivationFrame* frame = stack_trace->FrameAt(i);
+      if (frame->IsDebuggable()) {
+        stepping_fp_ = frame->fp();
+        break;
+      }
+    }
+  }
+}
+
+
 bool Debugger::IsDebuggable(const Function& func) {
   if (!IsDebuggableFunctionKind(func)) {
     return false;
@@ -1940,17 +1979,6 @@
 }
 
 
-static uword DebuggableCallerFP(DebuggerStackTrace* stack_trace) {
-  for (intptr_t i = 1; i < stack_trace->Length(); i++) {
-    ActivationFrame* frame = stack_trace->FrameAt(i);
-    if (frame->IsDebuggable()) {
-      return frame->fp();
-    }
-  }
-  return 0;
-}
-
-
 void Debugger::DebuggerStepCallback() {
   ASSERT(isolate_->single_step());
   // We can't get here unless the debugger event handler enabled
@@ -1998,17 +2026,7 @@
   ASSERT(stack_trace_ == NULL);
   stack_trace_ = CollectStackTrace();
   SignalPausedEvent(frame, NULL);
-
-  if (resume_action_ == kSingleStep) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = 0;
-  } else if (resume_action_ == kStepOver) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = frame->fp();
-  } else if (resume_action_ == kStepOut) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = DebuggableCallerFP(stack_trace_);
-  }
+  HandleSteppingRequest(stack_trace_);
   stack_trace_ = NULL;
 }
 
@@ -2040,18 +2058,8 @@
   ASSERT(stack_trace_ == NULL);
   stack_trace_ = stack_trace;
   SignalPausedEvent(top_frame, bpt->src_bpt_);
+  HandleSteppingRequest(stack_trace_);
   stack_trace_ = NULL;
-
-  if (resume_action_ == kSingleStep) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = 0;
-  } else if (resume_action_ == kStepOver) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = top_frame->fp();
-  } else if (resume_action_ == kStepOut) {
-    isolate_->set_single_step(true);
-    stepping_fp_ = DebuggableCallerFP(stack_trace);
-  }
   if (bpt->IsInternal()) {
     RemoveInternalBreakpoints();
   }
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 1db1200..0664bac 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -367,7 +367,8 @@
   void DebuggerStepCallback();
 
   void SignalExceptionThrown(const Instance& exc);
-  static void SignalIsolateEvent(EventType type);
+  void SignalIsolateEvent(EventType type);
+  static void SignalIsolateInterrupted();
 
   uword GetPatchedStubAddress(uword breakpoint_address);
 
@@ -442,6 +443,8 @@
   // interrupts, etc.
   void Pause(DebuggerEvent* event);
 
+  void HandleSteppingRequest(DebuggerStackTrace* stack_trace);
+
   Isolate* isolate_;
   Dart_Port isolate_id_;  // A unique ID for the isolate in the debugger.
   bool initialized_;
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 15ff31b..99b7ad9 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1308,10 +1308,19 @@
 
 static Monitor* sync = NULL;
 static bool isolate_interrupted = false;
+static bool pause_event_handled = false;
 static Dart_IsolateId interrupt_isolate_id = ILLEGAL_ISOLATE_ID;
 static volatile bool continue_isolate_loop = true;
 
 
+static void InterruptIsolateHandler(Dart_IsolateId isolateId,
+                                    intptr_t breakpointId,
+                                    const Dart_CodeLocation& location) {
+  MonitorLocker ml(sync);
+  pause_event_handled = true;
+  ml.Notify();
+}
+
 static void TestInterruptIsolate(Dart_IsolateId isolate_id,
                                  Dart_IsolateEvent kind) {
   if (kind == kCreated) {
@@ -1328,7 +1337,7 @@
       MonitorLocker ml(sync);
       isolate_interrupted = true;
       continue_isolate_loop = false;
-      ml.Notify();
+      Dart_SetStepInto();
     }
   } else if (kind == kShutdown) {
     if (interrupt_isolate_id == isolate_id) {
@@ -1394,6 +1403,7 @@
   Dart_SetIsolateEventHandler(&TestInterruptIsolate);
   sync = new Monitor();
   EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
+  Dart_SetPausedEventHandler(InterruptIsolateHandler);
   int result = Thread::Start(InterruptIsolateRun, 0);
   EXPECT_EQ(0, result);
 
@@ -1413,11 +1423,12 @@
   // Wait for the test isolate to be interrupted.
   {
     MonitorLocker ml(sync);
-    while (!isolate_interrupted) {
+    while (!isolate_interrupted || !pause_event_handled) {
       ml.Wait();
     }
   }
   EXPECT(isolate_interrupted);
+  EXPECT(pause_event_handled);
 
   // Wait for the test isolate to shutdown.
   {
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index defd14e..ab9e6cd 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -54,6 +54,20 @@
 }
 
 
+void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) {
+  RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(slot());
+  RawFloat64x2* raw_float64x2 = Float64x2::New(value());
+  *float64x2_slot = raw_float64x2;
+
+  if (FLAG_trace_deoptimization_verbose) {
+    double x = raw_float64x2->x();
+    double y = raw_float64x2->y();
+    OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n",
+                 reinterpret_cast<uword>(slot()), x, y);
+  }
+}
+
+
 void DeferredInt32x4::Materialize(DeoptContext* deopt_context) {
   RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(slot());
   RawInt32x4* raw_int32x4 = Int32x4::New(value());
diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h
index 809a2ad..2e0733c 100644
--- a/runtime/vm/deferred_objects.h
+++ b/runtime/vm/deferred_objects.h
@@ -87,6 +87,23 @@
 };
 
 
+class DeferredFloat64x2 : public DeferredSlot {
+ public:
+  DeferredFloat64x2(simd128_value_t value, RawInstance** slot,
+                    DeferredSlot* next)
+      : DeferredSlot(slot, next), value_(value) { }
+
+  virtual void Materialize(DeoptContext* deopt_context);
+
+  simd128_value_t value() const { return value_; }
+
+ private:
+  const simd128_value_t value_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredFloat64x2);
+};
+
+
 class DeferredInt32x4 : public DeferredSlot {
  public:
   DeferredInt32x4(simd128_value_t value, RawInstance** slot,
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 150e191..9dca795 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -262,7 +262,7 @@
   // described as part of the expression stack for the bottom-most deoptimized
   // frame. They will be used during materialization and removed from the stack
   // right before control switches to the unoptimized code.
-  const intptr_t num_materializations = len - frame_size;
+  const intptr_t num_materializations = deopt_info.NumMaterializations();
   PrepareForDeferredMaterialization(num_materializations);
   for (intptr_t from_index = 0, to_index = kDartFrameFixedSize;
        from_index < num_materializations;
@@ -364,7 +364,12 @@
   Object& obj = Object::Handle();
   for (intptr_t i = 0; i < dest_frame_size_; i++) {
     obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
-    ASSERT(obj.IsNull() || obj.IsInstance() || obj.IsContext());
+    ASSERT(obj.IsNull() ||
+           obj.IsInstance() ||
+           obj.IsContext() ||
+           obj.IsTypeArguments() ||
+           obj.IsClass() ||  // TODO(turnidge): Ask around and find out why
+           obj.IsField());   // Class/Field show up here.  Maybe type feedback?
     dest_array.SetAt(i, obj);
   }
   return dest_array.raw();
@@ -507,6 +512,38 @@
 };
 
 
+class DeoptFloat64x2StackSlotInstr : public DeoptInstr {
+ public:
+  explicit DeoptFloat64x2StackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
+    ASSERT(stack_slot_index_ >= 0);
+  }
+
+  virtual intptr_t source_index() const { return stack_slot_index_; }
+  virtual DeoptInstr::Kind kind() const { return kFloat64x2StackSlot; }
+
+  virtual const char* ToCString() const {
+    return Isolate::Current()->current_zone()->PrintToString(
+        "f64x2s%" Pd "", stack_slot_index_);
+  }
+
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
+        deopt_context->GetSourceFrameAddressAt(source_index));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferFloat64x2Materialization(
+        *source_addr, reinterpret_cast<RawFloat64x2**>(dest_addr));
+  }
+
+ private:
+  const intptr_t stack_slot_index_;  // First argument is 0, always >= 0.
+
+  DISALLOW_COPY_AND_ASSIGN(DeoptFloat64x2StackSlotInstr);
+};
+
+
 class DeoptInt32x4StackSlotInstr : public DeoptInstr {
  public:
   explicit DeoptInt32x4StackSlotInstr(intptr_t source_index)
@@ -745,6 +782,33 @@
 };
 
 
+class DeoptFloat64x2FpuRegisterInstr: public DeoptInstr {
+ public:
+  explicit DeoptFloat64x2FpuRegisterInstr(intptr_t reg_as_int)
+      : reg_(static_cast<FpuRegister>(reg_as_int)) {}
+
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
+  virtual DeoptInstr::Kind kind() const { return kFloat64x2FpuRegister; }
+
+  virtual const char* ToCString() const {
+    return Isolate::Current()->current_zone()->PrintToString(
+        "%s(f64x2)", Assembler::FpuRegisterName(reg_));
+  }
+
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferFloat64x2Materialization(
+        value, reinterpret_cast<RawFloat64x2**>(dest_addr));
+  }
+
+ private:
+  const FpuRegister reg_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeoptFloat64x2FpuRegisterInstr);
+};
+
+
 // Deoptimization instruction moving an XMM register.
 class DeoptInt32x4FpuRegisterInstr: public DeoptInstr {
  public:
@@ -1072,6 +1136,8 @@
     case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index);
     case kFloat32x4StackSlot:
         return new DeoptFloat32x4StackSlotInstr(source_index);
+    case kFloat64x2StackSlot:
+        return new DeoptFloat64x2StackSlotInstr(source_index);
     case kInt32x4StackSlot:
         return new DeoptInt32x4StackSlotInstr(source_index);
     case kRetAddress: return new DeoptRetAddressInstr(source_index);
@@ -1081,6 +1147,8 @@
     case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index);
     case kFloat32x4FpuRegister:
         return new DeoptFloat32x4FpuRegisterInstr(source_index);
+    case kFloat64x2FpuRegister:
+        return new DeoptFloat64x2FpuRegisterInstr(source_index);
     case kInt32x4FpuRegister:
         return new DeoptInt32x4FpuRegisterInstr(source_index);
     case kPcMarker: return new DeoptPcMarkerInstr(source_index);
@@ -1212,9 +1280,11 @@
       deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg());
     } else if (value->definition()->representation() == kUnboxedFloat32x4) {
       deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg());
-    } else {
-      ASSERT(value->definition()->representation() == kUnboxedInt32x4);
+    } else if (value->definition()->representation() == kUnboxedInt32x4) {
       deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg());
+    } else {
+      ASSERT(value->definition()->representation() == kUnboxedFloat64x2);
+      deopt_instr = new DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg());
     }
   } else if (source_loc.IsStackSlot()) {
     ASSERT(value->definition()->representation() == kTagged);
@@ -1232,9 +1302,11 @@
     intptr_t source_index = CalculateStackIndex(source_loc);
     if (value->definition()->representation() == kUnboxedFloat32x4) {
       deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index);
-    } else {
-      ASSERT(value->definition()->representation() == kUnboxedInt32x4);
+    } else if (value->definition()->representation() == kUnboxedInt32x4) {
       deopt_instr = new DeoptInt32x4StackSlotInstr(source_index);
+    } else {
+      ASSERT(value->definition()->representation() == kUnboxedFloat64x2);
+      deopt_instr = new DeoptFloat64x2StackSlotInstr(source_index);
     }
   } else if (source_loc.IsInvalid() &&
              value->definition()->IsMaterializeObject()) {
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 43a2bdc..cb304dd 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -134,6 +134,14 @@
         deferred_boxes_);
   }
 
+  void DeferFloat64x2Materialization(simd128_value_t value,
+                                     RawFloat64x2** slot) {
+    deferred_boxes_ = new DeferredFloat64x2(
+        value,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_boxes_);
+  }
+
   void DeferInt32x4Materialization(simd128_value_t value,
                                     RawInt32x4** slot) {
     deferred_boxes_ = new DeferredInt32x4(
@@ -210,11 +218,13 @@
     kFpuRegister,
     kInt64FpuRegister,
     kFloat32x4FpuRegister,
+    kFloat64x2FpuRegister,
     kInt32x4FpuRegister,
     kStackSlot,
     kDoubleStackSlot,
     kInt64StackSlot,
     kFloat32x4StackSlot,
+    kFloat64x2StackSlot,
     kInt32x4StackSlot,
     kPcMarker,
     kPp,
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index b59a05b..cce24b9 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -606,7 +606,8 @@
   if ((instr->representation() == kUnboxedDouble) ||
       (instr->representation() == kUnboxedMint) ||
       (instr->representation() == kUnboxedFloat32x4) ||
-      (instr->representation() == kUnboxedInt32x4)) {
+      (instr->representation() == kUnboxedInt32x4) ||
+      (instr->representation() == kUnboxedFloat64x2)) {
     return Location::kFpuRegister;
   } else {
     return Location::kRegister;
@@ -1602,7 +1603,8 @@
   // parallel move resolution.
   const bool need_quad = (register_kind_ == Location::kFpuRegister) &&
       ((range->representation() == kUnboxedFloat32x4) ||
-       (range->representation() == kUnboxedInt32x4));
+       (range->representation() == kUnboxedInt32x4)   ||
+       (range->representation() == kUnboxedFloat64x2));
 
   // Search for a free spill slot among allocated: the value in it should be
   // dead and its type should match (e.g. it should not be a part of the quad if
@@ -1651,7 +1653,8 @@
 
     Location location;
     if ((range->representation() == kUnboxedFloat32x4) ||
-        (range->representation() == kUnboxedInt32x4)) {
+        (range->representation() == kUnboxedInt32x4) ||
+        (range->representation() == kUnboxedFloat64x2)) {
       ASSERT(need_quad);
       location = Location::QuadStackSlot(slot_idx);
     } else {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 8eb9e54..d55f1e0 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2273,10 +2273,6 @@
                                                       instantiator_class,
                                                       NULL);
       arguments->Add(PushArgument(type_arguments));
-
-      Value* instantiator_val = Bind(new ConstantInstr(
-          Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
-      arguments->Add(PushArgument(instantiator_val));
     }
     AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(),
                                                          cls,
@@ -2396,7 +2392,7 @@
 }
 
 
-static intptr_t GetResultCidOfNative(const Function& function) {
+static intptr_t GetResultCidOfNativeFactory(const Function& function) {
   const Class& function_class = Class::Handle(function.Owner());
   if (function_class.library() == Library::TypedDataLibrary()) {
     const String& function_name = String::Handle(function.name());
@@ -2439,8 +2435,11 @@
                           arguments,
                           owner()->ic_data_array());
   if (node->function().is_native()) {
-    const intptr_t result_cid = GetResultCidOfNative(node->function());
-    call->set_result_cid(result_cid);
+    const intptr_t result_cid = GetResultCidOfNativeFactory(node->function());
+    if (result_cid != kDynamicCid) {
+      call->set_result_cid(result_cid);
+      call->set_is_native_list_factory(true);
+    }
   }
   ReturnDefinition(call);
 }
@@ -2491,12 +2490,14 @@
 
 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
   const Class& cls = Class::ZoneHandle(node->constructor().Owner());
-  const bool requires_type_arguments = cls.NumTypeArguments() > 0;
+  const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
 
   ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
-      new ZoneGrowableArray<PushArgumentInstr*>();
-  if (requires_type_arguments) {
-    BuildConstructorTypeArguments(node, allocate_arguments);
+      new ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0);
+  if (cls_is_parameterized) {
+    Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
+                                                      node->type_arguments());
+    allocate_arguments->Add(PushArgument(type_args));
   }
 
   Definition* allocation = new AllocateObjectInstr(
@@ -2681,79 +2682,14 @@
   const bool use_instantiator_type_args =
       type_arguments.IsUninstantiatedIdentity() ||
       type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
-  return use_instantiator_type_args
-      ? instantiator_value
-      : Bind(new InstantiateTypeArgumentsInstr(token_pos,
-                                               type_arguments,
-                                               instantiator_class,
-                                               instantiator_value));
-}
-
-
-void EffectGraphVisitor::BuildConstructorTypeArguments(
-    ConstructorCallNode* node,
-    ZoneGrowableArray<PushArgumentInstr*>* call_arguments) {
-  const Class& cls = Class::ZoneHandle(node->constructor().Owner());
-  ASSERT((cls.NumTypeArguments() > 0) && !node->constructor().IsFactory());
-  if (node->type_arguments().IsNull() ||
-      node->type_arguments().IsInstantiated()) {
-    Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments()));
-    call_arguments->Add(PushArgument(type_arguments_val));
-
-    // No instantiator required.
-    Value* instantiator_val = Bind(new ConstantInstr(
-        Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
-    call_arguments->Add(PushArgument(instantiator_val));
-    return;
-  }
-
-  // The type arguments are uninstantiated. We use expression_temp_var to save
-  // the instantiator type arguments because they have two uses.
-  ASSERT(owner()->parsed_function()->expression_temp_var() != NULL);
-  const Class& instantiator_class = Class::Handle(
-      owner()->parsed_function()->function().Owner());
-  Value* type_arguments_val = BuildInstantiatorTypeArguments(
-      node->token_pos(), instantiator_class, NULL);
-
-  const bool use_instantiator_type_args =
-      node->type_arguments().IsUninstantiatedIdentity() ||
-      node->type_arguments().CanShareInstantiatorTypeArguments(
-          instantiator_class);
-
-  if (!use_instantiator_type_args) {
-    const intptr_t len = node->type_arguments().Length();
-    if (node->type_arguments().IsRawInstantiatedRaw(len)) {
-      type_arguments_val =
-          Bind(BuildStoreExprTemp(type_arguments_val));
-      type_arguments_val = Bind(
-          new ExtractConstructorTypeArgumentsInstr(
-              node->token_pos(),
-              node->type_arguments(),
-              instantiator_class,
-              type_arguments_val));
-    } else {
-      Do(BuildStoreExprTemp(type_arguments_val));
-      type_arguments_val = Bind(new ConstantInstr(node->type_arguments()));
-    }
-  }
-  call_arguments->Add(PushArgument(type_arguments_val));
-
-  Value* instantiator_val = NULL;
-  if (!use_instantiator_type_args) {
-    instantiator_val = Bind(BuildLoadExprTemp());
-    const intptr_t len = node->type_arguments().Length();
-    if (node->type_arguments().IsRawInstantiatedRaw(len)) {
-      instantiator_val =
-          Bind(new ExtractConstructorInstantiatorInstr(node,
-                                                       instantiator_class,
-                                                       instantiator_val));
-    }
+  if (use_instantiator_type_args) {
+    return instantiator_value;
   } else {
-    // No instantiator required.
-    instantiator_val = Bind(new ConstantInstr(
-        Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
+    return Bind(new InstantiateTypeArgumentsInstr(token_pos,
+                                                  type_arguments,
+                                                  instantiator_class,
+                                                  instantiator_value));
   }
-  call_arguments->Add(PushArgument(instantiator_val));
 }
 
 
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 0b3cae9..c0ddd97 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -336,14 +336,6 @@
       intptr_t token_pos,
       const TypeArguments& type_arguments);
 
-  // Creates a possibly uninstantiated type argument vector and the type
-  // argument vector of the instantiator used in
-  // preparation of a constructor call.
-  // May be called only if allocating an object of a parameterized class.
-  void BuildConstructorTypeArguments(
-      ConstructorCallNode* node,
-      ZoneGrowableArray<PushArgumentInstr*>* call_arguments);
-
   void BuildTypecheckPushArguments(
       intptr_t token_pos,
       PushArgumentInstr** push_instantiator,
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 9d20dcd..58b9f5f 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -86,6 +86,8 @@
           Isolate::Current()->object_store()->double_class())),
       float32x4_class_(Class::ZoneHandle(
           Isolate::Current()->object_store()->float32x4_class())),
+      float64x2_class_(Class::ZoneHandle(
+          Isolate::Current()->object_store()->float64x2_class())),
       int32x4_class_(Class::ZoneHandle(
           Isolate::Current()->object_store()->int32x4_class())),
       list_class_(Class::ZoneHandle(
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 812d62d..dd8bc52 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -428,6 +428,7 @@
 
   const Class& double_class() const { return double_class_; }
   const Class& float32x4_class() const { return float32x4_class_; }
+  const Class& float64x2_class() const { return float64x2_class_; }
   const Class& int32x4_class() const { return int32x4_class_; }
 
   void SaveLiveRegisters(LocationSummary* locs);
@@ -592,6 +593,7 @@
 
   const Class& double_class_;
   const Class& float32x4_class_;
+  const Class& float64x2_class_;
   const Class& int32x4_class_;
   const Class& list_class_;
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 93cf6c4..eb7fa01 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -9,6 +9,7 @@
 
 #include "vm/ast_printer.h"
 #include "vm/compiler.h"
+#include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -44,7 +45,7 @@
 
 
 bool FlowGraphCompiler::SupportsUnboxedFloat32x4() {
-  return CPUFeatures::neon_supported() && FLAG_enable_simd_inline;
+  return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline;
 }
 
 
@@ -718,7 +719,9 @@
 
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) return;
+  if (is_optimizing()) {
+    return;
+  }
   Definition* defn = instr->AsDefinition();
   if ((defn != NULL) && defn->is_used()) {
     __ Push(defn->locs()->out().reg());
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 27c34cb..94af4b2 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -9,6 +9,7 @@
 
 #include "vm/ast_printer.h"
 #include "vm/compiler.h"
+#include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -43,7 +44,7 @@
 
 bool FlowGraphCompiler::SupportsUnboxedMints() {
   // Support unboxed mints when SSE 4.1 is available.
-  return FLAG_unbox_mints && CPUFeatures::sse4_1_supported();
+  return FLAG_unbox_mints && TargetCPUFeatures::sse4_1_supported();
 }
 
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index ce258c0..4bc20e1 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -6,6 +6,7 @@
 
 #include "vm/bit_vector.h"
 #include "vm/cha.h"
+#include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph_builder.h"
 #include "vm/flow_graph_compiler.h"
@@ -622,6 +623,13 @@
     converted = new UnboxInt32x4Instr(use->CopyWithType(), deopt_id);
   } else if ((from == kUnboxedInt32x4) && (to == kTagged)) {
     converted = new BoxInt32x4Instr(use->CopyWithType());
+  } else if ((from == kTagged) && (to == kUnboxedFloat64x2)) {
+    ASSERT((deopt_target != NULL) || (use->Type()->ToCid() == kFloat64x2Cid));
+    const intptr_t deopt_id = (deopt_target != NULL) ?
+        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
+    converted = new UnboxFloat64x2Instr(use->CopyWithType(), deopt_id);
+  } else if ((from == kUnboxedFloat64x2) && (to == kTagged)) {
+    converted = new BoxFloat64x2Instr(use->CopyWithType());
   } else {
     // We have failed to find a suitable conversion instruction.
     // Insert two "dummy" conversion instructions with the correct
@@ -640,6 +648,8 @@
       boxed = new BoxFloat32x4Instr(use->CopyWithType());
     } else if (from == kUnboxedMint) {
       boxed = new BoxIntegerInstr(use->CopyWithType());
+    } else if (from == kUnboxedFloat64x2) {
+      boxed = new BoxFloat64x2Instr(use->CopyWithType());
     } else {
       UNIMPLEMENTED();
     }
@@ -654,6 +664,8 @@
       converted = new UnboxFloat32x4Instr(to_value, deopt_id);
     } else if (to == kUnboxedMint) {
       converted = new UnboxIntegerInstr(to_value, deopt_id);
+    } else if (to == kUnboxedFloat64x2) {
+      converted = new UnboxFloat64x2Instr(to_value, deopt_id);
     } else {
       UNIMPLEMENTED();
     }
@@ -1050,6 +1062,10 @@
     case MethodRecognizer::kInt32x4ArraySetIndexed:
       return kTypedDataInt32x4ArrayCid;
 
+    case MethodRecognizer::kFloat64x2ArrayGetIndexed:
+    case MethodRecognizer::kFloat64x2ArraySetIndexed:
+      return kTypedDataFloat64x2ArrayCid;
+
     default:
       break;
   }
@@ -1175,6 +1191,13 @@
         ASSERT(value_type.IsInstantiated());
         break;
       }
+      case kTypedDataFloat64x2ArrayCid: {
+        type_args = instantiator = flow_graph_->constant_null();
+        ASSERT((array_cid != kTypedDataFloat64x2ArrayCid) ||
+               value_type.IsFloat64x2Type());
+        ASSERT(value_type.IsInstantiated());
+        break;
+      }
       default:
         // TODO(fschneider): Add support for other array types.
         UNREACHABLE();
@@ -1220,6 +1243,15 @@
                                     Definition::kEffect);
   }
 
+  if (array_cid == kTypedDataFloat32ArrayCid) {
+    stored_value =
+        new DoubleToFloatInstr(new Value(stored_value), call->deopt_id());
+    cursor = flow_graph()->AppendTo(cursor,
+                                    stored_value,
+                                    NULL,
+                                    Definition::kValue);
+  }
+
   intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
   *last = new StoreIndexedInstr(new Value(array),
                                 new Value(index),
@@ -1262,7 +1294,10 @@
     case MethodRecognizer::kUint16ArrayGetIndexed:
       return InlineGetIndexed(kind, call, receiver, ic_data, entry, last);
     case MethodRecognizer::kFloat32x4ArrayGetIndexed:
-      if (!ShouldInlineSimd()) return false;
+    case MethodRecognizer::kFloat64x2ArrayGetIndexed:
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
       return InlineGetIndexed(kind, call, receiver, ic_data, entry, last);
     case MethodRecognizer::kInt32ArrayGetIndexed:
     case MethodRecognizer::kUint32ArrayGetIndexed:
@@ -1284,13 +1319,17 @@
     case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
     case MethodRecognizer::kInt16ArraySetIndexed:
     case MethodRecognizer::kUint16ArraySetIndexed:
-      if (!ArgIsAlways(kSmiCid, ic_data, 2)) return false;
+      if (!ArgIsAlways(kSmiCid, ic_data, 2)) {
+        return false;
+      }
       value_check = ic_data.AsUnaryClassChecksForArgNr(2);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               &ic_data, value_check, entry, last);
     case MethodRecognizer::kInt32ArraySetIndexed:
     case MethodRecognizer::kUint32ArraySetIndexed:
-      if (!CanUnboxInt32()) return false;
+      if (!CanUnboxInt32()) {
+        return false;
+      }
       // Check that value is always smi or mint, if the platform has unboxed
       // mints (ia32 with at least SSE 4.1).
       value_check = ic_data.AsUnaryClassChecksForArgNr(2);
@@ -1306,14 +1345,31 @@
     case MethodRecognizer::kFloat32ArraySetIndexed:
     case MethodRecognizer::kFloat64ArraySetIndexed:
       // Check that value is always double.
-      if (!ArgIsAlways(kDoubleCid, ic_data, 2)) return false;
+      if (!ArgIsAlways(kDoubleCid, ic_data, 2)) {
+        return false;
+      }
       value_check = ic_data.AsUnaryClassChecksForArgNr(2);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               &ic_data, value_check, entry, last);
     case MethodRecognizer::kFloat32x4ArraySetIndexed:
-      if (!ShouldInlineSimd()) return false;
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
       // Check that value is always a Float32x4.
-      if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false;
+      if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) {
+        return false;
+      }
+      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      return InlineSetIndexed(kind, target, call, receiver, token_pos,
+                              &ic_data, value_check, entry, last);
+    case MethodRecognizer::kFloat64x2ArraySetIndexed:
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
+      // Check that value is always a Float32x4.
+      if (!ArgIsAlways(kFloat64x2Cid, ic_data, 2)) {
+        return false;
+      }
       value_check = ic_data.AsUnaryClassChecksForArgNr(2);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               &ic_data, value_check, entry, last);
@@ -1334,12 +1390,16 @@
                                      kTypedDataUint16ArrayCid,
                                      ic_data, entry, last);
     case MethodRecognizer::kByteArrayBaseGetInt32:
-      if (!CanUnboxInt32()) return false;
+      if (!CanUnboxInt32()) {
+        return false;
+      }
       return InlineByteArrayViewLoad(call, receiver, receiver_cid,
                                      kTypedDataInt32ArrayCid,
                                      ic_data, entry, last);
     case MethodRecognizer::kByteArrayBaseGetUint32:
-      if (!CanUnboxInt32()) return false;
+      if (!CanUnboxInt32()) {
+        return false;
+      }
       return InlineByteArrayViewLoad(call, receiver, receiver_cid,
                                      kTypedDataUint32ArrayCid,
                                      ic_data, entry, last);
@@ -1352,15 +1412,75 @@
                                      kTypedDataFloat64ArrayCid,
                                      ic_data, entry, last);
     case MethodRecognizer::kByteArrayBaseGetFloat32x4:
-      if (!ShouldInlineSimd()) return false;
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
       return InlineByteArrayViewLoad(call, receiver, receiver_cid,
                                      kTypedDataFloat32x4ArrayCid,
                                      ic_data, entry, last);
     case MethodRecognizer::kByteArrayBaseGetInt32x4:
-      if (!ShouldInlineSimd()) return false;
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
       return InlineByteArrayViewLoad(call, receiver, receiver_cid,
                                      kTypedDataInt32x4ArrayCid,
                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetInt8:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataInt8ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetUint8:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataUint8ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetInt16:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataInt16ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetUint16:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataUint16ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetInt32:
+      if (!CanUnboxInt32()) {
+        return false;
+      }
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataInt32ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetUint32:
+      if (!CanUnboxInt32()) {
+        return false;
+      }
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataUint32ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetFloat32:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataFloat32ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetFloat64:
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataFloat64ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetFloat32x4:
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataFloat32x4ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kByteArrayBaseSetInt32x4:
+      if (!ShouldInlineSimd()) {
+        return false;
+      }
+      return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
+                                      kTypedDataInt32x4ArrayCid,
+                                      ic_data, entry, last);
+    case MethodRecognizer::kStringBaseCodeUnitAt:
+      return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
+    case MethodRecognizer::kStringBaseCharAt:
+      return InlineStringBaseCharAt(call, receiver_cid, entry, last);
     default:
       return false;
   }
@@ -1468,10 +1588,19 @@
                                index_scale,
                                array_cid,
                                deopt_id);
-  flow_graph()->AppendTo(cursor,
-                         *last,
-                         deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
-                         Definition::kValue);
+  cursor = flow_graph()->AppendTo(
+      cursor,
+      *last,
+      deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
+      Definition::kValue);
+
+  if (array_cid == kTypedDataFloat32ArrayCid) {
+    *last = new FloatToDoubleInstr(new Value(*last), deopt_id);
+    flow_graph()->AppendTo(cursor,
+                           *last,
+                           deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
+                           Definition::kValue);
+  }
   return true;
 }
 
@@ -2369,42 +2498,139 @@
 }
 
 
-LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt(
-    InstanceCallInstr* call,
-    intptr_t cid) {
+bool FlowGraphOptimizer::TryReplaceInstanceCallWithInline(
+    InstanceCallInstr* call) {
+  ASSERT(call->HasICData());
+  Function& target = Function::Handle();
+  GrowableArray<intptr_t> class_ids;
+  call->ic_data()->GetCheckAt(0, &class_ids, &target);
+  const intptr_t receiver_cid = class_ids[0];
+
+  TargetEntryInstr* entry;
+  Definition* last;
+  if (!TryInlineRecognizedMethod(receiver_cid,
+                                 target,
+                                 call,
+                                 call->ArgumentAt(0),
+                                 call->token_pos(),
+                                 *call->ic_data(),
+                                 &entry, &last)) {
+    return false;
+  }
+
+  // Insert receiver class check.
+  AddReceiverCheck(call);
+  // Remove the original push arguments.
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+  // Replace all uses of this definition with the result.
+  call->ReplaceUsesWith(last);
+  // Finally insert the sequence other definition in place of this one in the
+  // graph.
+  call->previous()->LinkTo(entry->next());
+  entry->UnuseAllInputs();  // Entry block is not in the graph.
+  last->LinkTo(call);
+  // Remove through the iterator.
+  ASSERT(current_iterator()->Current() == call);
+  current_iterator()->RemoveCurrentFromGraph();
+  call->set_previous(NULL);
+  call->set_next(NULL);
+  return true;
+}
+
+
+// Returns the LoadIndexedInstr.
+Definition* FlowGraphOptimizer::PrepareInlineStringIndexOp(
+    Instruction* call,
+    intptr_t cid,
+    Definition* str,
+    Definition* index,
+    Instruction* cursor) {
+
+  cursor = flow_graph()->AppendTo(cursor,
+                                  new CheckSmiInstr(new Value(index),
+                                                    call->deopt_id()),
+                                  call->env(),
+                                  Definition::kEffect);
+
+  // Load the length of the string.
+  LoadFieldInstr* length = BuildLoadStringLength(str);
+  cursor = flow_graph()->AppendTo(cursor, length, NULL, Definition::kValue);
+  // Bounds check.
+  cursor = flow_graph()->AppendTo(cursor,
+                                   new CheckArrayBoundInstr(new Value(length),
+                                                            new Value(index),
+                                                            call->deopt_id()),
+                                   call->env(),
+                                   Definition::kEffect);
+
+  LoadIndexedInstr* load_indexed = new LoadIndexedInstr(
+      new Value(str),
+      new Value(index),
+      FlowGraphCompiler::ElementSizeFor(cid),
+      cid,
+      Isolate::kNoDeoptId);
+
+  cursor = flow_graph()->AppendTo(cursor,
+                                  load_indexed,
+                                  NULL,
+                                  Definition::kValue);
+  ASSERT(cursor == load_indexed);
+  return load_indexed;
+}
+
+
+bool FlowGraphOptimizer::InlineStringCodeUnitAt(
+    Instruction* call,
+    intptr_t cid,
+    TargetEntryInstr** entry,
+    Definition** last) {
+  // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
+  if (RawObject::IsExternalStringClassId(cid)) {
+    return false;
+  }
+
   Definition* str = call->ArgumentAt(0);
   Definition* index = call->ArgumentAt(1);
-  AddReceiverCheck(call);
-  InsertBefore(call,
-               new CheckSmiInstr(new Value(index), call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
-  // If both index and string are constants, then do a compile-time check.
-  // TODO(srdjan): Remove once constant propagation handles bounds checks.
-  bool skip_check = false;
-  if (str->IsConstant() && index->IsConstant()) {
-    const String& constant_string =
-        String::Cast(str->AsConstant()->value());
-    const Object& constant_index = index->AsConstant()->value();
-    skip_check = constant_index.IsSmi() &&
-        (Smi::Cast(constant_index).Value() < constant_string.Length());
+
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+
+  *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
+
+  return true;
+}
+
+
+bool FlowGraphOptimizer::InlineStringBaseCharAt(
+    Instruction* call,
+    intptr_t cid,
+    TargetEntryInstr** entry,
+    Definition** last) {
+  // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
+  if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
+    return false;
   }
-  if (!skip_check) {
-    // Insert bounds check.
-    LoadFieldInstr* length = BuildLoadStringLength(str);
-    InsertBefore(call, length, NULL, Definition::kValue);
-    InsertBefore(call,
-                 new CheckArrayBoundInstr(new Value(length),
-                                          new Value(index),
-                                          call->deopt_id()),
-                 call->env(),
-                 Definition::kEffect);
-  }
-  return new LoadIndexedInstr(new Value(str),
-                              new Value(index),
-                              FlowGraphCompiler::ElementSizeFor(cid),
-                              cid,
-                              Isolate::kNoDeoptId);  // Can't deoptimize.
+  Definition* str = call->ArgumentAt(0);
+  Definition* index = call->ArgumentAt(1);
+
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+
+  *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
+
+  StringFromCharCodeInstr* char_at =
+          new StringFromCharCodeInstr(new Value(*last), cid);
+
+  flow_graph()->AppendTo(*last, char_at, NULL, Definition::kValue);
+  *last = char_at;
+
+  return true;
 }
 
 
@@ -2491,26 +2717,15 @@
     return true;
   }
 
-  if ((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) &&
+  if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
+       (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
       (ic_data.NumberOfChecks() == 1) &&
       ((class_ids[0] == kOneByteStringCid) ||
        (class_ids[0] == kTwoByteStringCid))) {
-    LoadIndexedInstr* instr = BuildStringCodeUnitAt(call, class_ids[0]);
-    ReplaceCall(call, instr);
-    return true;
+    return TryReplaceInstanceCallWithInline(call);
   }
+
   if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
-    if (recognized_kind == MethodRecognizer::kStringBaseCharAt) {
-      // TODO(fschneider): Handle TwoByteString.
-      LoadIndexedInstr* load_char_code =
-          BuildStringCodeUnitAt(call, class_ids[0]);
-      InsertBefore(call, load_char_code, NULL, Definition::kValue);
-      StringFromCharCodeInstr* char_at =
-          new StringFromCharCodeInstr(new Value(load_char_code),
-                                      kOneByteStringCid);
-      ReplaceCall(call, char_at);
-      return true;
-    }
     if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
       // This is an internal method, no need to check argument types nor
       // range.
@@ -2564,7 +2779,7 @@
       case MethodRecognizer::kDoubleTruncate:
       case MethodRecognizer::kDoubleFloor:
       case MethodRecognizer::kDoubleCeil:
-        if (!CPUFeatures::double_truncate_round_supported()) {
+        if (!TargetCPUFeatures::double_truncate_round_supported()) {
           ReplaceWithMathCFunction(call, recognized_kind);
         } else {
           AddReceiverCheck(call);
@@ -3031,14 +3246,158 @@
                                1,
                                view_cid,
                                deopt_id);
-  flow_graph()->AppendTo(cursor,
-                         *last,
-                         deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
-                         Definition::kValue);
+  cursor = flow_graph()->AppendTo(
+      cursor,
+      *last,
+      deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
+      Definition::kValue);
+
+  if (view_cid == kTypedDataFloat32ArrayCid) {
+    *last = new FloatToDoubleInstr(new Value(*last), deopt_id);
+    flow_graph()->AppendTo(cursor,
+                           *last,
+                           deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
+                           Definition::kValue);
+  }
   return true;
 }
 
 
+bool FlowGraphOptimizer::InlineByteArrayViewStore(const Function& target,
+                                                  Instruction* call,
+                                                  Definition* receiver,
+                                                  intptr_t array_cid,
+                                                  intptr_t view_cid,
+                                                  const ICData& ic_data,
+                                                  TargetEntryInstr** entry,
+                                                  Definition** last) {
+  ASSERT(array_cid != kIllegalCid);
+  Definition* array = receiver;
+  Definition* index = call->ArgumentAt(1);
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+  Instruction* cursor = *entry;
+
+  array_cid = PrepareInlineByteArrayViewOp(call,
+                                           array_cid,
+                                           view_cid,
+                                           &array,
+                                           index,
+                                           &cursor);
+
+  // Extract the instance call so we can use the function_name in the stored
+  // value check ICData.
+  InstanceCallInstr* i_call = NULL;
+  if (call->IsPolymorphicInstanceCall()) {
+    i_call = call->AsPolymorphicInstanceCall()->instance_call();
+  } else {
+    ASSERT(call->IsInstanceCall());
+    i_call = call->AsInstanceCall();
+  }
+  ASSERT(i_call != NULL);
+  ICData& value_check = ICData::ZoneHandle();
+  switch (view_cid) {
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid: {
+      // Check that value is always smi.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                i_call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kSmiCid, target);
+      break;
+    }
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+      // We don't have ICData for the value stored, so we optimistically assume
+      // smis first. If we ever deoptimized here, we require to unbox the value
+      // before storing to handle the mint case, too.
+      if (i_call->ic_data()->deopt_reason() == kDeoptUnknown) {
+        value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                  i_call->function_name(),
+                                  Object::empty_array(),  // Dummy args. descr.
+                                  Isolate::kNoDeoptId,
+                                  1);
+        value_check.AddReceiverCheck(kSmiCid, target);
+      }
+      break;
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid: {
+      // Check that value is always double.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                i_call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kDoubleCid, target);
+      break;
+    }
+    case kTypedDataInt32x4ArrayCid: {
+      // Check that value is always Int32x4.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                i_call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kInt32x4Cid, target);
+      break;
+    }
+    case kTypedDataFloat32x4ArrayCid: {
+      // Check that value is always Float32x4.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                i_call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kFloat32x4Cid, target);
+      break;
+    }
+    default:
+      // Array cids are already checked in the caller.
+      UNREACHABLE();
+  }
+
+  Definition* stored_value = call->ArgumentAt(2);
+  if (!value_check.IsNull()) {
+    AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(),
+                  call);
+  }
+
+  if (view_cid == kTypedDataFloat32ArrayCid) {
+    stored_value =
+        new DoubleToFloatInstr(new Value(stored_value), call->deopt_id());
+    cursor = flow_graph()->AppendTo(cursor,
+                                    stored_value,
+                                    NULL,
+                                    Definition::kValue);
+  }
+
+  StoreBarrierType needs_store_barrier = kNoStoreBarrier;
+  *last = new StoreIndexedInstr(new Value(array),
+                                new Value(index),
+                                new Value(stored_value),
+                                needs_store_barrier,
+                                1,  // Index scale
+                                view_cid,
+                                call->deopt_id());
+
+  flow_graph()->AppendTo(cursor,
+                         *last,
+                         call->deopt_id() != Isolate::kNoDeoptId ?
+                            call->env() : NULL,
+                         Definition::kEffect);
+  return true;
+}
+
+
+
 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp(
     Instruction* call,
     intptr_t array_cid,
@@ -3129,46 +3488,7 @@
   if (simd_view && !ShouldInlineSimd()) {
     return false;
   }
-
-  ASSERT(call->HasICData());
-  Function& target = Function::Handle();
-  GrowableArray<intptr_t> class_ids;
-  call->ic_data()->GetCheckAt(0, &class_ids, &target);
-  const intptr_t receiver_cid = class_ids[0];
-
-  TargetEntryInstr* entry;
-  Definition* last;
-  if (!TryInlineRecognizedMethod(receiver_cid,
-                                 target,
-                                 call,
-                                 call->ArgumentAt(0),
-                                 call->token_pos(),
-                                 *call->ic_data(),
-                                 &entry, &last)) {
-    return false;
-  }
-
-  // Insert receiver class check.
-  AddReceiverCheck(call);
-  // Remove the original push arguments.
-  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
-    PushArgumentInstr* push = call->PushArgumentAt(i);
-    push->ReplaceUsesWith(push->value()->definition());
-    push->RemoveFromGraph();
-  }
-  // Replace all uses of this definition with the result.
-  call->ReplaceUsesWith(last);
-  // Finally insert the sequence other definition in place of this one in the
-  // graph.
-  call->previous()->LinkTo(entry->next());
-  entry->UnuseAllInputs();  // Entry block is not in the graph.
-  last->LinkTo(call);
-  // Remove through the iterator.
-  ASSERT(current_iterator()->Current() == call);
-  current_iterator()->RemoveCurrentFromGraph();
-  call->set_previous(NULL);
-  call->set_next(NULL);
-  return true;
+  return TryReplaceInstanceCallWithInline(call);
 }
 
 
@@ -3179,165 +3499,7 @@
   if (simd_view && !ShouldInlineSimd()) {
     return false;
   }
-  ASSERT(call->HasICData());
-  Function& target = Function::Handle();
-  GrowableArray<intptr_t> class_ids;
-  call->ic_data()->GetCheckAt(0, &class_ids, &target);
-  const intptr_t receiver_cid = class_ids[0];
-
-  Definition* array = call->ArgumentAt(0);
-  PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array);
-  ICData& value_check = ICData::ZoneHandle();
-  switch (view_cid) {
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid: {
-      // Check that value is always smi.
-      value_check = ICData::New(flow_graph_->parsed_function().function(),
-                                call->function_name(),
-                                Object::empty_array(),  // Dummy args. descr.
-                                Isolate::kNoDeoptId,
-                                1);
-      value_check.AddReceiverCheck(kSmiCid, target);
-      break;
-    }
-    case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid:
-      // We don't have ICData for the value stored, so we optimistically assume
-      // smis first. If we ever deoptimized here, we require to unbox the value
-      // before storing to handle the mint case, too.
-      if (call->ic_data()->deopt_reason() == kDeoptUnknown) {
-        value_check = ICData::New(flow_graph_->parsed_function().function(),
-                                  call->function_name(),
-                                  Object::empty_array(),  // Dummy args. descr.
-                                  Isolate::kNoDeoptId,
-                                  1);
-        value_check.AddReceiverCheck(kSmiCid, target);
-      }
-      break;
-    case kTypedDataFloat32ArrayCid:
-    case kTypedDataFloat64ArrayCid: {
-      // Check that value is always double.
-      value_check = ICData::New(flow_graph_->parsed_function().function(),
-                                call->function_name(),
-                                Object::empty_array(),  // Dummy args. descr.
-                                Isolate::kNoDeoptId,
-                                1);
-      value_check.AddReceiverCheck(kDoubleCid, target);
-      break;
-    }
-    case kTypedDataInt32x4ArrayCid: {
-      // Check that value is always Int32x4.
-      value_check = ICData::New(flow_graph_->parsed_function().function(),
-                                call->function_name(),
-                                Object::empty_array(),  // Dummy args. descr.
-                                Isolate::kNoDeoptId,
-                                1);
-      value_check.AddReceiverCheck(kInt32x4Cid, target);
-      break;
-    }
-    case kTypedDataFloat32x4ArrayCid: {
-      // Check that value is always Float32x4.
-      value_check = ICData::New(flow_graph_->parsed_function().function(),
-                                call->function_name(),
-                                Object::empty_array(),  // Dummy args. descr.
-                                Isolate::kNoDeoptId,
-                                1);
-      value_check.AddReceiverCheck(kFloat32x4Cid, target);
-      break;
-    }
-    default:
-      // Array cids are already checked in the caller.
-      UNREACHABLE();
-  }
-
-  Definition* index = call->ArgumentAt(1);
-  Definition* stored_value = call->ArgumentAt(2);
-  if (!value_check.IsNull()) {
-    AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(),
-                  call);
-  }
-  StoreBarrierType needs_store_barrier = kNoStoreBarrier;
-  StoreIndexedInstr* array_op = new StoreIndexedInstr(new Value(array),
-                                                      new Value(index),
-                                                      new Value(stored_value),
-                                                      needs_store_barrier,
-                                                      1,  // Index scale
-                                                      view_cid,
-                                                      call->deopt_id());
-  ReplaceCall(call, array_op);
-  return true;
-}
-
-
-void FlowGraphOptimizer::PrepareByteArrayViewOp(
-    InstanceCallInstr* call,
-    intptr_t receiver_cid,
-    intptr_t view_cid,
-    Definition** array) {
-  Definition* byte_index = call->ArgumentAt(1);
-
-  AddReceiverCheck(call);
-  const bool is_immutable = true;
-  LoadFieldInstr* length = new LoadFieldInstr(
-      new Value(*array),
-      CheckArrayBoundInstr::LengthOffsetFor(receiver_cid),
-      Type::ZoneHandle(Type::SmiType()),
-      is_immutable);
-  length->set_result_cid(kSmiCid);
-  length->set_recognized_kind(
-      LoadFieldInstr::RecognizedKindFromArrayCid(receiver_cid));
-  InsertBefore(call, length, NULL, Definition::kValue);
-
-  // len_in_bytes = length * kBytesPerElement(receiver)
-  intptr_t element_size = FlowGraphCompiler::ElementSizeFor(receiver_cid);
-  ConstantInstr* bytes_per_element =
-      flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
-  BinarySmiOpInstr* len_in_bytes =
-      new BinarySmiOpInstr(Token::kMUL,
-                           new Value(length),
-                           new Value(bytes_per_element),
-                           call->deopt_id());
-  InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
-
-  ConstantInstr* length_adjustment =
-      flow_graph()->GetConstant(Smi::Handle(Smi::New(
-          FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
-  // adjusted_length = len_in_bytes - (element_size - 1).
-  BinarySmiOpInstr* adjusted_length =
-      new BinarySmiOpInstr(Token::kSUB,
-                           new Value(len_in_bytes),
-                           new Value(length_adjustment),
-                           call->deopt_id());
-  InsertBefore(call, adjusted_length, call->env(), Definition::kValue);
-  // Check adjusted_length > 0.
-  ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
-  InsertBefore(call,
-               new CheckArrayBoundInstr(new Value(adjusted_length),
-                                        new Value(zero),
-                                        call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
-  // Check 0 <= byte_index < adjusted_length.
-  InsertBefore(call,
-               new CheckArrayBoundInstr(new Value(adjusted_length),
-                                        new Value(byte_index),
-                                        call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
-
-  // Insert load of elements for external typed arrays.
-  if (RawObject::IsExternalTypedDataClassId(receiver_cid)) {
-    LoadUntaggedInstr* elements =
-        new LoadUntaggedInstr(new Value(*array),
-                              ExternalTypedData::data_offset());
-    InsertBefore(call, elements, NULL, Definition::kValue);
-    *array = elements;
-  }
+  return TryReplaceInstanceCallWithInline(call);
 }
 
 
@@ -5201,8 +5363,8 @@
 
   const PhiPlaceMoves* phi_moves() const { return phi_moves_; }
 
-  // Returns true if the result of AllocateObject can be aliased by some
-  // other SSA variable and false otherwise. Currently simply checks if
+  // Returns true if the result of an allocation instruction can be aliased by
+  // some other SSA variable and false otherwise. Currently simply checks if
   // this value is stored in a field, escapes to another function or
   // participates in a phi.
   static bool CanBeAliased(AllocateObjectInstr* alloc) {
@@ -5548,18 +5710,6 @@
 }
 
 
-static bool HasSimpleTypeArguments(AllocateObjectInstr* alloc) {
-  if (alloc->ArgumentCount() == 0) return true;
-  ASSERT(alloc->ArgumentCount() == 2);
-  Value* arg1 = alloc->PushArgumentAt(1)->value();
-  if (!arg1->BindsToConstant()) return false;
-
-  const Object& obj = arg1->BoundConstant();
-  return obj.IsSmi()
-      && (Smi::Cast(obj).Value() == StubCode::kNoInstantiator);
-}
-
-
 class LoadOptimizer : public ValueObject {
  public:
   LoadOptimizer(FlowGraph* graph,
@@ -5675,6 +5825,7 @@
           if ((array_store == NULL) ||
               (array_store->class_id() == kArrayCid) ||
               (array_store->class_id() == kTypedDataFloat64ArrayCid) ||
+              (array_store->class_id() == kTypedDataFloat32ArrayCid) ||
               (array_store->class_id() == kTypedDataFloat32x4ArrayCid)) {
             bool is_load = false;
             Place store_place(instr, &is_load);
@@ -5722,9 +5873,7 @@
         // TODO(vegorov): record null-values at least for not final fields of
         // escaping object.
         AllocateObjectInstr* alloc = instr->AsAllocateObject();
-        if ((alloc != NULL) &&
-            !AliasedSet::CanBeAliased(alloc) &&
-            HasSimpleTypeArguments(alloc)) {
+        if ((alloc != NULL) && !AliasedSet::CanBeAliased(alloc)) {
           for (Value* use = alloc->input_use_list();
                use != NULL;
                use = use->next_use()) {
@@ -5741,7 +5890,7 @@
               if (out_values == NULL) out_values = CreateBlockOutValues();
 
               if (alloc->ArgumentCount() > 0) {
-                ASSERT(alloc->ArgumentCount() == 2);
+                ASSERT(alloc->ArgumentCount() == 1);
                 intptr_t type_args_offset =
                     alloc->cls().type_arguments_field_offset();
                 if (load->offset_in_bytes() == type_args_offset) {
@@ -7230,38 +7379,6 @@
 }
 
 
-void ConstantPropagator::VisitExtractConstructorTypeArguments(
-    ExtractConstructorTypeArgumentsInstr* instr) {
-  CompileType* type = instr->instantiator()->Type();
-  if (type->HasDecidableNullability()) {
-    if (!type->is_nullable()) {
-      SetValue(instr, instr->type_arguments());
-      return;
-    }
-    ASSERT(type->IsNull());
-    SetValue(instr, instr->instantiator()->definition()->constant_value());
-    return;
-  }
-  SetValue(instr, non_constant_);
-}
-
-
-void ConstantPropagator::VisitExtractConstructorInstantiator(
-    ExtractConstructorInstantiatorInstr* instr) {
-  CompileType* type = instr->instantiator()->Type();
-  if (type->HasDecidableNullability()) {
-    if (type->IsNull()) {
-      SetValue(instr, Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)));
-      return;
-    }
-    ASSERT(!type->is_nullable());
-    SetValue(instr, instr->instantiator()->definition()->constant_value());
-    return;
-  }
-  SetValue(instr, non_constant_);
-}
-
-
 void ConstantPropagator::VisitAllocateContext(AllocateContextInstr* instr) {
   SetValue(instr, non_constant_);
 }
@@ -7424,6 +7541,18 @@
 }
 
 
+void ConstantPropagator::VisitDoubleToFloat(DoubleToFloatInstr* instr) {
+  // TODO(kmillikin): Handle conversion.
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloatToDouble(FloatToDoubleInstr* instr) {
+  // TODO(kmillikin): Handle conversion.
+  SetValue(instr, non_constant_);
+}
+
+
 void ConstantPropagator::VisitInvokeMathCFunction(
     InvokeMathCFunctionInstr* instr) {
   // TODO(kmillikin): Handle conversion.
@@ -7654,6 +7783,28 @@
 }
 
 
+void ConstantPropagator::VisitUnboxFloat64x2(UnboxFloat64x2Instr* instr) {
+  const Object& value = instr->value()->definition()->constant_value();
+  if (IsNonConstant(value)) {
+    SetValue(instr, non_constant_);
+  } else if (IsConstant(value)) {
+    // TODO(kmillikin): Handle conversion.
+    SetValue(instr, non_constant_);
+  }
+}
+
+
+void ConstantPropagator::VisitBoxFloat64x2(BoxFloat64x2Instr* instr) {
+  const Object& value = instr->value()->definition()->constant_value();
+  if (IsNonConstant(value)) {
+    SetValue(instr, non_constant_);
+  } else if (IsConstant(value)) {
+    // TODO(kmillikin): Handle conversion.
+    SetValue(instr, non_constant_);
+  }
+}
+
+
 void ConstantPropagator::VisitUnboxInt32x4(UnboxInt32x4Instr* instr) {
   const Object& value = instr->value()->definition()->constant_value();
   if (IsNonConstant(value)) {
@@ -8259,8 +8410,6 @@
 // instructions that write into fields of the allocated object.
 // We do not support materialization of the object that has type arguments.
 static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc) {
-  if (!HasSimpleTypeArguments(alloc)) return false;
-
   for (Value* use = alloc->input_use_list();
        use != NULL;
        use = use->next_use()) {
@@ -8298,7 +8447,7 @@
   ASSERT(alloc->input_use_list() == NULL);
   alloc->RemoveFromGraph();
   if (alloc->ArgumentCount() > 0) {
-    ASSERT(alloc->ArgumentCount() == 2);
+    ASSERT(alloc->ArgumentCount() == 1);
     for (intptr_t i = 0; i < alloc->ArgumentCount(); ++i) {
       alloc->PushArgumentAt(i)->RemoveFromGraph();
     }
@@ -8473,7 +8622,7 @@
   }
 
   if (alloc->ArgumentCount() > 0) {
-    ASSERT(alloc->ArgumentCount() == 2);
+    ASSERT(alloc->ArgumentCount() == 1);
     const String& name = String::Handle(Symbols::New(":type_args"));
     const Field& type_args_field =
         Field::ZoneHandle(Field::New(
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index a3d035c..f68f52b 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -120,8 +120,23 @@
   void ReplaceWithInstanceOf(InstanceCallInstr* instr);
   void ReplaceWithTypeCast(InstanceCallInstr* instr);
 
-  LoadIndexedInstr* BuildStringCodeUnitAt(InstanceCallInstr* call,
-                                          intptr_t cid);
+  bool TryReplaceInstanceCallWithInline(InstanceCallInstr* call);
+
+  Definition* PrepareInlineStringIndexOp(Instruction* call,
+                                         intptr_t cid,
+                                         Definition* str,
+                                         Definition* index,
+                                         Instruction* cursor);
+
+  bool InlineStringCodeUnitAt(Instruction* call,
+                              intptr_t cid,
+                              TargetEntryInstr** entry,
+                              Definition** last);
+
+  bool InlineStringBaseCharAt(Instruction* call,
+                              intptr_t cid,
+                              TargetEntryInstr** entry,
+                              Definition** last);
 
   bool InlineByteArrayViewLoad(Instruction* call,
                                Definition* receiver,
@@ -131,6 +146,15 @@
                                TargetEntryInstr** entry,
                                Definition** last);
 
+  bool InlineByteArrayViewStore(const Function& target,
+                                Instruction* call,
+                                Definition* receiver,
+                                intptr_t array_cid,
+                                intptr_t view_cid,
+                                const ICData& ic_data,
+                                TargetEntryInstr** entry,
+                                Definition** last);
+
   intptr_t PrepareInlineByteArrayViewOp(Instruction* call,
                                         intptr_t array_cid,
                                         intptr_t view_cid,
@@ -142,10 +166,6 @@
                               intptr_t view_cid);
   bool BuildByteArrayViewStore(InstanceCallInstr* call,
                                intptr_t view_cid);
-  void PrepareByteArrayViewOp(InstanceCallInstr* call,
-                              intptr_t receiver_cid,
-                              intptr_t view_cid,
-                              Definition** array);
 
   // Insert a check of 'to_check' determined by 'unary_checks'.  If the
   // check fails it will deoptimize to 'deopt_id' using the deoptimization
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 2042771..b539d3b 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -1206,6 +1206,16 @@
 }
 
 
+CompileType UnboxFloat64x2Instr::ComputeType() const {
+  return CompileType::FromCid(kFloat64x2Cid);
+}
+
+
+CompileType BoxFloat64x2Instr::ComputeType() const {
+  return CompileType::FromCid(kFloat64x2Cid);
+}
+
+
 CompileType UnboxInt32x4Instr::ComputeType() const {
   return CompileType::FromCid(kInt32x4Cid);
 }
@@ -1226,6 +1236,17 @@
 }
 
 
+CompileType FloatToDoubleInstr::ComputeType() const {
+  return CompileType::FromCid(kDoubleCid);
+}
+
+
+CompileType DoubleToFloatInstr::ComputeType() const {
+  // Type is double when converted back.
+  return CompileType::FromCid(kDoubleCid);
+}
+
+
 CompileType InvokeMathCFunctionInstr::ComputeType() const {
   return CompileType::FromCid(kDoubleCid);
 }
diff --git a/runtime/vm/freelist.cc b/runtime/vm/freelist.cc
index f187841..7a9c930 100644
--- a/runtime/vm/freelist.cc
+++ b/runtime/vm/freelist.cc
@@ -43,6 +43,12 @@
 }
 
 
+intptr_t FreeListElement::HeaderSizeFor(intptr_t size) {
+  if (size == 0) return 0;
+  return ((size > RawObject::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
+}
+
+
 FreeList::FreeList() {
   Reset();
 }
@@ -65,7 +71,7 @@
       bool status =
           VirtualMemory::Protect(reinterpret_cast<void*>(element),
                                  size,
-                                 VirtualMemory::kReadWrite /*Execute*/);
+                                 VirtualMemory::kReadWrite);
       ASSERT(status);
     }
     return reinterpret_cast<uword>(element);
@@ -84,12 +90,12 @@
         // If the remainder size is zero, only the element itself needs to
         // be made writable.
         intptr_t remainder_size = element->Size() - size;
-        intptr_t region_size = size +
-            ((remainder_size > 0) ? FreeListElement::kHeaderSize : 0);
+        intptr_t region_size =
+            size + FreeListElement::HeaderSizeFor(remainder_size);
         bool status =
             VirtualMemory::Protect(reinterpret_cast<void*>(element),
                                    region_size,
-                                   VirtualMemory::kReadWrite /*Execute*/);
+                                   VirtualMemory::kReadWrite);
         ASSERT(status);
       }
       SplitElementAfterAndEnqueue(element, size, is_protected);
@@ -103,19 +109,20 @@
     if (current->Size() >= size) {
       // Found an element large enough to hold the requested size. Dequeue,
       // split and enqueue the remainder.
+      intptr_t remainder_size = current->Size() - size;
+      intptr_t region_size =
+          size + FreeListElement::HeaderSizeFor(remainder_size);
       if (is_protected) {
         // Make the allocated block and the header of the remainder element
         // writable.  The remainder will be non-writable if necessary after
         // the call to SplitElementAfterAndEnqueue.
-        intptr_t remainder_size = current->Size() - size;
-        intptr_t region_size = size +
-            ((remainder_size > 0) ? FreeListElement::kHeaderSize : 0);
         bool status =
             VirtualMemory::Protect(reinterpret_cast<void*>(current),
                                    region_size,
-                                   VirtualMemory::kReadWrite /*Execute*/);
+                                   VirtualMemory::kReadWrite);
         ASSERT(status);
       }
+
       if (previous == NULL) {
         free_lists_[kNumLists] = current->next();
       } else {
@@ -126,8 +133,7 @@
         uword target_address = 0L;
         if (is_protected) {
           uword writable_start = reinterpret_cast<uword>(current);
-          uword writable_end =
-              writable_start + size + FreeListElement::kHeaderSize - 1;
+          uword writable_end = writable_start + region_size - 1;
           target_address = previous->next_address();
           target_is_protected =
               !VirtualMemory::InSamePage(target_address, writable_start) &&
@@ -137,7 +143,7 @@
           bool status =
               VirtualMemory::Protect(reinterpret_cast<void*>(target_address),
                                      kWordSize,
-                                     VirtualMemory::kReadWrite /*Execute*/);
+                                     VirtualMemory::kReadWrite);
           ASSERT(status);
         }
         previous->set_next(current->next());
diff --git a/runtime/vm/freelist.h b/runtime/vm/freelist.h
index 9bed00e..adfeb63 100644
--- a/runtime/vm/freelist.h
+++ b/runtime/vm/freelist.h
@@ -19,9 +19,6 @@
 // the element at the address following the next_ field.
 class FreeListElement {
  public:
-  // Maximum header size is three words (tags, next, and size).
-  static const intptr_t kHeaderSize = 3 * kWordSize;
-
   FreeListElement* next() const {
     return next_;
   }
@@ -43,6 +40,8 @@
 
   static void InitOnce();
 
+  static intptr_t HeaderSizeFor(intptr_t size);
+
   // Used to allocate class for free list elements in Object::InitOnce.
   class FakeInstance {
    public:
diff --git a/runtime/vm/freelist_test.cc b/runtime/vm/freelist_test.cc
index fc506d7..b7cfbca 100644
--- a/runtime/vm/freelist_test.cc
+++ b/runtime/vm/freelist_test.cc
@@ -8,47 +8,189 @@
 
 namespace dart {
 
-TEST_CASE(FreeList) {
-  FreeList* free_list = new FreeList();
-  intptr_t kBlobSize = 1 * MB;
-  intptr_t kSmallObjectSize = 4 * kWordSize;
-  intptr_t kMediumObjectSize = 16 * kWordSize;
-  intptr_t kLargeObjectSize = 8 * KB;
-  uword blob = reinterpret_cast<uword>(malloc(kBlobSize));
+static uword Allocate(FreeList* free_list, intptr_t size, bool is_protected) {
+  uword result = free_list->TryAllocate(size, is_protected);
+  if (result && is_protected) {
+    bool status = VirtualMemory::Protect(reinterpret_cast<void*>(result),
+                                         size,
+                                         VirtualMemory::kReadExecute);
+    ASSERT(status);
+  }
+  return result;
+}
+
+
+static void Free(FreeList* free_list,
+                 uword address,
+                 intptr_t size,
+                 bool is_protected) {
+  if (is_protected) {
+    bool status = VirtualMemory::Protect(reinterpret_cast<void*>(address),
+                                         size,
+                                         VirtualMemory::kReadWrite);
+    ASSERT(status);
+  }
+  free_list->Free(address, size);
+  if (is_protected) {
+    bool status = VirtualMemory::Protect(reinterpret_cast<void*>(address),
+                                         size,
+                                         VirtualMemory::kReadExecute);
+    ASSERT(status);
+  }
+}
+
+
+static void TestFreeList(VirtualMemory* region,
+                         FreeList* free_list,
+                         bool is_protected) {
+  const intptr_t kSmallObjectSize = 4 * kWordSize;
+  const intptr_t kMediumObjectSize = 16 * kWordSize;
+  const intptr_t kLargeObjectSize = 8 * KB;
+  uword blob = region->start();
   // Enqueue the large blob as one free block.
-  free_list->Free(blob, kBlobSize);
+  free_list->Free(blob, region->size());
+
+  if (is_protected) {
+    // Write protect the whole region.
+    region->Protect(VirtualMemory::kReadExecute);
+  }
+
   // Allocate a small object. Expect it to be positioned as the first element.
-  uword small_object = free_list->TryAllocate(kSmallObjectSize, false);
+  uword small_object = Allocate(free_list, kSmallObjectSize, is_protected);
   EXPECT_EQ(blob, small_object);
   // Freeing and allocating should give us the same memory back.
-  free_list->Free(small_object, kSmallObjectSize);
-  small_object = free_list->TryAllocate(kSmallObjectSize, false);
+  Free(free_list, small_object, kSmallObjectSize, is_protected);
+  small_object = Allocate(free_list, kSmallObjectSize, is_protected);
   EXPECT_EQ(blob, small_object);
   // Splitting the remainder further with small and medium objects.
-  uword small_object2 = free_list->TryAllocate(kSmallObjectSize, false);
+  uword small_object2 = Allocate(free_list, kSmallObjectSize, is_protected);
   EXPECT_EQ(blob + kSmallObjectSize, small_object2);
-  uword med_object = free_list->TryAllocate(kMediumObjectSize, false);
+  uword med_object = Allocate(free_list, kMediumObjectSize, is_protected);
   EXPECT_EQ(small_object2 + kSmallObjectSize, med_object);
   // Allocate a large object.
-  uword large_object = free_list->TryAllocate(kLargeObjectSize, false);
+  uword large_object = Allocate(free_list, kLargeObjectSize, is_protected);
   EXPECT_EQ(med_object + kMediumObjectSize, large_object);
   // Make sure that small objects can still split the remainder.
-  uword small_object3 = free_list->TryAllocate(kSmallObjectSize, false);
+  uword small_object3 = Allocate(free_list, kSmallObjectSize, is_protected);
   EXPECT_EQ(large_object + kLargeObjectSize, small_object3);
   // Split the large object.
-  free_list->Free(large_object, kLargeObjectSize);
-  uword small_object4 = free_list->TryAllocate(kSmallObjectSize, false);
+  Free(free_list, large_object, kLargeObjectSize, is_protected);
+  uword small_object4 = Allocate(free_list, kSmallObjectSize, is_protected);
   EXPECT_EQ(large_object, small_object4);
   // Get the full remainder of the large object.
   large_object =
-      free_list->TryAllocate(kLargeObjectSize - kSmallObjectSize, false);
+      Allocate(free_list, kLargeObjectSize - kSmallObjectSize, is_protected);
   EXPECT_EQ(small_object4 + kSmallObjectSize, large_object);
   // Get another large object from the large unallocated remainder.
-  uword large_object2 = free_list->TryAllocate(kLargeObjectSize, false);
+  uword large_object2 = Allocate(free_list, kLargeObjectSize, is_protected);
   EXPECT_EQ(small_object3 + kSmallObjectSize, large_object2);
+}
+
+TEST_CASE(FreeList) {
+  FreeList* free_list = new FreeList();
+  const intptr_t kBlobSize = 1 * MB;
+  VirtualMemory* region = VirtualMemory::Reserve(kBlobSize);
+  region->Commit(/* is_executable */ false);
+
+  TestFreeList(region, free_list, false);
+
   // Delete the memory associated with the test.
-  free(reinterpret_cast<void*>(blob));
+  delete region;
   delete free_list;
 }
 
+
+TEST_CASE(FreeListProtected) {
+  FreeList* free_list = new FreeList();
+  const intptr_t kBlobSize = 1 * MB;
+  VirtualMemory* region = VirtualMemory::Reserve(kBlobSize);
+  region->Commit(/* is_executable */ false);
+
+  TestFreeList(region, free_list, true);
+
+  // Delete the memory associated with the test.
+  delete region;
+  delete free_list;
+}
+
+
+TEST_CASE(FreeListProtectedTinyObjects) {
+  FreeList* free_list = new FreeList();
+  const intptr_t kBlobSize = 1 * MB;
+  const intptr_t kObjectSize = 2 * kWordSize;
+  uword* objects = new uword[kBlobSize / kObjectSize];
+
+  VirtualMemory* blob = VirtualMemory::ReserveAligned(kBlobSize, 4096);
+  blob->Commit(/* is_executable = */ false);
+  blob->Protect(VirtualMemory::kReadWrite);
+
+  // Enqueue the large blob as one free block.
+  free_list->Free(blob->start(), blob->size());
+
+  // Write protect the whole region.
+  blob->Protect(VirtualMemory::kReadExecute);
+
+  // Allocate small objects.
+  for (intptr_t i = 0; i < blob->size() / kObjectSize; i++) {
+    objects[i] = Allocate(free_list,
+                          kObjectSize,
+                          true);  // is_protected
+  }
+
+  // All space is occupied. Expect failed allocation.
+  ASSERT(Allocate(free_list, kObjectSize, true) == 0);
+
+  // Free all objects again. Make the whole region writable for this.
+  blob->Protect(VirtualMemory::kReadWrite);
+  for (intptr_t i = 0; i < blob->size() / kObjectSize; i++) {
+    free_list->Free(objects[i], kObjectSize);
+  }
+
+  // Delete the memory associated with the test.
+  delete blob;
+  delete free_list;
+  delete[] objects;
+}
+
+
+TEST_CASE(FreeListProtectedVariableSizeObjects) {
+  FreeList* free_list = new FreeList();
+  const intptr_t kBlobSize = 8 * KB;
+  const intptr_t kMinSize = 2 * kWordSize;
+  uword* objects = new uword[kBlobSize / kMinSize];
+  for (intptr_t i = 0; i < kBlobSize / kMinSize; ++i) {
+    objects[i] = NULL;
+  }
+
+  VirtualMemory* blob = VirtualMemory::ReserveAligned(kBlobSize, 4096);
+  blob->Commit(/* is_executable = */ false);
+  blob->Protect(VirtualMemory::kReadWrite);
+
+  // Enqueue the large blob as one free block.
+  free_list->Free(blob->start(), blob->size());
+
+  // Write protect the whole region.
+  blob->Protect(VirtualMemory::kReadExecute);
+
+  // Allocate and free objects so that free list has > 1 elements.
+  uword e0 = Allocate(free_list, 1 * KB, true);
+  ASSERT(e0);
+  uword e1 = Allocate(free_list, 3 * KB, true);
+  ASSERT(e1);
+  uword e2 = Allocate(free_list, 2 * KB, true);
+  ASSERT(e2);
+  uword e3 = Allocate(free_list, 2 * KB, true);
+  ASSERT(e3);
+
+  Free(free_list, e1, 3 * KB, true);
+  Free(free_list, e2, 2 * KB, true);
+  e0 = Allocate(free_list, 3 * KB - 2 * kWordSize, true);
+  ASSERT(e0);
+
+  // Delete the memory associated with the test.
+  delete blob;
+  delete free_list;
+  delete[] objects;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 682c75a..a4f0d2d 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -551,14 +551,6 @@
 }
 
 
-void ExtractConstructorTypeArgumentsInstr::PrintOperandsTo(
-    BufferFormatter* f) const {
-  const String& type_args = String::Handle(type_arguments().Name());
-  f->Print("%s, ", type_args.ToCString());
-  instantiator()->PrintTo(f);
-}
-
-
 void AllocateContextInstr::PrintOperandsTo(BufferFormatter* f) const {
   f->Print("%" Pd "", num_context_variables());
 }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 9a06cfd..d8df9e5 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -6,6 +6,7 @@
 
 #include "vm/bigint_operations.h"
 #include "vm/bit_vector.h"
+#include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph_allocator.h"
 #include "vm/flow_graph_builder.h"
@@ -33,6 +34,7 @@
 DECLARE_FLAG(bool, trace_optimization);
 DECLARE_FLAG(bool, trace_constant_propagation);
 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
+DECLARE_FLAG(bool, enable_type_checks);
 
 Definition::Definition()
     : range_(NULL),
@@ -1284,6 +1286,35 @@
 }
 
 
+Definition* DoubleToFloatInstr::Canonicalize(FlowGraph* flow_graph) {
+#ifdef DEBUG
+  // Must only be used in Float32 StoreIndexedInstr or FloatToDoubleInstr or
+  // Phis introduce by load forwarding.
+  ASSERT(env_use_list() == NULL);
+  for (Value* use = input_use_list();
+       use != NULL;
+       use = use->next_use()) {
+    ASSERT(use->instruction()->IsPhi() ||
+           use->instruction()->IsFloatToDouble() ||
+           (use->instruction()->IsStoreIndexed() &&
+            (use->instruction()->AsStoreIndexed()->class_id() ==
+             kTypedDataFloat32ArrayCid)));
+  }
+#endif
+  if (!HasUses()) return NULL;
+  if (value()->definition()->IsFloatToDouble()) {
+    // F2D(D2F(v)) == v.
+    return value()->definition()->AsFloatToDouble()->value()->definition();
+  }
+  return this;
+}
+
+
+Definition* FloatToDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
+  return HasUses() ? this : NULL;
+}
+
+
 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraph* flow_graph) {
   Definition* result = NULL;
 
@@ -1434,10 +1465,14 @@
   // call we can replace the length load with the length argument passed to
   // the constructor.
   StaticCallInstr* call = instance()->definition()->AsStaticCall();
-  if ((call != NULL) &&
-      call->is_known_list_constructor() &&
-      IsFixedLengthArrayCid(call->Type()->ToCid())) {
-    return call->ArgumentAt(1);
+  if (call != NULL) {
+    if (call->is_known_list_constructor() &&
+        IsFixedLengthArrayCid(call->Type()->ToCid())) {
+      return call->ArgumentAt(1);
+    }
+    if (call->is_native_list_factory()) {
+      return call->ArgumentAt(0);
+    }
   }
   // For arrays with guarded lengths, replace the length load
   // with a constant.
@@ -1498,6 +1533,11 @@
 }
 
 
+Definition* InstantiateTypeArgumentsInstr::Canonicalize(FlowGraph* flow_graph) {
+  return (FLAG_enable_type_checks || HasUses()) ? this : NULL;
+}
+
+
 LocationSummary* DebugStepCheckInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 0;
   const intptr_t kNumTemps = 0;
@@ -1566,6 +1606,30 @@
 }
 
 
+Definition* BoxFloat64x2Instr::Canonicalize(FlowGraph* flow_graph) {
+  if (input_use_list() == NULL) {
+    // Environments can accomodate any representation. No need to box.
+    return value()->definition();
+  }
+
+  // Fold away BoxFloat64x2(UnboxFloat64x2(v)).
+  UnboxFloat64x2Instr* defn = value()->definition()->AsUnboxFloat64x2();
+  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat64x2Cid)) {
+    return defn->value()->definition();
+  }
+
+  return this;
+}
+
+
+Definition* UnboxFloat64x2Instr::Canonicalize(FlowGraph* flow_graph) {
+  // Fold away UnboxFloat64x2(BoxFloat64x2(v)).
+  BoxFloat64x2Instr* defn = value()->definition()->AsBoxFloat64x2();
+  return (defn != NULL) ? defn->value()->definition() : this;
+}
+
+
+
 Definition* BoxInt32x4Instr::Canonicalize(FlowGraph* flow_graph) {
   if (input_use_list() == NULL) {
     // Environments can accomodate any representation. No need to box.
@@ -1808,7 +1872,23 @@
   }
 
   if (field().guarded_list_length() != Field::kNoFixedLength) {
-    // We are still guarding the list length.
+    // We are still guarding the list length. Check if length is statically
+    // known.
+    StaticCallInstr* call = value()->definition()->AsStaticCall();
+    if (call != NULL) {
+      ConstantInstr* length = NULL;
+      if (call->is_known_list_constructor() &&
+          LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) {
+        length = call->ArgumentAt(1)->AsConstant();
+      }
+      if (call->is_native_list_factory()) {
+        length = call->ArgumentAt(0)->AsConstant();
+      }
+      if ((length != NULL) && length->value().IsSmi()) {
+        intptr_t known_length = Smi::Cast(length->value()).Value();
+        return (known_length != field().guarded_list_length()) ? this : NULL;
+      }
+    }
     return this;
   }
 
@@ -3029,7 +3109,7 @@
     case MethodRecognizer::kDoubleTruncate:
     case MethodRecognizer::kDoubleFloor:
     case MethodRecognizer::kDoubleCeil: {
-      ASSERT(!CPUFeatures::double_truncate_round_supported());
+      ASSERT(!TargetCPUFeatures::double_truncate_round_supported());
       return 1;
     }
     case MethodRecognizer::kDoubleRound:
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 17272be..427ae91 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -168,6 +168,9 @@
   V(_Float32x4Array, []=, Float32x4ArraySetIndexed, 1583018506)                \
   V(_Int32x4Array, [], Int32x4ArrayGetIndexed, 1911863146)                     \
   V(_Int32x4Array, []=, Int32x4ArraySetIndexed, 973572811)                     \
+  V(_Float64x2Array, [], Float64x2ArrayGetIndexed, 325873961)                  \
+  V(_Float64x2Array, []=, Float64x2ArraySetIndexed, 2105580462)                \
+
 
 
 // A list of core function that should always be inlined.
@@ -183,6 +186,8 @@
 
 // A list of core functions that internally dispatch based on received id.
 #define POLYMORPHIC_TARGET_LIST(V)                                             \
+  V(_StringBase, [], StringBaseCharAt, 585372763)                              \
+  V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1958436584)                 \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802)                     \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841)                   \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1832126257)                  \
@@ -193,6 +198,16 @@
   V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1356392173)              \
   V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1239681356)          \
   V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 163795162)               \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1793798234)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 67253374)                     \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 10467750)                    \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 1596986894)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 868037529)                   \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1776345006)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1807927533)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 399659907)               \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1612092224)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 74799321)                \
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -638,8 +653,6 @@
   M(LoadClassId)                                                               \
   M(InstantiateType)                                                           \
   M(InstantiateTypeArguments)                                                  \
-  M(ExtractConstructorTypeArguments)                                           \
-  M(ExtractConstructorInstantiator)                                            \
   M(AllocateContext)                                                           \
   M(CloneContext)                                                              \
   M(BinarySmiOp)                                                               \
@@ -650,6 +663,8 @@
   M(DoubleToInteger)                                                           \
   M(DoubleToSmi)                                                               \
   M(DoubleToDouble)                                                            \
+  M(DoubleToFloat)                                                             \
+  M(FloatToDouble)                                                             \
   M(CheckClass)                                                                \
   M(CheckSmi)                                                                  \
   M(Constant)                                                                  \
@@ -700,6 +715,8 @@
   M(Int32x4ToFloat32x4)                                                        \
   M(BinaryInt32x4Op)                                                           \
   M(TestSmi)                                                                   \
+  M(BoxFloat64x2)                                                              \
+  M(UnboxFloat64x2)                                                            \
 
 
 #define FORWARD_DECLARATION(type) class type##Instr;
@@ -966,6 +983,7 @@
   friend class UnboxIntegerInstr;
   friend class UnboxDoubleInstr;
   friend class UnboxFloat32x4Instr;
+  friend class UnboxFloat64x2Instr;
   friend class UnboxInt32x4Instr;
   friend class BinaryDoubleOpInstr;
   friend class BinaryFloat32x4OpInstr;
@@ -1005,6 +1023,8 @@
   friend class LICM;
   friend class DoubleToSmiInstr;
   friend class DoubleToDoubleInstr;
+  friend class DoubleToFloatInstr;
+  friend class FloatToDoubleInstr;
   friend class InvokeMathCFunctionInstr;
   friend class MergedMathInstr;
   friend class FlowGraphOptimizer;
@@ -3187,7 +3207,8 @@
         argument_names_(argument_names),
         arguments_(arguments),
         result_cid_(kDynamicCid),
-        is_known_list_constructor_(false) {
+        is_known_list_constructor_(false),
+        is_native_list_factory_(false) {
     ASSERT(function.IsZoneHandle());
     ASSERT(argument_names.IsZoneHandle() ||  argument_names.InVMHeap());
   }
@@ -3226,6 +3247,11 @@
     is_known_list_constructor_ = value;
   }
 
+  bool is_native_list_factory() const { return is_native_list_factory_; }
+  void set_is_native_list_factory(bool value) {
+    is_native_list_factory_ = value;
+  }
+
   virtual bool MayThrow() const { return true; }
 
  private:
@@ -3238,6 +3264,7 @@
 
   // 'True' for recognized list constructors.
   bool is_known_list_constructor_;
+  bool is_native_list_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(StaticCallInstr);
 };
@@ -3698,9 +3725,9 @@
  public:
   StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
     ASSERT(char_code != NULL);
-    ASSERT(char_code->definition()->IsLoadIndexed() &&
-           (char_code->definition()->AsLoadIndexed()->class_id() ==
-            kOneByteStringCid));
+    ASSERT(char_code->definition()->IsLoadIndexed());
+    ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
+           kOneByteStringCid);
     SetInputAt(0, char_code);
   }
 
@@ -3939,7 +3966,7 @@
         closure_function_(Function::ZoneHandle()),
         context_field_(Field::ZoneHandle()) {
     // Either no arguments or one type-argument and one instantiator.
-    ASSERT(arguments->is_empty() || (arguments->length() == 2));
+    ASSERT(arguments->is_empty() || (arguments->length() == 1));
   }
 
   DECLARE_INSTRUCTION(AllocateObject)
@@ -4388,6 +4415,8 @@
 
   virtual bool MayThrow() const { return true; }
 
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
  private:
   const intptr_t token_pos_;
   const TypeArguments& type_arguments_;
@@ -4397,78 +4426,6 @@
 };
 
 
-class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> {
- public:
-  ExtractConstructorTypeArgumentsInstr(
-      intptr_t token_pos,
-      const TypeArguments& type_arguments,
-      const Class& instantiator_class,
-      Value* instantiator)
-      : token_pos_(token_pos),
-        type_arguments_(type_arguments),
-        instantiator_class_(instantiator_class) {
-    SetInputAt(0, instantiator);
-  }
-
-  DECLARE_INSTRUCTION(ExtractConstructorTypeArguments)
-
-  Value* instantiator() const { return inputs_[0]; }
-  const TypeArguments& type_arguments() const {
-    return type_arguments_;
-  }
-  const Class& instantiator_class() const { return instantiator_class_; }
-  intptr_t token_pos() const { return token_pos_; }
-
-  virtual void PrintOperandsTo(BufferFormatter* f) const;
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual EffectSet Effects() const { return EffectSet::None(); }
-
-  virtual bool MayThrow() const { return false; }
-
- private:
-  const intptr_t token_pos_;
-  const TypeArguments& type_arguments_;
-  const Class& instantiator_class_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr);
-};
-
-
-class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> {
- public:
-  ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node,
-                                      const Class& instantiator_class,
-                                      Value* instantiator)
-      : ast_node_(*ast_node), instantiator_class_(instantiator_class) {
-    SetInputAt(0, instantiator);
-  }
-
-  DECLARE_INSTRUCTION(ExtractConstructorInstantiator)
-
-  Value* instantiator() const { return inputs_[0]; }
-  const TypeArguments& type_arguments() const {
-    return ast_node_.type_arguments();
-  }
-  const Function& constructor() const { return ast_node_.constructor(); }
-  const Class& instantiator_class() const { return instantiator_class_; }
-  intptr_t token_pos() const { return ast_node_.token_pos(); }
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual EffectSet Effects() const { return EffectSet::None(); }
-
-  virtual bool MayThrow() const { return false; }
-
- private:
-  const ConstructorCallNode& ast_node_;
-  const Class& instantiator_class_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr);
-};
-
-
 class AllocateContextInstr : public TemplateDefinition<0> {
  public:
   AllocateContextInstr(intptr_t token_pos,
@@ -4630,6 +4587,43 @@
 };
 
 
+class BoxFloat64x2Instr : public TemplateDefinition<1> {
+ public:
+  explicit BoxFloat64x2Instr(Value* value) {
+    SetInputAt(0, value);
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    return Isolate::kNoDeoptId;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedFloat64x2;
+  }
+
+  DECLARE_INSTRUCTION(BoxFloat64x2)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual bool MayThrow() const { return false; }
+
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BoxFloat64x2Instr);
+};
+
+
+
 class BoxInt32x4Instr : public TemplateDefinition<1> {
  public:
   explicit BoxInt32x4Instr(Value* value) {
@@ -4769,6 +4763,40 @@
 };
 
 
+class UnboxFloat64x2Instr : public TemplateDefinition<1> {
+ public:
+  UnboxFloat64x2Instr(Value* value, intptr_t deopt_id) {
+    SetInputAt(0, value);
+    deopt_id_ = deopt_id;
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  virtual bool CanDeoptimize() const {
+    return (value()->Type()->ToCid() != kFloat64x2Cid);
+  }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat64x2;
+  }
+
+  DECLARE_INSTRUCTION(UnboxFloat64x2)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual bool MayThrow() const { return false; }
+
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UnboxFloat64x2Instr);
+};
+
+
 class UnboxInt32x4Instr : public TemplateDefinition<1> {
  public:
   UnboxInt32x4Instr(Value* value, intptr_t deopt_id) {
@@ -6599,6 +6627,92 @@
 };
 
 
+class DoubleToFloatInstr: public TemplateDefinition<1> {
+ public:
+  DoubleToFloatInstr(Value* value, intptr_t deopt_id) {
+    SetInputAt(0, value);
+    // Override generated deopt-id.
+    deopt_id_ = deopt_id;
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  DECLARE_INSTRUCTION(DoubleToFloat)
+
+  virtual CompileType ComputeType() const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    // This works since double is the representation that the typed array
+    // store expects.
+    // TODO(fschneider): Change this to a genuine float representation once it
+    // is supported.
+    return kUnboxedDouble;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedDouble;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual bool MayThrow() const { return false; }
+
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr);
+};
+
+
+class FloatToDoubleInstr: public TemplateDefinition<1> {
+ public:
+  FloatToDoubleInstr(Value* value, intptr_t deopt_id) {
+    SetInputAt(0, value);
+    // Override generated deopt-id.
+    deopt_id_ = deopt_id;
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  DECLARE_INSTRUCTION(FloatToDouble)
+
+  virtual CompileType ComputeType() const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kUnboxedDouble;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedDouble;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual bool MayThrow() const { return false; }
+
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FloatToDoubleInstr);
+};
+
+
 class InvokeMathCFunctionInstr : public Definition {
  public:
   InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 55c8e2c..3f32880 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -829,6 +829,8 @@
       return CompileType::FromCid(kFloat32x4Cid);
     case kTypedDataInt32x4ArrayCid:
       return CompileType::FromCid(kInt32x4Cid);
+    case kTypedDataFloat64x2ArrayCid:
+      return CompileType::FromCid(kFloat64x2Cid);
 
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
@@ -882,6 +884,8 @@
       return kUnboxedInt32x4;
     case kTypedDataFloat32x4ArrayCid:
       return kUnboxedFloat32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNREACHABLE();
       return kTagged;
@@ -899,10 +903,18 @@
   // tagged (for all element sizes > 1).
   // TODO(regis): Revisit and see if the index can be immediate.
   locs->set_in(1, Location::WritableRegister());
-  if ((representation() == kUnboxedDouble) ||
+  if ((representation() == kUnboxedDouble)    ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
-    locs->set_out(Location::RequiresFpuRegister());
+      (representation() == kUnboxedInt32x4)   ||
+      (representation() == kUnboxedFloat64x2)) {
+    if (class_id() == kTypedDataFloat32ArrayCid) {
+      // Need register <= Q7 for float operations.
+      // TODO(fschneider): Add a register policy to specify a subset of
+      // registers.
+      locs->set_out(Location::FpuRegisterLocation(Q7));
+    } else {
+      locs->set_out(Location::RequiresFpuRegister());
+    }
   } else {
     locs->set_out(Location::RequiresRegister());
   }
@@ -951,10 +963,11 @@
   }
   element_address = Address(array, index.reg(), LSL, 0);
 
-  if ((representation() == kUnboxedDouble) ||
-      (representation() == kUnboxedMint) ||
+  if ((representation() == kUnboxedDouble)    ||
+      (representation() == kUnboxedMint)      ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
+      (representation() == kUnboxedInt32x4)   ||
+      (representation() == kUnboxedFloat64x2)) {
     QRegister result = locs()->out().fpu_reg();
     DRegister dresult0 = EvenDRegisterOf(result);
     DRegister dresult1 = OddDRegisterOf(result);
@@ -966,12 +979,11 @@
         UNIMPLEMENTED();
         break;
       case kTypedDataFloat32ArrayCid:
-        // Load single precision float and promote to double.
+        // Load single precision float.
         // vldrs does not support indexed addressing.
         __ add(index.reg(), index.reg(), ShifterOperand(array));
         element_address = Address(index.reg(), 0);
-        __ vldrs(STMP, element_address);
-        __ vcvtds(dresult0, STMP);
+        __ vldrs(EvenSRegisterOf(dresult0), element_address);
         break;
       case kTypedDataFloat64ArrayCid:
         // vldrd does not support indexed addressing.
@@ -979,11 +991,13 @@
         element_address = Address(index.reg(), 0);
         __ vldrd(dresult0, element_address);
         break;
+      case kTypedDataFloat64x2ArrayCid:
       case kTypedDataInt32x4ArrayCid:
       case kTypedDataFloat32x4ArrayCid:
         __ add(index.reg(), index.reg(), ShifterOperand(array));
+        // TODO(zra): Maybe use vldmd here.
         __ LoadDFromOffset(dresult0, index.reg(), 0);
-        __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize);
+        __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize);
         break;
     }
     return;
@@ -1067,6 +1081,8 @@
       return kUnboxedFloat32x4;
     case kTypedDataInt32x4ArrayCid:
       return kUnboxedInt32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNREACHABLE();
       return kTagged;
@@ -1103,9 +1119,13 @@
       locs->set_in(2, Location::WritableRegister());
       break;
     case kTypedDataFloat32ArrayCid:
+      // Need low register (<= Q7).
+      locs->set_in(2, Location::FpuRegisterLocation(Q7));
+      break;
     case kTypedDataFloat64ArrayCid:  // TODO(srdjan): Support Float64 constants.
     case kTypedDataInt32x4ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid:
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
     default:
@@ -1231,12 +1251,10 @@
       break;
     }
     case kTypedDataFloat32ArrayCid: {
-      DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg());
-      // Convert to single precision.
-      __ vcvtsd(STMP, in2);
-      // Store.
+      SRegister value =
+          EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));
       __ add(index.reg(), index.reg(), ShifterOperand(array));
-      __ StoreSToOffset(STMP, index.reg(), 0);
+      __ StoreSToOffset(value, index.reg(), 0);
       break;
     }
     case kTypedDataFloat64ArrayCid: {
@@ -1245,6 +1263,7 @@
       __ StoreDToOffset(in2, index.reg(), 0);
       break;
     }
+    case kTypedDataFloat64x2ArrayCid:
     case kTypedDataInt32x4ArrayCid:
     case kTypedDataFloat32x4ArrayCid: {
       QRegister in = locs()->in(2).fpu_reg();
@@ -1252,7 +1271,7 @@
       DRegister din1 = OddDRegisterOf(in);
       __ add(index.reg(), index.reg(), ShifterOperand(array));
       __ StoreDToOffset(din0, index.reg(), 0);
-      __ StoreDToOffset(din1, index.reg(), 2*kWordSize);
+      __ StoreDToOffset(din1, index.reg(), 2 * kWordSize);
       break;
     }
     default:
@@ -1697,7 +1716,7 @@
         __ StoreDToOffset(value, temp,
             Float32x4::value_offset() - kHeapObjectTag);
         __ StoreDToOffset(value_odd, temp,
-            Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+            Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
         break;
       default:
         UNREACHABLE();
@@ -1796,14 +1815,15 @@
                          FieldAddress(instance_reg, field().Offset()),
                          temp2);
       __ Bind(&copy_float32x4);
+      // TODO(zra): Maybe use vldmd here.
       __ LoadDFromOffset(fpu_temp, value_reg,
           Float32x4::value_offset() - kHeapObjectTag);
       __ LoadDFromOffset(fpu_temp_odd, value_reg,
-          Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+          Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
       __ StoreDToOffset(fpu_temp, temp,
           Float32x4::value_offset() - kHeapObjectTag);
       __ StoreDToOffset(fpu_temp_odd, temp,
-          Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+          Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
       __ b(&skip_store);
     }
 
@@ -1995,6 +2015,38 @@
 };
 
 
+class BoxFloat64x2SlowPath : public SlowPathCode {
+ public:
+  explicit BoxFloat64x2SlowPath(Instruction* instruction)
+      : instruction_(instruction) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    __ Comment("BoxFloat64x2SlowPath");
+    __ Bind(entry_label());
+    const Class& float64x2_class = compiler->float64x2_class();
+    const Code& stub =
+        Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
+    const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
+
+    LocationSummary* locs = instruction_->locs();
+    locs->live_registers()->Remove(locs->out());
+
+    compiler->SaveLiveRegisters(locs);
+    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+                           &label,
+                           PcDescriptors::kOther,
+                           locs);
+    __ mov(locs->out().reg(), ShifterOperand(R0));
+    compiler->RestoreLiveRegisters(locs);
+
+    __ b(exit_label());
+  }
+
+ private:
+  Instruction* instruction_;
+};
+
+
 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -2035,10 +2087,11 @@
         break;
       case kFloat32x4Cid:
         __ Comment("UnboxedFloat32x4LoadFieldInstr");
+        // TODO(zra): Maybe use vldmd here.
         __ LoadDFromOffset(result, temp,
             Float32x4::value_offset() - kHeapObjectTag);
         __ LoadDFromOffset(result_odd, temp,
-            Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+            Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
         break;
       default:
         UNREACHABLE();
@@ -2111,14 +2164,15 @@
                      temp);
       __ Bind(slow_path->exit_label());
       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
+      // TODO(zra): Maybe use vldmd here.
       __ LoadDFromOffset(value, temp,
           Float32x4::value_offset() - kHeapObjectTag);
       __ LoadDFromOffset(value_odd, temp,
-          Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+          Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
       __ StoreDToOffset(value, result_reg,
           Float32x4::value_offset() - kHeapObjectTag);
       __ StoreDToOffset(value_odd, result_reg,
-          Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+          Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
       __ b(&done);
     }
 
@@ -2177,6 +2231,8 @@
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
+  ASSERT(instantiator_reg == R0);
+  ASSERT(instantiator_reg == result_reg);
 
   // 'instantiator_reg' is the instantiator TypeArguments object (or null).
   ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
@@ -2192,6 +2248,26 @@
     __ cmp(instantiator_reg, ShifterOperand(IP));
     __ b(&type_arguments_instantiated, EQ);
   }
+
+  __ LoadObject(R2, type_arguments());
+  __ ldr(R2, FieldAddress(R2, TypeArguments::instantiations_offset()));
+  __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag);
+  // The instantiations cache is initialized with Object::zero_array() and is
+  // therefore guaranteed to contain kNoInstantiator. No length check needed.
+  Label loop, found, slow_case;
+  __ Bind(&loop);
+  __ ldr(R1, Address(R2, 0 * kWordSize));  // Cached instantiator.
+  __ cmp(R1, ShifterOperand(R0));
+  __ b(&found, EQ);
+  __ AddImmediate(R2, 2 * kWordSize);
+  __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator));
+  __ b(&loop, NE);
+  __ b(&slow_case);
+  __ Bind(&found);
+  __ ldr(R0, Address(R2, 1 * kWordSize));  // Cached instantiated args.
+  __ b(&type_arguments_instantiated);
+
+  __ Bind(&slow_case);
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
@@ -2205,88 +2281,6 @@
   __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
   __ Pop(result_reg);  // Pop instantiated type arguments.
   __ Bind(&type_arguments_instantiated);
-  ASSERT(instantiator_reg == result_reg);
-}
-
-
-LocationSummary*
-ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  Register result_reg = locs()->out().reg();
-  ASSERT(instantiator_reg == result_reg);
-
-  // instantiator_reg is the instantiator type argument vector,
-  // i.e. a TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  __ CompareImmediate(instantiator_reg,
-                      reinterpret_cast<intptr_t>(Object::null()));
-  __ b(&type_arguments_instantiated, EQ);
-  // Instantiate non-null type arguments.
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments());
-  // result_reg: uninstantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
-
-  // result_reg: uninstantiated or instantiated type arguments.
-}
-
-
-LocationSummary*
-ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorInstantiatorInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  ASSERT(locs()->out().reg() == instantiator_reg);
-
-  // instantiator_reg is the instantiator TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  Label instantiator_not_null;
-  __ CompareImmediate(instantiator_reg,
-                      reinterpret_cast<intptr_t>(Object::null()));
-  __ b(&instantiator_not_null, NE);
-  // Null was used in VisitExtractConstructorTypeArguments as the
-  // instantiated type arguments, no proper instantiator needed.
-  __ LoadImmediate(instantiator_reg,
-                   Smi::RawValue(StubCode::kNoInstantiator));
-  __ Bind(&instantiator_not_null);
-  // instantiator_reg: instantiator or kNoInstantiator.
 }
 
 
@@ -3035,7 +3029,7 @@
   __ StoreDToOffset(value_even, out_reg,
       Float32x4::value_offset() - kHeapObjectTag);
   __ StoreDToOffset(value_odd, out_reg,
-      Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+      Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
 }
 
 
@@ -3071,10 +3065,87 @@
 
   const DRegister result_even = EvenDRegisterOf(result);
   const DRegister result_odd = OddDRegisterOf(result);
+  // TODO(zra): Maybe use vldmd here.
   __ LoadDFromOffset(result_even, value,
       Float32x4::value_offset() - kHeapObjectTag);
   __ LoadDFromOffset(result_odd, value,
-      Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+      Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
+}
+
+
+LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs,
+                          kNumTemps,
+                          LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_temp(0, Location::RequiresRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
+  compiler->AddSlowPathCode(slow_path);
+
+  Register out_reg = locs()->out().reg();
+  QRegister value = locs()->in(0).fpu_reg();
+  DRegister value_even = EvenDRegisterOf(value);
+  DRegister value_odd = OddDRegisterOf(value);
+
+  __ TryAllocate(compiler->float64x2_class(),
+                 slow_path->entry_label(),
+                 out_reg,
+                 locs()->temp(0).reg());
+  __ Bind(slow_path->exit_label());
+
+  __ StoreDToOffset(value_even, out_reg,
+      Float64x2::value_offset() - kHeapObjectTag);
+  __ StoreDToOffset(value_odd, out_reg,
+      Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag);
+}
+
+
+LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  if (kNumTemps > 0) {
+    ASSERT(kNumTemps == 1);
+    summary->set_temp(0, Location::RequiresRegister());
+  }
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
+}
+
+
+void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const Register value = locs()->in(0).reg();
+  const QRegister result = locs()->out().fpu_reg();
+
+  if (value_cid != kFloat64x2Cid) {
+    const Register temp = locs()->temp(0).reg();
+    Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
+    __ tst(value, ShifterOperand(kSmiTagMask));
+    __ b(deopt, EQ);
+    __ CompareClassId(value, kFloat64x2Cid, temp);
+    __ b(deopt, NE);
+  }
+
+  const DRegister result_even = EvenDRegisterOf(result);
+  const DRegister result_odd = OddDRegisterOf(result);
+  // TODO(zra): Maybe use vldmd here.
+  __ LoadDFromOffset(result_even, value,
+      Float64x2::value_offset() - kHeapObjectTag);
+  __ LoadDFromOffset(result_odd, value,
+      Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag);
 }
 
 
@@ -3141,7 +3212,7 @@
   __ StoreDToOffset(value_even, out_reg,
       Int32x4::value_offset() - kHeapObjectTag);
   __ StoreDToOffset(value_odd, out_reg,
-      Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+      Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
 }
 
 
@@ -3177,10 +3248,11 @@
 
   const DRegister result_even = EvenDRegisterOf(result);
   const DRegister result_odd = OddDRegisterOf(result);
+  // TODO(zra): Maybe use vldmd here.
   __ LoadDFromOffset(result_even, value,
       Int32x4::value_offset() - kHeapObjectTag);
   __ LoadDFromOffset(result_odd, value,
-      Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
+      Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
 }
 
 
@@ -4270,35 +4342,51 @@
 
 
 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* result =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  // Low (<= Q7) Q registers are needed for the conversion instructions.
   result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::FpuRegisterLocation(Q7));
+  return result;
+}
+
+
+void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
+  SRegister result = EvenSRegisterOf(EvenDRegisterOf(locs()->out().fpu_reg()));
+  __ vcvtsd(result, value);
+}
+
+
+LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  // Low (<= Q7) Q registers are needed for the conversion instructions.
+  result->set_in(0, Location::FpuRegisterLocation(Q7));
   result->set_out(Location::RequiresFpuRegister());
   return result;
 }
 
 
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // QRegister value = locs()->in(0).fpu_reg();
-  // QRegister result = locs()->out().fpu_reg();
-  switch (recognized_kind()) {
-    case MethodRecognizer::kDoubleTruncate:
-      UNIMPLEMENTED();
-      // __ roundsd(result, value,  Assembler::kRoundToZero);
-      break;
-    case MethodRecognizer::kDoubleFloor:
-      UNIMPLEMENTED();
-      // __ roundsd(result, value,  Assembler::kRoundDown);
-      break;
-    case MethodRecognizer::kDoubleCeil:
-      UNIMPLEMENTED();
-      // __ roundsd(result, value,  Assembler::kRoundUp);
-      break;
-    default:
-      UNREACHABLE();
-  }
+void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SRegister value = EvenSRegisterOf(EvenDRegisterOf(locs()->in(0).fpu_reg()));
+  DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
+  __ vcvtds(result, value);
 }
 
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index be9f97f..f81ca75 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -834,6 +834,8 @@
       return CompileType::FromCid(kFloat32x4Cid);
     case kTypedDataInt32x4ArrayCid:
       return CompileType::FromCid(kInt32x4Cid);
+    case kTypedDataFloat64x2ArrayCid:
+      return CompileType::FromCid(kFloat64x2Cid);
 
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
@@ -887,6 +889,8 @@
       return kUnboxedFloat32x4;
     case kTypedDataInt32x4ArrayCid:
       return kUnboxedInt32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNIMPLEMENTED();
       return kTagged;
@@ -912,7 +916,8 @@
   }
   if ((representation() == kUnboxedDouble) ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
+      (representation() == kUnboxedInt32x4) ||
+      (representation() == kUnboxedFloat64x2)) {
     locs->set_out(Location::RequiresFpuRegister());
   } else {
     locs->set_out(Location::RequiresRegister());
@@ -945,7 +950,8 @@
   if ((representation() == kUnboxedDouble) ||
       (representation() == kUnboxedMint) ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
+      (representation() == kUnboxedInt32x4) ||
+      (representation() == kUnboxedFloat64x2)) {
     XmmRegister result = locs()->out().fpu_reg();
     if ((index_scale() == 1) && index.IsRegister()) {
       __ SmiUntag(index.reg());
@@ -960,15 +966,14 @@
         __ movss(result, element_address);
         break;
       case kTypedDataFloat32ArrayCid:
-        // Load single precision float and promote to double.
         __ movss(result, element_address);
-        __ cvtss2sd(result, locs()->out().fpu_reg());
         break;
       case kTypedDataFloat64ArrayCid:
         __ movsd(result, element_address);
         break;
       case kTypedDataInt32x4ArrayCid:
       case kTypedDataFloat32x4ArrayCid:
+      case kTypedDataFloat64x2ArrayCid:
         __ movups(result, element_address);
         break;
     }
@@ -1056,6 +1061,8 @@
       return kUnboxedFloat32x4;
     case kTypedDataInt32x4ArrayCid:
       return kUnboxedInt32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNIMPLEMENTED();
       return kTagged;
@@ -1109,15 +1116,13 @@
                       : Location::RequiresFpuRegister());
       break;
     case kTypedDataFloat32ArrayCid:
-      // Need temp register for float-to-double conversion.
-      locs->AddTemp(Location::RequiresFpuRegister());
-      // Fall through.
     case kTypedDataFloat64ArrayCid:
       // TODO(srdjan): Support Float64 constants.
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
     case kTypedDataInt32x4ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid:
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
     default:
@@ -1229,16 +1234,14 @@
       }
       break;
     case kTypedDataFloat32ArrayCid:
-      // Convert to single precision.
-      __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
-      // Store.
-      __ movss(element_address, locs()->temp(0).fpu_reg());
+      __ movss(element_address, locs()->in(2).fpu_reg());
       break;
     case kTypedDataFloat64ArrayCid:
       __ movsd(element_address, locs()->in(2).fpu_reg());
       break;
     case kTypedDataInt32x4ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid:
       __ movups(element_address, locs()->in(2).fpu_reg());
       break;
     default:
@@ -1995,6 +1998,37 @@
 };
 
 
+class BoxFloat64x2SlowPath : public SlowPathCode {
+ public:
+  explicit BoxFloat64x2SlowPath(Instruction* instruction)
+      : instruction_(instruction) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    __ Comment("BoxFloat64x2SlowPath");
+    __ Bind(entry_label());
+    const Class& float64x2_class = compiler->float64x2_class();
+    const Code& stub =
+        Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
+    const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
+
+    LocationSummary* locs = instruction_->locs();
+    locs->live_registers()->Remove(locs->out());
+
+    compiler->SaveLiveRegisters(locs);
+    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+                           &label,
+                           PcDescriptors::kOther,
+                           locs);
+    __ MoveRegister(locs->out().reg(), EAX);
+    compiler->RestoreLiveRegisters(locs);
+
+    __ jmp(exit_label());
+  }
+
+ private:
+  Instruction* instruction_;
+};
+
 
 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -2163,6 +2197,8 @@
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
+  ASSERT(instantiator_reg == EAX);
+  ASSERT(instantiator_reg == result_reg);
 
   // 'instantiator_reg' is the instantiator TypeArguments object (or null).
   ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
@@ -2179,6 +2215,28 @@
     __ cmpl(instantiator_reg, raw_null);
     __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
   }
+  // Lookup cache before calling runtime.
+  // TODO(fschneider): Consider moving this into a shared stub to reduce
+  // generated code size.
+  __ LoadObject(EDI, type_arguments());
+  __ movl(EDI, FieldAddress(EDI, TypeArguments::instantiations_offset()));
+  __ leal(EDI, FieldAddress(EDI, Array::data_offset()));
+  // The instantiations cache is initialized with Object::zero_array() and is
+  // therefore guaranteed to contain kNoInstantiator. No length check needed.
+  Label loop, found, slow_case;
+  __ Bind(&loop);
+  __ movl(EDX, Address(EDI, 0 * kWordSize));  // Cached instantiator.
+  __ cmpl(EDX, EAX);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+  __ addl(EDI, Immediate(2 * kWordSize));
+  __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+  __ jmp(&slow_case, Assembler::kNearJump);
+  __ Bind(&found);
+  __ movl(EAX, Address(EDI, 1 * kWordSize));  // Cached instantiated args.
+  __ jmp(&type_arguments_instantiated, Assembler::kNearJump);
+
+  __ Bind(&slow_case);
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
@@ -2192,90 +2250,6 @@
   __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
   __ popl(result_reg);  // Pop instantiated type arguments.
   __ Bind(&type_arguments_instantiated);
-  ASSERT(instantiator_reg == result_reg);
-}
-
-
-LocationSummary*
-ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  Register result_reg = locs()->out().reg();
-  ASSERT(instantiator_reg == result_reg);
-
-  // instantiator_reg is the instantiator type argument vector,
-  // i.e. a TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-          instantiator_class()));
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  Label type_arguments_instantiated;
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ cmpl(instantiator_reg, raw_null);
-  __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
-  // Instantiate non-null type arguments.
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments());
-  // result_reg: uninstantiated type arguments.
-
-  __ Bind(&type_arguments_instantiated);
-  // result_reg: uninstantiated or instantiated type arguments.
-}
-
-
-LocationSummary*
-ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorInstantiatorInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  ASSERT(locs()->out().reg() == instantiator_reg);
-
-  // instantiator_reg is the instantiator TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  Label instantiator_not_null;
-  __ cmpl(instantiator_reg, raw_null);
-  __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
-  // Null was used in VisitExtractConstructorTypeArguments as the
-  // instantiated type arguments, no proper instantiator needed.
-  __ movl(instantiator_reg,
-          Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-  __ Bind(&instantiator_not_null);
-  // instantiator_reg: instantiator or kNoInstantiator.
 }
 
 
@@ -3102,6 +3076,69 @@
 }
 
 
+LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs,
+                          kNumTemps,
+                          LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
+  compiler->AddSlowPathCode(slow_path);
+
+  Register out_reg = locs()->out().reg();
+  XmmRegister value = locs()->in(0).fpu_reg();
+
+  __ TryAllocate(compiler->float64x2_class(),
+                 slow_path->entry_label(),
+                 Assembler::kFarJump,
+                 out_reg,
+                 kNoRegister);
+  __ Bind(slow_path->exit_label());
+  __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
+}
+
+
+LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  if (kNumTemps > 0) {
+    ASSERT(kNumTemps == 1);
+    summary->set_temp(0, Location::RequiresRegister());
+  }
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
+}
+
+
+void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const Register value = locs()->in(0).reg();
+  const XmmRegister result = locs()->out().fpu_reg();
+
+  if (value_cid != kFloat64x2Cid) {
+    const Register temp = locs()->temp(0).reg();
+    Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
+    __ testl(value, Immediate(kSmiTagMask));
+    __ j(ZERO, deopt);
+    __ CompareClassId(value, kFloat64x2Cid, temp);
+    __ j(NOT_EQUAL, deopt);
+  }
+  __ movups(result, FieldAddress(value, Float64x2::value_offset()));
+}
+
+
 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -4226,6 +4263,38 @@
 }
 
 
+LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ cvtsd2ss(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
+}
+
+
+LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ cvtss2sd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
+}
+
+
 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
   ASSERT((InputCount() == 1) || (InputCount() == 2));
   const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index df916f9..ffae96d 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1043,9 +1043,8 @@
         UNIMPLEMENTED();
         break;
       case kTypedDataFloat32ArrayCid:
-        // Load single precision float and promote to double.
-        __ lwc1(STMP1, element_address);
-        __ cvtds(result, STMP1);
+        // Load single precision float.
+        __ lwc1(EvenFRegisterOf(result), element_address);
         break;
       case kTypedDataFloat64ArrayCid:
         __ LoadDFromOffset(result, index.reg(),
@@ -1308,12 +1307,11 @@
       }
       break;
     }
-    case kTypedDataFloat32ArrayCid:
-      // Convert to single precision.
-      __ cvtsd(STMP1, locs()->in(2).fpu_reg());
-      // Store.
-      __ swc1(STMP1, element_address);
+    case kTypedDataFloat32ArrayCid: {
+      FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg());
+      __ swc1(value, element_address);
       break;
+    }
     case kTypedDataFloat64ArrayCid:
       __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(),
           FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
@@ -2139,6 +2137,8 @@
   __ TraceSimMsg("InstantiateTypeArgumentsInstr");
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
+  ASSERT(instantiator_reg == T0);
+  ASSERT(instantiator_reg == result_reg);
 
   // 'instantiator_reg' is the instantiator TypeArguments object (or null).
   ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
@@ -2153,6 +2153,24 @@
     __ BranchEqual(instantiator_reg, reinterpret_cast<int32_t>(Object::null()),
                    &type_arguments_instantiated);
   }
+
+  __ LoadObject(T2, type_arguments());
+  __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset()));
+  __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag);
+  // The instantiations cache is initialized with Object::zero_array() and is
+  // therefore guaranteed to contain kNoInstantiator. No length check needed.
+  Label loop, found, slow_case;
+  __ Bind(&loop);
+  __ lw(T1, Address(T2, 0 * kWordSize));  // Cached instantiator.
+  __ beq(T1, T0, &found);
+  __ BranchNotEqual(T1, Smi::RawValue(StubCode::kNoInstantiator), &loop);
+  __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize));
+  __ b(&slow_case);
+  __ Bind(&found);
+  __ lw(T0, Address(T2, 1 * kWordSize));  // Cached instantiated args.
+  __ b(&type_arguments_instantiated);
+
+  __ Bind(&slow_case);
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
   __ addiu(SP, SP, Immediate(-3 * kWordSize));
@@ -2173,86 +2191,6 @@
   // Drop instantiator and uninstantiated type arguments.
   __ addiu(SP, SP, Immediate(3 * kWordSize));
   __ Bind(&type_arguments_instantiated);
-  ASSERT(instantiator_reg == result_reg);
-}
-
-
-LocationSummary*
-ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  Register result_reg = locs()->out().reg();
-  ASSERT(instantiator_reg == result_reg);
-
-  // instantiator_reg is the instantiator type argument vector,
-  // i.e. a TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  __ BranchEqual(instantiator_reg, reinterpret_cast<int32_t>(Object::null()),
-                 &type_arguments_instantiated);
-  // Instantiate non-null type arguments.
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments());
-  // result_reg: uninstantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
-
-  // result_reg: uninstantiated or instantiated type arguments.
-}
-
-
-LocationSummary*
-ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorInstantiatorInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  ASSERT(locs()->out().reg() == instantiator_reg);
-
-  // instantiator_reg is the instantiator TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-  Label instantiator_not_null;
-  __ BranchNotEqual(instantiator_reg, reinterpret_cast<int32_t>(Object::null()),
-                    &instantiator_not_null);
-  // Null was used in VisitExtractConstructorTypeArguments as the
-  // instantiated type arguments, no proper instantiator needed.
-  __ LoadImmediate(instantiator_reg,
-                   Smi::RawValue(StubCode::kNoInstantiator));
-  __ Bind(&instantiator_not_null);
-  // instantiator_reg: instantiator or kNoInstantiator.
 }
 
 
@@ -3019,6 +2957,28 @@
 }
 
 
+LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
   UNIMPLEMENTED();
   return NULL;
@@ -3584,8 +3544,44 @@
 }
 
 
+LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  DRegister value = locs()->in(0).fpu_reg();
+  FRegister result = EvenFRegisterOf(locs()->out().fpu_reg());
+  __ cvtsd(result, value);
+}
+
+
+LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  FRegister value = EvenFRegisterOf(locs()->in(0).fpu_reg());
+  DRegister result = locs()->out().fpu_reg();
+  __ cvtds(result, value);
+}
+
+
 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
-  // Calling convetion on MIPS uses D6 and D7 to pass the first two
+  // Calling convention on MIPS uses D6 and D7 to pass the first two
   // double arguments.
   ASSERT((InputCount() == 1) || (InputCount() == 2));
   const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index ecb7ec4..f1598c7 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -769,6 +769,8 @@
       return CompileType::FromCid(kFloat32x4Cid);
     case kTypedDataInt32x4ArrayCid:
       return CompileType::FromCid(kInt32x4Cid);
+    case kTypedDataFloat64x2ArrayCid:
+      return CompileType::FromCid(kFloat64x2Cid);
 
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
@@ -813,6 +815,8 @@
       return kUnboxedInt32x4;
     case kTypedDataFloat32x4ArrayCid:
       return kUnboxedFloat32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNIMPLEMENTED();
       return kTagged;
@@ -839,9 +843,10 @@
                           index()->definition()->AsConstant()->value())
                       : Location::RequiresRegister());
   }
-  if ((representation() == kUnboxedDouble) ||
+  if ((representation() == kUnboxedDouble)    ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
+      (representation() == kUnboxedInt32x4)   ||
+      (representation() == kUnboxedFloat64x2)) {
     locs->set_out(Location::RequiresFpuRegister());
   } else {
     locs->set_out(Location::RequiresRegister());
@@ -874,9 +879,10 @@
             Smi::Cast(index.constant()).Value());
   }
 
-  if ((representation() == kUnboxedDouble) ||
+  if ((representation() == kUnboxedDouble)    ||
       (representation() == kUnboxedFloat32x4) ||
-      (representation() == kUnboxedInt32x4)) {
+      (representation() == kUnboxedInt32x4)   ||
+      (representation() == kUnboxedFloat64x2)) {
     if ((index_scale() == 1) && index.IsRegister()) {
       __ SmiUntag(index.reg());
     }
@@ -885,13 +891,12 @@
     if (class_id() == kTypedDataFloat32ArrayCid) {
       // Load single precision float.
       __ movss(result, element_address);
-      // Promote to double.
-      __ cvtss2sd(result, locs()->out().fpu_reg());
     } else if (class_id() == kTypedDataFloat64ArrayCid) {
       __ movsd(result, element_address);
     } else {
-      ASSERT((class_id() == kTypedDataInt32x4ArrayCid) ||
-             (class_id() == kTypedDataFloat32x4ArrayCid));
+      ASSERT((class_id() == kTypedDataInt32x4ArrayCid)   ||
+             (class_id() == kTypedDataFloat32x4ArrayCid) ||
+             (class_id() == kTypedDataFloat64x2ArrayCid));
       __ movups(result, element_address);
     }
     return;
@@ -964,6 +969,8 @@
       return kUnboxedFloat32x4;
     case kTypedDataInt32x4ArrayCid:
       return kUnboxedInt32x4;
+    case kTypedDataFloat64x2ArrayCid:
+      return kUnboxedFloat64x2;
     default:
       UNIMPLEMENTED();
       return kTagged;
@@ -1014,14 +1021,12 @@
       locs->set_in(2, Location::WritableRegister());
       break;
     case kTypedDataFloat32ArrayCid:
-      // Need temp register for float-to-double conversion.
-      locs->AddTemp(Location::RequiresFpuRegister());
-      // Fall through.
     case kTypedDataFloat64ArrayCid:
       // TODO(srdjan): Support Float64 constants.
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
     case kTypedDataInt32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
@@ -1131,15 +1136,13 @@
         break;
     }
     case kTypedDataFloat32ArrayCid:
-      // Convert to single precision.
-      __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
-      // Store.
-      __ movss(element_address, locs()->temp(0).fpu_reg());
+      __ movss(element_address, locs()->in(2).fpu_reg());
       break;
     case kTypedDataFloat64ArrayCid:
       __ movsd(element_address, locs()->in(2).fpu_reg());
       break;
     case kTypedDataInt32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
       __ movups(element_address, locs()->in(2).fpu_reg());
       break;
@@ -1887,6 +1890,38 @@
 };
 
 
+class BoxFloat64x2SlowPath : public SlowPathCode {
+ public:
+  explicit BoxFloat64x2SlowPath(Instruction* instruction)
+      : instruction_(instruction) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    __ Comment("BoxFloat64x2SlowPath");
+    __ Bind(entry_label());
+    const Class& float64x2_class = compiler->float64x2_class();
+    const Code& stub =
+        Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
+    const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
+
+    LocationSummary* locs = instruction_->locs();
+    locs->live_registers()->Remove(locs->out());
+
+    compiler->SaveLiveRegisters(locs);
+    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+                           &label,
+                           PcDescriptors::kOther,
+                           locs);
+    __ MoveRegister(locs->out().reg(), RAX);
+    compiler->RestoreLiveRegisters(locs);
+
+    __ jmp(exit_label());
+  }
+
+ private:
+  Instruction* instruction_;
+};
+
+
 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -2051,6 +2086,8 @@
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
+  ASSERT(instantiator_reg == RAX);
+  ASSERT(instantiator_reg == result_reg);
 
   // 'instantiator_reg' is the instantiator TypeArguments object (or null).
   ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
@@ -2065,6 +2102,29 @@
     __ CompareObject(instantiator_reg, Object::null_object(), PP);
     __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
   }
+
+  // Lookup cache before calling runtime.
+  // TODO(fschneider): Consider moving this into a shared stub to reduce
+  // generated code size.
+  __ LoadObject(RDI, type_arguments(), PP);
+  __ movq(RDI, FieldAddress(RDI, TypeArguments::instantiations_offset()));
+  __ leaq(RDI, FieldAddress(RDI, Array::data_offset()));
+  // The instantiations cache is initialized with Object::zero_array() and is
+  // therefore guaranteed to contain kNoInstantiator. No length check needed.
+  Label loop, found, slow_case;
+  __ Bind(&loop);
+  __ movq(RDX, Address(RDI, 0 * kWordSize));  // Cached instantiator.
+  __ cmpq(RDX, RAX);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+  __ addq(RDI, Immediate(2 * kWordSize));
+  __ cmpq(RDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+  __ jmp(&slow_case, Assembler::kNearJump);
+  __ Bind(&found);
+  __ movq(RAX, Address(RDI, 1 * kWordSize));  // Cached instantiated args.
+  __ jmp(&type_arguments_instantiated, Assembler::kNearJump);
+
+  __ Bind(&slow_case);
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
   __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
@@ -2082,87 +2142,6 @@
 }
 
 
-LocationSummary*
-ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  Register result_reg = locs()->out().reg();
-  ASSERT(instantiator_reg == result_reg);
-
-  // instantiator_reg is the instantiator type argument vector,
-  // i.e. a TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-
-  __ CompareObject(instantiator_reg, Object::null_object(), PP);
-  __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
-  // Instantiate non-null type arguments.
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments(), PP);
-  // result_reg: uninstantiated type arguments.
-
-  __ Bind(&type_arguments_instantiated);
-  // result_reg: uninstantiated or instantiated type arguments.
-}
-
-
-LocationSummary*
-ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void ExtractConstructorInstantiatorInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  Register instantiator_reg = locs()->in(0).reg();
-  ASSERT(locs()->out().reg() == instantiator_reg);
-
-  // instantiator_reg is the instantiator TypeArguments object (or null).
-  ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
-         !type_arguments().CanShareInstantiatorTypeArguments(
-             instantiator_class()));
-
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
-
-  Label instantiator_not_null;
-  __ CompareObject(instantiator_reg, Object::null_object(), PP);
-  __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
-  // Null was used in VisitExtractConstructorTypeArguments as the
-  // instantiated type arguments, no proper instantiator needed.
-  __ LoadImmediate(instantiator_reg,
-          Immediate(Smi::RawValue(StubCode::kNoInstantiator)), PP);
-  __ Bind(&instantiator_not_null);
-  // instantiator_reg: instantiator or kNoInstantiator.
-}
-
-
 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 0;
   const intptr_t kNumTemps = 1;
@@ -3087,6 +3066,64 @@
 }
 
 
+LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs,
+                          kNumTemps,
+                          LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
+  compiler->AddSlowPathCode(slow_path);
+
+  Register out_reg = locs()->out().reg();
+  XmmRegister value = locs()->in(0).fpu_reg();
+
+  __ TryAllocate(compiler->float64x2_class(),
+                 slow_path->entry_label(),
+                 Assembler::kFarJump,
+                 out_reg,
+                 kNoRegister);
+  __ Bind(slow_path->exit_label());
+  __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
+}
+
+
+LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
+}
+
+
+void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const Register value = locs()->in(0).reg();
+  const XmmRegister result = locs()->out().fpu_reg();
+
+  if (value_cid != kFloat64x2Cid) {
+    Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
+    __ testq(value, Immediate(kSmiTagMask));
+    __ j(ZERO, deopt);
+    __ CompareClassId(value, kFloat64x2Cid);
+    __ j(NOT_EQUAL, deopt);
+  }
+  __ movups(result, FieldAddress(value, Float64x2::value_offset()));
+}
+
+
 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -4245,6 +4282,38 @@
 }
 
 
+LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ cvtsd2ss(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
+}
+
+
+LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::SameAsFirstInput());
+  return result;
+}
+
+
+void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ cvtss2sd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
+}
+
+
 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
   // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
   // double arguments and XMM0 to return the result. Unfortunately
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index bb493ab..2d578a6 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -479,15 +479,15 @@
 }
 
 
-bool Isolate::GetStackBounds(uintptr_t* lower, uintptr_t* upper) {
-  uintptr_t stack_lower = stack_limit();
-  if (stack_lower == static_cast<uintptr_t>(~0)) {
+bool Isolate::GetStackBounds(uword* lower, uword* upper) {
+  uword stack_lower = stack_limit();
+  if (stack_lower == kUwordMax) {
     stack_lower = saved_stack_limit();
   }
-  if (stack_lower == static_cast<uintptr_t>(~0)) {
+  if (stack_lower == kUwordMax) {
     return false;
   }
-  uintptr_t stack_upper = stack_lower + GetSpecifiedStackSize();
+  uword stack_upper = stack_lower + GetSpecifiedStackSize();
   *lower = stack_lower;
   *upper = stack_upper;
   return true;
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7d31166..e0ce7cb 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -224,7 +224,7 @@
   uword saved_stack_limit() const { return saved_stack_limit_; }
 
   // Retrieve the stack address bounds.
-  bool GetStackBounds(uintptr_t* lower, uintptr_t* upper);
+  bool GetStackBounds(uword* lower, uword* upper);
 
   static uword GetSpecifiedStackSize();
 
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 8dd4a01..1c60d5b 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -3,17 +3,23 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "platform/assert.h"
-#include "vm/object.h"
+
+#include "vm/dart_entry.h"
 #include "vm/debugger.h"
 #include "vm/json_stream.h"
+#include "vm/message.h"
+#include "vm/object.h"
 
 
 namespace dart {
 
+DECLARE_FLAG(bool, trace_service);
+
 JSONStream::JSONStream(intptr_t buf_size)
     : open_objects_(0),
       buffer_(buf_size),
       reply_port_(ILLEGAL_PORT),
+      command_(""),
       arguments_(NULL),
       num_arguments_(0),
       option_keys_(NULL),
@@ -26,6 +32,94 @@
 }
 
 
+void JSONStream::Setup(Zone* zone,
+                       const Instance& reply_port,
+                       const GrowableObjectArray& path,
+                       const GrowableObjectArray& option_keys,
+                       const GrowableObjectArray& option_values) {
+  // Setup the reply port.
+  const Object& id_obj = Object::Handle(
+      DartLibraryCalls::PortGetId(reply_port));
+  if (id_obj.IsError()) {
+    Exceptions::PropagateError(Error::Cast(id_obj));
+  }
+  const Integer& id = Integer::Cast(id_obj);
+  Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
+  ASSERT(port != ILLEGAL_PORT);
+  set_reply_port(port);
+
+  // Setup JSONStream arguments and options. The arguments and options
+  // are zone allocated and will be freed immediately after handling the
+  // message.
+  const char** arguments = zone->Alloc<const char*>(path.Length());
+  String& string_iterator = String::Handle();
+  for (intptr_t i = 0; i < path.Length(); i++) {
+    string_iterator ^= path.At(i);
+    arguments[i] = zone->MakeCopyOfString(string_iterator.ToCString());
+    if (i == 0) {
+      command_ = arguments[i];
+    }
+  }
+  SetArguments(arguments, path.Length());
+  if (option_keys.Length() > 0) {
+    const char** option_keys_native =
+        zone->Alloc<const char*>(option_keys.Length());
+    const char** option_values_native =
+        zone->Alloc<const char*>(option_keys.Length());
+    for (intptr_t i = 0; i < option_keys.Length(); i++) {
+      string_iterator ^= option_keys.At(i);
+      option_keys_native[i] =
+          zone->MakeCopyOfString(string_iterator.ToCString());
+      string_iterator ^= option_values.At(i);
+      option_values_native[i] =
+          zone->MakeCopyOfString(string_iterator.ToCString());
+    }
+    SetOptions(option_keys_native, option_values_native, option_keys.Length());
+  }
+  if (FLAG_trace_service) {
+    Isolate* isolate = Isolate::Current();
+    ASSERT(isolate != NULL);
+    const char* isolate_name = isolate->name();
+    OS::Print("Isolate %s processing service request /%s\n",
+              isolate_name, command_);
+    setup_time_micros_ = OS::GetCurrentTimeMicros();
+  }
+}
+
+
+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);
+}
+
+
+void JSONStream::PostReply() {
+  Dart_Port port = reply_port();
+  ASSERT(port != ILLEGAL_PORT);
+  set_reply_port(ILLEGAL_PORT);  // Prevent double replies.
+  int64_t process_delta_micros = 0;
+  if (FLAG_trace_service) {
+    process_delta_micros = OS::GetCurrentTimeMicros() - setup_time_micros_;
+  }
+  const String& reply = String::Handle(String::New(ToCString()));
+  ASSERT(!reply.IsNull());
+
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  writer.WriteMessage(reply);
+  PortMap::PostMessage(new Message(port, data,
+                                   writer.BytesWritten(),
+                                   Message::kNormalPriority));
+  if (FLAG_trace_service) {
+    Isolate* isolate = Isolate::Current();
+    ASSERT(isolate != NULL);
+    const char* isolate_name = isolate->name();
+    OS::Print("Isolate %s processed service request /%s in %" Pd64" us.\n",
+              isolate_name, command_, process_delta_micros);
+  }
+}
+
+
 const char* JSONStream::LookupOption(const char* key) const {
   for (int i = 0; i < num_options(); i++) {
     if (!strcmp(key, option_keys_[i])) {
@@ -127,14 +221,6 @@
 }
 
 
-void JSONStream::PrintValue(const Field& field,
-                            const Instance& instance,
-                            bool ref) {
-  PrintCommaIfNeeded();
-  field.PrintToJSONStreamWithInstance(this, instance, ref);
-}
-
-
 void JSONStream::PrintValue(SourceBreakpoint* bpt) {
   PrintCommaIfNeeded();
   bpt->PrintToJSONStream(this);
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 8966b04..ba09e5d 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -12,17 +12,26 @@
 namespace dart {
 
 class Field;
+class GrowableObjectArray;
 class Instance;
 class JSONArray;
 class JSONObject;
 class Object;
 class SourceBreakpoint;
+class Zone;
 
 class JSONStream : ValueObject {
  public:
   explicit JSONStream(intptr_t buf_size = 256);
   ~JSONStream();
 
+  void Setup(Zone* zone,
+             const Instance& reply_port,
+             const GrowableObjectArray& path,
+             const GrowableObjectArray& option_keys,
+             const GrowableObjectArray& option_values);
+  void PostReply();
+
   TextBuffer* buffer() { return &buffer_; }
   const char* ToCString() { return buffer_.buf(); }
 
@@ -47,6 +56,11 @@
 
   const char* LookupOption(const char* key) const;
 
+  const char* command() const { return command_; }
+  const char** arguments() const { return arguments_; }
+  const char** option_keys() const { return option_keys_; }
+  const char** option_values() const { return option_values_; }
+
  private:
   void Clear();
 
@@ -62,7 +76,6 @@
   void PrintValue(const char* s);
   void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   void PrintValue(const Object& o, bool ref = true);
-  void PrintValue(const Field& f, const Instance& instance, bool ref = true);
   void PrintValue(SourceBreakpoint* bpt);
 
   void PrintPropertyBool(const char* name, bool b);
@@ -82,11 +95,13 @@
   intptr_t open_objects_;
   TextBuffer buffer_;
   Dart_Port reply_port_;
+  const char* command_;
   const char** arguments_;
   intptr_t num_arguments_;
   const char** option_keys_;
   const char** option_values_;
   intptr_t num_options_;
+  int64_t setup_time_micros_;
 
   friend class JSONObject;
   friend class JSONArray;
@@ -157,12 +172,6 @@
   void AddValue(const Object& obj, bool ref = true) const {
     stream_->PrintValue(obj, ref);
   }
-  // Print a field bound to a value.  Value is looked up from 'instance'.
-  void AddValue(const Field& field,
-                const Instance& instance,
-                bool ref = true) const {
-    stream_->PrintValue(field, instance, ref);
-  }
   void AddValue(SourceBreakpoint* bpt) const {
     stream_->PrintValue(bpt);
   }
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index 6d93f71..89e6702 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -23,6 +23,7 @@
   kUnboxedMint,
   kUnboxedFloat32x4,
   kUnboxedInt32x4,
+  kUnboxedFloat64x2,
   kNumRepresentations
 };
 
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index f25e723..1451856 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -135,10 +135,10 @@
     return AutoSetupScopeBits::mask_in_place();
   }
 
-  static int ParameterCountForResolution(const Function& function) {
+  static intptr_t ParameterCountForResolution(const Function& function) {
     ASSERT(function.is_native());
     ASSERT(!function.IsConstructor());  // Not supported.
-    int count = function.NumParameters();
+    intptr_t count = function.NumParameters();
     if (function.is_static() && function.IsClosureFunction()) {
       // The closure object is hidden and not accessible from native code.
       // However, if the function is an instance closure function, the captured
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8720418..3ea8065 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -93,6 +93,7 @@
 Instance* Object::null_instance_ = NULL;
 TypeArguments* Object::null_type_arguments_ = NULL;
 Array* Object::empty_array_ = NULL;
+Array* Object::zero_array_ = NULL;
 PcDescriptors* Object::empty_descriptors_ = NULL;
 Instance* Object::sentinel_ = NULL;
 Instance* Object::transition_sentinel_ = NULL;
@@ -449,6 +450,7 @@
   null_instance_ = Instance::ReadOnlyHandle();
   null_type_arguments_ = TypeArguments::ReadOnlyHandle();
   empty_array_ = Array::ReadOnlyHandle();
+  zero_array_ = Array::ReadOnlyHandle();
   empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
   sentinel_ = Instance::ReadOnlyHandle();
   transition_sentinel_ = Instance::ReadOnlyHandle();
@@ -477,9 +479,11 @@
   *null_instance_ = Instance::null();
   *null_type_arguments_ = TypeArguments::null();
 
-  // Initialize the empty array handle to null_ in order to be able to check
-  // if the empty array was allocated (RAW_NULL is not available).
+  // Initialize the empty and zero array handles to null_ in order to be able to
+  // check if the empty and zero arrays were allocated (RAW_NULL is not
+  // available).
   *empty_array_ = Array::null();
+  *zero_array_ = Array::null();
 
   Class& cls = Class::Handle();
 
@@ -657,6 +661,17 @@
     empty_array_->raw_ptr()->length_ = Smi::New(0);
   }
 
+  // Allocate and initialize the zero_array instance.
+  {
+    uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
+    InitializeObject(address, kArrayCid, Array::InstanceSize(1));
+    Array::initializeHandle(
+        zero_array_,
+        reinterpret_cast<RawArray*>(address + kHeapObjectTag));
+    zero_array_->raw_ptr()->length_ = Smi::New(1);
+    zero_array_->raw_ptr()->data()[0] = Smi::New(0);
+  }
+
   // Allocate and initialize the empty_descriptors instance.
   {
     uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
@@ -720,6 +735,8 @@
   ASSERT(null_type_arguments_->IsTypeArguments());
   ASSERT(!empty_array_->IsSmi());
   ASSERT(empty_array_->IsArray());
+  ASSERT(!zero_array_->IsSmi());
+  ASSERT(zero_array_->IsArray());
   ASSERT(!sentinel_->IsSmi());
   ASSERT(sentinel_->IsInstance());
   ASSERT(!transition_sentinel_->IsSmi());
@@ -2029,7 +2046,6 @@
   }
   ASSERT(!IsMixinApplication() || is_mixin_type_applied());
   const AbstractType& sup_type = AbstractType::Handle(isolate, super_type());
-  ASSERT(sup_type.IsResolved());
   const TypeArguments& sup_type_args =
       TypeArguments::Handle(isolate, sup_type.arguments());
   if (sup_type_args.IsNull()) {
@@ -2045,6 +2061,8 @@
   // finalized, but the last num_sup_type_args type arguments will not be
   // modified by finalization, only shifted to higher indices in the vector.
   // They may however get wrapped in a BoundedType, which we skip.
+  // The super type may not even be resolved yet. This is not necessary, since
+  // we only check for matching type parameters, which are resolved by default.
   const TypeArguments& type_params =
       TypeArguments::Handle(isolate, type_parameters());
   // Determine the maximum overlap of a prefix of the vector consisting of the
@@ -3115,6 +3133,12 @@
 }
 
 
+void Class::set_is_cycle_free() const {
+  ASSERT(!is_cycle_free());
+  set_state_bits(CycleFreeBit::update(true, raw_ptr()->state_bits_));
+}
+
+
 void Class::set_is_finalized() const {
   ASSERT(!is_finalized());
   set_state_bits(ClassFinalizedBits::update(RawClass::kFinalized,
@@ -3140,7 +3164,6 @@
 
 
 void Class::set_interfaces(const Array& value) const {
-  // Verification and resolving of interfaces occurs in finalizer.
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->interfaces_, value.raw());
 }
@@ -4214,9 +4237,11 @@
   // Lookup instantiator and, if found, return paired instantiated result.
   Array& prior_instantiations = Array::Handle(instantiations());
   ASSERT(!prior_instantiations.IsNull() && prior_instantiations.IsArray());
-  intptr_t length = prior_instantiations.Length();
+  // The instantiations cache is initialized with Object::zero_array() and is
+  // therefore guaranteed to contain kNoInstantiator. No length check needed.
+  ASSERT(prior_instantiations.Length() > 0);
   intptr_t index = 0;
-  while (index < length) {
+  while (true) {
     if (prior_instantiations.At(index) == instantiator_type_arguments.raw()) {
       return TypeArguments::RawCast(prior_instantiations.At(index + 1));
     }
@@ -4234,19 +4259,22 @@
   // Instantiation did not result in bound error. Canonicalize type arguments.
   result = result.Canonicalize();
   // Add instantiator and result to instantiations array.
-  if ((index + 2) > length) {
+  intptr_t length = prior_instantiations.Length();
+  if ((index + 2) >= length) {
     // Grow the instantiations array.
-    length = (length == 0) ? 2 : length + 4;
+    // The initial array is Object::zero_array() of length 1.
+    length = (length > 64) ?
+        (length + 64) :
+        ((length == 1) ? 3 : ((length - 1) * 2 + 1));
     prior_instantiations =
         Array::Grow(prior_instantiations, length, Heap::kOld);
     set_instantiations(prior_instantiations);
+    ASSERT((index + 2) < length);
   }
   prior_instantiations.SetAt(index, instantiator_type_arguments);
   prior_instantiations.SetAt(index + 1, result);
-  if ((index + 2) < length) {
-    prior_instantiations.SetAt(index + 2,
-        Smi::Handle(Smi::New(StubCode::kNoInstantiator)));
-  }
+  prior_instantiations.SetAt(index + 2,
+                             Smi::Handle(Smi::New(StubCode::kNoInstantiator)));
   return result.raw();
 }
 
@@ -4266,7 +4294,10 @@
     // Length must be set before we start storing into the array.
     result.SetLength(len);
   }
-  result.set_instantiations(Object::empty_array());
+  // The zero array should have been initialized.
+  ASSERT(Object::zero_array().raw() != Array::null());
+  COMPILE_ASSERT(StubCode::kNoInstantiator == 0, kNoInstantiator_must_be_zero);
+  result.set_instantiations(Object::zero_array());
   return result.raw();
 }
 
@@ -4362,6 +4393,7 @@
   if (IsNull() || IsFinalized()) {
     return raw();
   }
+  ASSERT(IsResolved());
   AbstractType& type = AbstractType::Handle();
   const intptr_t num_types = Length();
   const TypeArguments& clone = TypeArguments::Handle(
@@ -4371,6 +4403,7 @@
     type = type.CloneUnfinalized();
     clone.SetTypeAt(i, type);
   }
+  ASSERT(clone.IsResolved());
   return clone.raw();
 }
 
@@ -5100,9 +5133,9 @@
     }
     return false;  // Too many named arguments.
   }
-  const int num_pos_args = num_arguments - num_named_arguments;
-  const int num_opt_pos_params = NumOptionalPositionalParameters();
-  const int num_pos_params = num_fixed_parameters() + num_opt_pos_params;
+  const intptr_t num_pos_args = num_arguments - num_named_arguments;
+  const intptr_t num_opt_pos_params = NumOptionalPositionalParameters();
+  const intptr_t num_pos_params = num_fixed_parameters() + num_opt_pos_params;
   if (num_pos_args > num_pos_params) {
     if (error_message != NULL) {
       const intptr_t kMessageBufferSize = 64;
@@ -5552,9 +5585,9 @@
   ASSERT(!IsConstructor());
   Function& clone = Function::Handle();
   clone ^= Object::Clone(*this, Heap::kOld);
-  const Class& owner = Class::Handle(this->Owner());
+  const Class& origin = Class::Handle(this->origin());
   const PatchClass& clone_owner =
-      PatchClass::Handle(PatchClass::New(new_owner, owner));
+      PatchClass::Handle(PatchClass::New(new_owner, origin));
   clone.set_owner(clone_owner);
   clone.StorePointer(&clone.raw_ptr()->code_, Code::null());
   clone.StorePointer(&clone.raw_ptr()->unoptimized_code_, Code::null());
@@ -6365,13 +6398,6 @@
 }
 
 void Field::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  PrintToJSONStreamWithInstance(stream, Object::null_instance(), ref);
-}
-
-
-void Field::PrintToJSONStreamWithInstance(JSONStream* stream,
-                                          const Instance& instance,
-                                          bool ref) const {
   JSONObject jsobj(stream);
   const char* internal_field_name = String::Handle(name()).ToCString();
   const char* field_name = String::Handle(UserVisibleName()).ToCString();
@@ -6384,10 +6410,7 @@
   jsobj.AddProperty("name", internal_field_name);
   jsobj.AddProperty("user_name", field_name);
   if (is_static()) {
-    const Object& valueObj = Object::Handle(value());
-    jsobj.AddProperty("value", valueObj);
-  } else if (!instance.IsNull()) {
-    const Object& valueObj = Object::Handle(instance.GetField(*this));
+    const Instance& valueObj = Instance::Handle(value());
     jsobj.AddProperty("value", valueObj);
   }
 
@@ -9790,11 +9813,7 @@
 
 
 intptr_t DeoptInfo::FrameSize() const {
-  intptr_t pos = 0;
-  while (Instruction(pos) == DeoptInstr::kMaterializeObject) {
-    pos++;
-  }
-  return TranslationLength() - pos;
+  return TranslationLength() - NumMaterializations();
 }
 
 
@@ -9811,6 +9830,15 @@
 }
 
 
+intptr_t DeoptInfo::NumMaterializations() const {
+  intptr_t pos = 0;
+  while (Instruction(pos) == DeoptInstr::kMaterializeObject) {
+    pos++;
+  }
+  return pos;
+}
+
+
 void DeoptInfo::ToInstructions(const Array& table,
                                GrowableArray<DeoptInstr*>* instructions) const {
   ASSERT(instructions->is_empty());
@@ -11981,7 +12009,7 @@
 }
 
 
-bool Instance::IsValidFieldOffset(int offset) const {
+bool Instance::IsValidFieldOffset(intptr_t offset) const {
   const Class& cls = Class::Handle(clazz());
   return (offset >= 0 && offset <= (cls.instance_size() - kWordSize));
 }
@@ -12055,20 +12083,34 @@
     jsobj.AddProperty("type", ref ? "@Null" : "Null");
     jsobj.AddProperty("id", "objects/being-initialized");
     return;
+  } else if (raw() == Symbols::OptimizedOut().raw()) {
+    // TODO(turnidge): This is a hack.  The user could have this
+    // special string in their program.  Fixing this involves updating
+    // the debugging api a bit.
+    jsobj.AddProperty("type", ref ? "@Null" : "Null");
+    jsobj.AddProperty("id", "objects/optimized-out");
+    jsobj.AddProperty("preview", "<optimized out>");
+    return;
   } else {
     ObjectIdRing* ring = Isolate::Current()->object_id_ring();
     intptr_t id = ring->GetIdForObject(raw());
-    jsobj.AddProperty("type", JSONType(ref));
+    if (IsClosure()) {
+      const Function& closureFunc = Function::Handle(Closure::function(*this));
+      jsobj.AddProperty("closureFunc", closureFunc);
+      jsobj.AddProperty("type", ref ? "@Closure" : "Closure");
+    } else {
+      jsobj.AddProperty("type", JSONType(ref));
+    }
     jsobj.AddPropertyF("id", "objects/%" Pd "", id);
     jsobj.AddProperty("class", cls);
   }
-
   if (ref) {
     return;
   }
 
   // Walk the superclass chain, adding all instance fields.
   {
+    Instance& fieldValue = Instance::Handle();
     JSONArray jsarr(&jsobj, "fields");
     while (!cls.IsNull()) {
       const Array& field_array = Array::Handle(cls.fields());
@@ -12077,7 +12119,10 @@
         for (intptr_t i = 0; i < field_array.Length(); i++) {
           field ^= field_array.At(i);
           if (!field.is_static()) {
-            jsarr.AddValue(field, *this);
+            fieldValue ^= GetField(field);
+            JSONObject jsfield(&jsarr);
+            jsfield.AddProperty("decl", field);
+            jsfield.AddProperty("value", fieldValue);
           }
         }
       }
@@ -12365,6 +12410,12 @@
 }
 
 
+bool AbstractType::IsFloat64x2Type() const {
+  return HasResolvedTypeClass() &&
+      (type_class() == Type::Handle(Type::Float64x2()).type_class());
+}
+
+
 bool AbstractType::IsInt32x4Type() const {
   return HasResolvedTypeClass() &&
       (type_class() == Type::Handle(Type::Int32x4()).type_class());
@@ -12533,6 +12584,11 @@
 }
 
 
+RawType* Type::Float64x2() {
+  return Isolate::Current()->object_store()->float64x2_type();
+}
+
+
 RawType* Type::Int32x4() {
   return Isolate::Current()->object_store()->int32x4_type();
 }
@@ -12564,6 +12620,7 @@
     // 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());
@@ -12577,6 +12634,7 @@
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
+  ASSERT(type.IsFinalized());
   return type.raw();
 }
 
@@ -12599,7 +12657,7 @@
 
 
 void Type::set_is_being_finalized() const {
-  ASSERT(!IsFinalized() && !IsBeingFinalized());
+  ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized());
   set_type_state(RawType::kBeingFinalized);
 }
 
@@ -12643,15 +12701,9 @@
 }
 
 
-bool Type::IsResolved() const {
-  if (IsFinalized()) {
-    return true;
-  }
-  if (!HasResolvedTypeClass()) {
-    return false;
-  }
-  const TypeArguments& args = TypeArguments::Handle(arguments());
-  return args.IsNull() || args.IsResolved();
+void Type::set_is_resolved() const {
+  ASSERT(!IsResolved());
+  set_type_state(RawType::kResolved);
 }
 
 
@@ -12806,7 +12858,9 @@
   TypeArguments& type_args = TypeArguments::Handle(arguments());
   type_args = type_args.CloneUnfinalized();
   const Class& type_cls = Class::Handle(type_class());
-  return Type::New(type_cls, type_args, token_pos());
+  const Type& type = Type::Handle(Type::New(type_cls, type_args, token_pos()));
+  type.set_is_resolved();
+  return type.raw();
 }
 
 
@@ -12840,13 +12894,13 @@
   if (canonical_types.IsNull()) {
     canonical_types = empty_array().raw();
   }
-  const intptr_t canonical_types_len = canonical_types.Length();
+  const intptr_t length = canonical_types.Length();
   // Linear search to see whether this type is already present in the
   // list of canonicalized types.
   // TODO(asiva): Try to re-factor this lookup code to make sharing
   // easy between the 4 versions of this loop.
   intptr_t index = 0;
-  while (index < canonical_types_len) {
+  while (index < length) {
     type ^= canonical_types.At(index);
     if (type.IsNull()) {
       break;
@@ -12865,9 +12919,10 @@
   type_args = type_args.Canonicalize(trail);
   set_arguments(type_args);
   // The type needs to be added to the list. Grow the list if it is full.
-  if (index == canonical_types_len) {
-    const intptr_t kLengthIncrement = 2;  // Raw and parameterized.
-    const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
+  if (index == length) {
+    const intptr_t new_length = (length > 64) ?
+        (length + 64) :
+        ((length == 0) ? 1 : (length * 2));
     const Array& new_canonical_types = Array::Handle(
         isolate, Array::Grow(canonical_types, new_length, Heap::kOld));
     cls.set_canonical_types(new_canonical_types);
@@ -12956,10 +13011,8 @@
 
 
 void Type::set_type_state(int8_t state) const {
-  ASSERT((state == RawType::kAllocated) ||
-         (state == RawType::kBeingFinalized) ||
-         (state == RawType::kFinalizedInstantiated) ||
-         (state == RawType::kFinalizedUninstantiated));
+  ASSERT((state >= RawType::kAllocated) &&
+         (state <= RawType::kFinalizedUninstantiated));
   raw_ptr()->type_state_ = state;
 }
 
@@ -16195,11 +16248,34 @@
 
 
 void Array::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  Instance::PrintToJSONStream(stream, ref);
+  JSONObject jsobj(stream);
+  Class& cls = Class::Handle(this->clazz());
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  jsobj.AddProperty("type", JSONType(ref));
+  jsobj.AddPropertyF("id", "objects/%" Pd "", id);
+  jsobj.AddProperty("class", cls);
+  jsobj.AddProperty("length", Length());
+  if (ref) {
+    return;
+  }
+  {
+    JSONArray jsarr(&jsobj, "elements");
+    for (intptr_t index = 0; index < Length(); index++) {
+      JSONObject jselement(&jsarr);
+      jselement.AddProperty("index", index);
+
+      Instance& instance = Instance::Handle();
+      instance ^= At(index);
+      jselement.AddProperty("value", instance);
+    }
+  }
 }
 
 
-RawArray* Array::Grow(const Array& source, int new_length, Heap::Space space) {
+RawArray* Array::Grow(const Array& source,
+                      intptr_t new_length,
+                      Heap::Space space) {
   const Array& result = Array::Handle(Array::New(new_length, space));
   intptr_t len = 0;
   if (!source.IsNull()) {
@@ -16506,7 +16582,28 @@
 
 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream,
                                             bool ref) const {
-  Instance::PrintToJSONStream(stream, ref);
+  JSONObject jsobj(stream);
+  Class& cls = Class::Handle(this->clazz());
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  jsobj.AddProperty("type", JSONType(ref));
+  jsobj.AddPropertyF("id", "objects/%" Pd "", id);
+  jsobj.AddProperty("class", cls);
+  jsobj.AddProperty("length", Length());
+  if (ref) {
+    return;
+  }
+  {
+    JSONArray jsarr(&jsobj, "elements");
+    for (intptr_t index = 0; index < Length(); index++) {
+      JSONObject jselement(&jsarr);
+      jselement.AddProperty("index", index);
+
+      Instance& instance = Instance::Handle();
+      instance ^= At(index);
+      jselement.AddProperty("value", instance);
+    }
+  }
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index ab2c0f7..3ee81df 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -367,6 +367,10 @@
     ASSERT(empty_array_ != NULL);
     return *empty_array_;
   }
+  static const Array& zero_array() {
+    ASSERT(zero_array_ != NULL);
+    return *zero_array_;
+  }
 
   static const PcDescriptors& empty_descriptors() {
     ASSERT(empty_descriptors_ != NULL);
@@ -614,6 +618,7 @@
   static Instance* null_instance_;
   static TypeArguments* null_type_arguments_;
   static Array* empty_array_;
+  static Array* zero_array_;
   static PcDescriptors* empty_descriptors_;
   static Instance* sentinel_;
   static Instance* transition_sentinel_;
@@ -992,6 +997,11 @@
   }
   void set_is_fields_marked_nullable() const;
 
+  bool is_cycle_free() const {
+    return CycleFreeBit::decode(raw_ptr()->state_bits_);
+  }
+  void set_is_cycle_free() const;
+
   uint16_t num_native_fields() const {
     return raw_ptr()->num_native_fields_;
   }
@@ -1100,6 +1110,7 @@
     kMixinAppAliasBit = 9,
     kMixinTypeAppliedBit = 10,
     kFieldsMarkedNullableBit = 11,
+    kCycleFreeBit = 12,
   };
   class ConstBit : public BitField<bool, kConstBit, 1> {};
   class ImplementedBit : public BitField<bool, kImplementedBit, 1> {};
@@ -1114,6 +1125,7 @@
   class MixinTypeAppliedBit : public BitField<bool, kMixinTypeAppliedBit, 1> {};
   class FieldsMarkedNullableBit : public BitField<bool,
       kFieldsMarkedNullableBit, 1> {};  // NOLINT
+  class CycleFreeBit : public BitField<bool, kCycleFreeBit, 1> {};
 
   void set_name(const String& value) const;
   void set_user_name(const String& value) const;
@@ -1280,12 +1292,13 @@
   bool IsEquivalent(const TypeArguments& other,
                     GrowableObjectArray* trail = NULL) const;
 
-  bool IsResolved() const;
   bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
   bool IsUninstantiatedIdentity() const;
   bool CanShareInstantiatorTypeArguments(const Class& instantiator_class) const;
 
-  // Returns true if all types of this vector are finalized.
+  // Returns true if all types of this vector are respectively, resolved,
+  // finalized, or bounded.
+  bool IsResolved() const;
   bool IsFinalized() const;
   bool IsBounded() const;
 
@@ -2181,12 +2194,6 @@
   static bool IsGetterName(const String& function_name);
   static bool IsSetterName(const String& function_name);
 
-  // When we print a field to a JSON stream, we want to make it appear
-  // that the value is a property of the field, so we allow the actual
-  // instance to be supplied here.
-  virtual void PrintToJSONStreamWithInstance(
-      JSONStream* stream, const Instance& instance, bool ref) const;
-
  private:
   friend class StoreInstanceFieldInstr;  // Generated code access to bit field.
 
@@ -3084,6 +3091,9 @@
   // instructions in the prefix.
   intptr_t FrameSize() const;
 
+  // Returns the number of kMaterializeObject instructions in the prefix.
+  intptr_t NumMaterializations() const;
+
   static RawDeoptInfo* New(intptr_t num_commands);
 
   static const intptr_t kBytesPerElement = (kNumberOfEntries * kWordSize);
@@ -3977,7 +3987,14 @@
     return ((index >= 0) && (index < clazz()->ptr()->num_native_fields_));
   }
 
-  inline intptr_t GetNativeField(Isolate* isolate, int index) const;
+  inline intptr_t GetNativeField(int index) const;
+  inline void GetNativeFields(uint16_t num_fields,
+                              intptr_t* field_values) const;
+
+  uint16_t NumNativeFields() const {
+    return clazz()->ptr()->num_native_fields_;
+  }
+
   void SetNativeField(int index, intptr_t value) const;
 
   // Returns true if the instance is a closure object.
@@ -4022,7 +4039,7 @@
   void SetFieldAtOffset(intptr_t offset, const Object& value) const {
     StorePointer(FieldAddrAtOffset(offset), value.raw());
   }
-  bool IsValidFieldOffset(int offset) const;
+  bool IsValidFieldOffset(intptr_t offset) const;
 
   static intptr_t NextFieldOffset() {
     return sizeof(RawInstance);
@@ -4130,6 +4147,9 @@
   // Check if this type represents the 'Float32x4' type.
   bool IsFloat32x4Type() const;
 
+  // Check if this type represents the 'Float64x2' type.
+  bool IsFloat64x2Type() const;
+
   // Check if this type represents the 'Int32x4' type.
   bool IsInt32x4Type() const;
 
@@ -4185,8 +4205,8 @@
   }
   virtual bool IsFinalized() const {
     return
-    (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
-    (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated);
+        (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
+        (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated);
   }
   void SetIsFinalized() const;
   void ResetIsFinalized() const;  // Ignore current state and set again.
@@ -4199,7 +4219,10 @@
   virtual bool IsMalformedOrMalbounded() const;
   virtual RawLanguageError* error() const { return raw_ptr()->error_; }
   virtual void set_error(const LanguageError& value) const;
-  virtual bool IsResolved() const;  // Class and all arguments classes resolved.
+  virtual bool IsResolved() const {
+    return raw_ptr()->type_state_ >= RawType::kResolved;
+  }
+  void set_is_resolved() const;
   virtual bool HasResolvedTypeClass() const;  // Own type class resolved.
   virtual RawClass* type_class() const;
   void set_type_class(const Object& value) const;
@@ -4254,6 +4277,9 @@
   // The 'Float32x4' type.
   static RawType* Float32x4();
 
+  // The 'Float64x2' type.
+  static RawType* Float64x2();
+
   // The 'Int32x4' type.
   static RawType* Int32x4();
 
@@ -5629,7 +5655,7 @@
   // 'source' to the new array. 'new_length' must be greater than or equal to
   // 'source.Length()'. 'source' can be null.
   static RawArray* Grow(const Array& source,
-                        int new_length,
+                        intptr_t new_length,
                         Heap::Space space = Heap::kNew);
 
   // Return an Array object that contains all the elements currently present
@@ -6554,7 +6580,7 @@
 }
 
 
-intptr_t Instance::GetNativeField(Isolate* isolate, int index) const {
+intptr_t Instance::GetNativeField(int index) const {
   ASSERT(IsValidNativeIndex(index));
   NoGCScope no_gc;
   RawTypedData* native_fields =
@@ -6566,6 +6592,25 @@
 }
 
 
+void Instance::GetNativeFields(uint16_t num_fields,
+                               intptr_t* field_values) const {
+  NoGCScope no_gc;
+  ASSERT(num_fields == NumNativeFields());
+  ASSERT(field_values != NULL);
+  RawTypedData* native_fields =
+      reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+  if (native_fields == TypedData::null()) {
+    for (intptr_t i = 0; i < num_fields; i++) {
+      field_values[i] = 0;
+    }
+  }
+  intptr_t* fields = reinterpret_cast<intptr_t*>(native_fields->ptr()->data_);
+  for (intptr_t i = 0; i < num_fields; i++) {
+    field_values[i] = fields[i];
+  }
+}
+
+
 bool String::Equals(const String& str) const {
   if (raw() == str.raw()) {
     return true;  // Both handles point to the same raw instance.
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 49b9444..cad024b 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1814,6 +1814,10 @@
 
   EXPECT_EQ(0, Object::empty_array().Length());
 
+  EXPECT_EQ(1, Object::zero_array().Length());
+  element = Object::zero_array().At(0);
+  EXPECT(Smi::Cast(element).IsZero());
+
   array.MakeImmutable();
   Object& obj = Object::Handle(array.raw());
   EXPECT(obj.IsArray());
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 67aaf47..907e0ac 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -5347,8 +5347,9 @@
   NativeFunction native_function = NativeEntry::ResolveNative(
       library, native_name, num_params, &auto_setup_scope);
   if (native_function == NULL) {
-    ErrorMsg(native_pos, "native function '%s' cannot be found",
-        native_name.ToCString());
+    ErrorMsg(native_pos,
+             "native function '%s' (%" Pd " arguments) cannot be found",
+             native_name.ToCString(), func.NumParameters());
   }
   func.SetIsNativeAutoSetupScope(auto_setup_scope);
 
@@ -7871,13 +7872,15 @@
     if (name.IsNull()) {
       ErrorMsg(left_pos, "expression is not assignable");
     }
-    result = ThrowNoSuchMethodError(original->token_pos(),
-                                    *target_cls,
-                                    name,
-                                    NULL,  // No arguments.
-                                    InvocationMirror::kStatic,
-                                    InvocationMirror::kSetter,
-                                    NULL);  // No existing function.
+    result = ThrowNoSuchMethodError(
+        original->token_pos(),
+        *target_cls,
+        name,
+        NULL,  // No arguments.
+        InvocationMirror::kStatic,
+        original->IsLoadLocalNode() ?
+            InvocationMirror::kLocalVar : InvocationMirror::kSetter,
+        NULL);  // No existing function.
   } else if (result->IsStoreIndexedNode() ||
              result->IsInstanceSetterNode() ||
              result->IsStaticSetterNode() ||
diff --git a/runtime/vm/proccpuinfo.cc b/runtime/vm/proccpuinfo.cc
new file mode 100644
index 0000000..17dc170
--- /dev/null
+++ b/runtime/vm/proccpuinfo.cc
@@ -0,0 +1,156 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
+
+#include "vm/proccpuinfo.h"
+
+#include <ctype.h>  // NOLINT
+#include <string.h>  // NOLINT
+
+#include "platform/assert.h"
+
+namespace dart {
+
+
+char* ProcCpuInfo::data_ = NULL;
+intptr_t ProcCpuInfo::datalen_ = 0;
+
+
+void ProcCpuInfo::InitOnce() {
+  // Get the size of the cpuinfo file by reading it until the end. This is
+  // required because files under /proc do not always return a valid size
+  // when using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
+  static const char PATHNAME[] = "/proc/cpuinfo";
+  FILE* fp = fopen(PATHNAME, "r");
+  if (fp != NULL) {
+    for (;;) {
+      char buffer[256];
+      size_t n = fread(buffer, 1, sizeof(buffer), fp);
+      if (n == 0) {
+        break;
+      }
+      datalen_ += n;
+    }
+    fclose(fp);
+  }
+
+  // Read the contents of the cpuinfo file.
+  data_ = new char[datalen_ + 1];
+  fp = fopen(PATHNAME, "r");
+  if (fp != NULL) {
+    for (intptr_t offset = 0; offset < datalen_; ) {
+      size_t n = fread(data_ + offset, 1, datalen_ - offset, fp);
+      if (n == 0) {
+        break;
+      }
+      offset += n;
+    }
+    fclose(fp);
+  }
+
+  // Zero-terminate the data.
+  data_[datalen_] = '\0';
+}
+
+
+void ProcCpuInfo::Cleanup() {
+  ASSERT(data_);
+  delete[] data_;
+  data_ = NULL;
+}
+
+
+char* ProcCpuInfo::FieldStart(const char* field) {
+  // Look for first field occurrence, and ensure it starts the line.
+  size_t fieldlen = strlen(field);
+  char* p = data_;
+  for (;;) {
+    p = strstr(p, field);
+    if (p == NULL) {
+      return NULL;
+    }
+    if (p == data_ || p[-1] == '\n') {
+      break;
+    }
+    p += fieldlen;
+  }
+
+  // Skip to the first colon followed by a space.
+  p = strchr(p + fieldlen, ':');
+  if (p == NULL || !isspace(p[1])) {
+    return NULL;
+  }
+  p += 2;
+
+  return p;
+}
+
+
+bool ProcCpuInfo::FieldContains(const char* field, const char* search_string) {
+  ASSERT(data_ != NULL);
+  ASSERT(search_string != NULL);
+
+  char* p = FieldStart(field);
+  if (p == NULL) {
+    return false;
+  }
+
+  // Find the end of the line.
+  char* q = strchr(p, '\n');
+  if (q == NULL) {
+    q = data_ + datalen_;
+  }
+
+  char saved_end = *q;
+  *q = '\0';
+  bool ret = (strcasestr(p, search_string) != NULL);
+  *q = saved_end;
+
+  return ret;
+}
+
+
+// Extract the content of a the first occurrence of a given field in
+// the content of the cpuinfo file and return it as a heap-allocated
+// string that must be freed by the caller using delete[].
+// Return NULL if not found.
+const char* ProcCpuInfo::ExtractField(const char* field) {
+  ASSERT(field != NULL);
+  ASSERT(data_ != NULL);
+
+  char* p = FieldStart(field);
+  if (p == NULL) {
+    return NULL;
+  }
+
+  // Find the end of the line.
+  char* q = strchr(p, '\n');
+  if (q == NULL) {
+    q = data_ + datalen_;
+  }
+
+  intptr_t len = q - p;
+  char* result = new char[len + 1];  // plus one for null-terminator.
+  // Copy the line into result, leaving enough room for a null-terminator.
+  char saved_end = *q;
+  *q = '\0';
+  strncpy(result, p, len);
+  result[len] = '\0';
+  *q = saved_end;
+
+  return result;
+}
+
+
+bool ProcCpuInfo::HasField(const char* field) {
+  ASSERT(field != NULL);
+  ASSERT(data_ != NULL);
+  return (FieldStart(field) != NULL);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
diff --git a/runtime/vm/proccpuinfo.h b/runtime/vm/proccpuinfo.h
new file mode 100644
index 0000000..0814c6a
--- /dev/null
+++ b/runtime/vm/proccpuinfo.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef VM_PROCCPUINFO_H_
+#define VM_PROCCPUINFO_H_
+
+#include "vm/globals.h"
+#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
+
+#include "vm/allocation.h"
+
+namespace dart {
+
+class ProcCpuInfo : public AllStatic {
+ public:
+  static void InitOnce();
+  static void Cleanup();
+  static bool FieldContains(const char* field, const char* search_string);
+  static const char* ExtractField(const char* field);
+  static bool HasField(const char* field);
+
+ private:
+  static char* data_;
+  static intptr_t datalen_;
+
+  static char* FieldStart(const char* field);
+};
+
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
+
+#endif  // VM_PROCCPUINFO_H_
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 6c6b19d..46c62fb 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -32,26 +32,15 @@
 DEFINE_FLAG(int, profile_period, 1000,
             "Time between profiler samples in microseconds. Minimum 250.");
 DEFINE_FLAG(int, profile_depth, 8,
-            "Maximum number stack frames walked. Minimum 1. Maximum 128.");
+            "Maximum number stack frames walked. Minimum 1. Maximum 255.");
 
 bool Profiler::initialized_ = false;
 SampleBuffer* Profiler::sample_buffer_ = NULL;
 
 void Profiler::InitOnce() {
-  const int kMinimumProfilePeriod = 250;
-  const int kMinimumDepth = 1;
-  const int kMaximumDepth = 128;
   // Place some sane restrictions on user controlled flags.
-  if (FLAG_profile_period < kMinimumProfilePeriod) {
-    FLAG_profile_period = kMinimumProfilePeriod;
-  }
-  if (FLAG_profile_depth < kMinimumDepth) {
-    FLAG_profile_depth = kMinimumDepth;
-  } else if (FLAG_profile_depth > kMaximumDepth) {
-    FLAG_profile_depth = kMaximumDepth;
-  }
-  // We must always initialize the Sample, even when the profiler is disabled.
-  Sample::InitOnce();
+  SetSamplePeriod(FLAG_profile_period);
+  SetSampleDepth(FLAG_profile_depth);
   if (!FLAG_profile) {
     return;
   }
@@ -74,6 +63,29 @@
 }
 
 
+void Profiler::SetSampleDepth(intptr_t depth) {
+  const int kMinimumDepth = 1;
+  const int kMaximumDepth = kSampleFramesSize - 1;
+  if (depth < kMinimumDepth) {
+    FLAG_profile_depth = kMinimumDepth;
+  } else if (depth > kMaximumDepth) {
+    FLAG_profile_depth = kMaximumDepth;
+  } else {
+    FLAG_profile_depth = depth;
+  }
+}
+
+
+void Profiler::SetSamplePeriod(intptr_t period) {
+  const int kMinimumProfilePeriod = 250;
+  if (period < kMinimumProfilePeriod) {
+    FLAG_profile_period = kMinimumProfilePeriod;
+  } else {
+    FLAG_profile_period = period;
+  }
+}
+
+
 void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) {
   if (!FLAG_profile) {
     return;
@@ -148,62 +160,26 @@
 }
 
 
-void Profiler::RecordTickInterruptCallback(const InterruptedThreadState& state,
-                                           void* data) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(data);
-  if (isolate == NULL) {
-    return;
-  }
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  if (sample_buffer == NULL) {
-    return;
-  }
-  Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(Sample::kIsolateSample, isolate, OS::GetCurrentTimeMicros(),
-               state.tid);
-}
-
-
-void Profiler::RecordSampleInterruptCallback(
-    const InterruptedThreadState& state,
-    void* data) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(data);
-  if (isolate == NULL) {
-    return;
-  }
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  if (sample_buffer == NULL) {
-    return;
-  }
-  Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(Sample::kIsolateSample, isolate, OS::GetCurrentTimeMicros(),
-               state.tid);
-  uintptr_t stack_lower = 0;
-  uintptr_t stack_upper = 0;
-  isolate->GetStackBounds(&stack_lower, &stack_upper);
-  if ((stack_lower == 0) || (stack_upper == 0)) {
-    stack_lower = 0;
-    stack_upper = 0;
-  }
-  ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
-                                        state.pc, state.fp, state.sp);
-  stackWalker.walk();
-}
-
-
 struct AddressEntry {
-  uintptr_t pc;
-  uintptr_t ticks;
+  uword pc;
+  intptr_t exclusive_ticks;
+  intptr_t inclusive_ticks;
+
+  void tick(bool exclusive) {
+    if (exclusive) {
+      exclusive_ticks++;
+    } else {
+      inclusive_ticks++;
+    }
+  }
 };
 
+struct CallEntry {
+  intptr_t code_table_index;
+  intptr_t count;
+};
+
+typedef bool (*RegionCompare)(uword pc, uword region_start, uword region_end);
 
 // A region of code. Each region is a kind of code (Dart, Collected, or Native).
 class CodeRegion : public ZoneAllocated {
@@ -214,42 +190,54 @@
     kNativeCode
   };
 
-  CodeRegion(Kind kind, uintptr_t start, uintptr_t end) :
+  CodeRegion(Kind kind, uword start, uword end) :
       kind_(kind),
       start_(start),
       end_(end),
       inclusive_ticks_(0),
       exclusive_ticks_(0),
       name_(NULL),
-      address_table_(new ZoneGrowableArray<AddressEntry>()) {
+      address_table_(new ZoneGrowableArray<AddressEntry>()),
+      callers_table_(new ZoneGrowableArray<CallEntry>()),
+      callees_table_(new ZoneGrowableArray<CallEntry>()) {
+    ASSERT(start_ < end_);
   }
 
   ~CodeRegion() {
   }
 
-  uintptr_t start() const { return start_; }
-  void set_start(uintptr_t start) {
+  uword start() const { return start_; }
+  void set_start(uword start) {
     start_ = start;
   }
 
-  uintptr_t end() const { return end_; }
-  void set_end(uintptr_t end) {
+  uword end() const { return end_; }
+  void set_end(uword end) {
     end_ = end;
   }
 
-  void AdjustExtent(uintptr_t start, uintptr_t end) {
+  void AdjustExtent(uword start, uword end) {
     if (start < start_) {
       start_ = start;
     }
     if (end > end_) {
       end_ = end;
     }
+    ASSERT(start_ < end_);
   }
 
-  bool contains(uintptr_t pc) const {
+  bool contains(uword pc) const {
     return (pc >= start_) && (pc < end_);
   }
 
+  bool overlaps(const CodeRegion* other) const {
+    ASSERT(other != NULL);
+    return other->contains(start_)   ||
+           other->contains(end_ - 1) ||
+           contains(other->start())  ||
+           contains(other->end() - 1);
+  }
+
   intptr_t inclusive_ticks() const { return inclusive_ticks_; }
   void set_inclusive_ticks(intptr_t inclusive_ticks) {
     inclusive_ticks_ = inclusive_ticks;
@@ -286,26 +274,33 @@
     return NULL;
   }
 
-  void AddTick(bool exclusive) {
+  void DebugPrint() const {
+    printf("%s [%" Px ", %" Px ") %s\n", KindToCString(kind_), start(), end(),
+           name_);
+  }
+
+  void AddTickAtAddress(uword pc, bool exclusive, intptr_t serial) {
+    // Assert that exclusive ticks are never passed a valid serial number.
+    ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
+    if (!exclusive && (inclusive_tick_serial_ == serial)) {
+      // We've already given this code object an inclusive tick for this sample.
+      return;
+    }
+    // Tick the code object.
     if (exclusive) {
       exclusive_ticks_++;
     } else {
+      // Mark the last serial we ticked the inclusive count.
+      inclusive_tick_serial_ = serial;
       inclusive_ticks_++;
     }
-  }
-
-  void DebugPrint() {
-    printf("%s [%" Px ", %" Px ") %s\n", name_, start(), end(),
-           KindToCString(kind_));
-  }
-
-  void AddTickAtAddress(uintptr_t pc) {
+    // Tick the address entry.
     const intptr_t length = address_table_->length();
     intptr_t i = 0;
     for (; i < length; i++) {
       AddressEntry& entry = (*address_table_)[i];
       if (entry.pc == pc) {
-        entry.ticks++;
+        entry.tick(exclusive);
         return;
       }
       if (entry.pc > pc) {
@@ -314,7 +309,7 @@
     }
     AddressEntry entry;
     entry.pc = pc;
-    entry.ticks = 1;
+    entry.tick(exclusive);
     if (i < length) {
       // Insert at i.
       address_table_->InsertAt(i, entry);
@@ -324,6 +319,13 @@
     }
   }
 
+  void AddCaller(intptr_t index) {
+    AddCallEntry(callers_table_, index);
+  }
+
+  void AddCallee(intptr_t index) {
+    AddCallEntry(callees_table_, index);
+  }
 
   void PrintToJSONArray(JSONArray* events, bool full) {
     JSONObject obj(events);
@@ -339,7 +341,8 @@
       func ^= code.function();
       if (func.IsNull()) {
         if (name() == NULL) {
-          GenerateAndSetSymbolName("Stub");
+          const char* stub_name = StubCode::NameOfStub(start());
+          GenerateAndSetSymbolName(stub_name == NULL ? "Stub" : stub_name);
         }
         obj.AddPropertyF("start", "%" Px "", start());
         obj.AddPropertyF("end", "%" Px "", end());
@@ -368,12 +371,52 @@
       for (intptr_t i = 0; i < address_table_->length(); i++) {
         const AddressEntry& entry = (*address_table_)[i];
         ticks.AddValueF("%" Px "", entry.pc);
-        ticks.AddValueF("%" Pd "", entry.ticks);
+        ticks.AddValueF("%" Pd "", entry.exclusive_ticks);
+        ticks.AddValueF("%" Pd "", entry.inclusive_ticks);
+      }
+    }
+    {
+      JSONArray callers(&obj, "callers");
+      for (intptr_t i = 0; i < callers_table_->length(); i++) {
+        const CallEntry& entry = (*callers_table_)[i];
+        callers.AddValueF("%" Pd "", entry.code_table_index);
+        callers.AddValueF("%" Pd "", entry.count);
+      }
+    }
+    {
+      JSONArray callees(&obj, "callees");
+      for (intptr_t i = 0; i < callees_table_->length(); i++) {
+        const CallEntry& entry = (*callees_table_)[i];
+        callees.AddValueF("%" Pd "", entry.code_table_index);
+        callees.AddValueF("%" Pd "", entry.count);
       }
     }
   }
 
  private:
+  void AddCallEntry(ZoneGrowableArray<CallEntry>* table, intptr_t index) {
+    const intptr_t length = table->length();
+    intptr_t i = 0;
+    for (; i < length; i++) {
+      CallEntry& entry = (*table)[i];
+      if (entry.code_table_index == index) {
+        entry.count++;
+        return;
+      }
+      if (entry.code_table_index > index) {
+        break;
+      }
+    }
+    CallEntry entry;
+    entry.code_table_index = index;
+    entry.count = 1;
+    if (i < length) {
+      table->InsertAt(i, entry);
+    } else {
+      table->Add(entry);
+    }
+  }
+
   void GenerateAndSetSymbolName(const char* prefix) {
     const intptr_t kBuffSize = 512;
     char buff[kBuffSize];
@@ -383,17 +426,44 @@
   }
 
   Kind kind_;
-  uintptr_t start_;
-  uintptr_t end_;
+  uword start_;
+  uword end_;
   intptr_t inclusive_ticks_;
   intptr_t exclusive_ticks_;
+  intptr_t inclusive_tick_serial_;
   const char* name_;
   ZoneGrowableArray<AddressEntry>* address_table_;
-
+  ZoneGrowableArray<CallEntry>* callers_table_;
+  ZoneGrowableArray<CallEntry>* callees_table_;
   DISALLOW_COPY_AND_ASSIGN(CodeRegion);
 };
 
 
+class ScopeStopwatch : public ValueObject {
+ public:
+  explicit ScopeStopwatch(const char* name) : name_(name) {
+    start_ = OS::GetCurrentTimeMillis();
+  }
+
+  intptr_t GetElapsed() const {
+    intptr_t end = OS::GetCurrentTimeMillis();
+    ASSERT(end >= start_);
+    return end - start_;
+  }
+
+  ~ScopeStopwatch() {
+    if (FLAG_trace_profiled_isolates) {
+      intptr_t elapsed = GetElapsed();
+      OS::Print("%s took %" Pd " millis.\n", name_, elapsed);
+    }
+  }
+
+ private:
+  const char* name_;
+  intptr_t start_;
+};
+
+
 // All code regions. Code region tables are built on demand when a profile
 // is requested (through the service or on isolate shutdown).
 class ProfilerCodeRegionTable : public ValueObject {
@@ -406,7 +476,7 @@
   ~ProfilerCodeRegionTable() {
   }
 
-  void AddTick(uintptr_t pc, bool exclusive, bool tick_address) {
+  void AddTick(uword pc, bool exclusive, intptr_t serial) {
     intptr_t index = FindIndex(pc);
     if (index < 0) {
       CodeRegion* code_region = CreateCodeRegion(pc);
@@ -415,10 +485,9 @@
     }
     ASSERT(index >= 0);
     ASSERT(index < code_region_table_->length());
-    (*code_region_table_)[index]->AddTick(exclusive);
-    if (tick_address) {
-      (*code_region_table_)[index]->AddTickAtAddress(pc);
-    }
+
+    // Update code object counters.
+    (*code_region_table_)[index]->AddTickAtAddress(pc, exclusive, serial);
   }
 
   intptr_t Length() const { return code_region_table_->length(); }
@@ -427,19 +496,57 @@
     return (*code_region_table_)[idx];
   }
 
- private:
-  intptr_t FindIndex(uintptr_t pc) {
-    const intptr_t length = code_region_table_->length();
-    for (intptr_t i = 0; i < length; i++) {
-      const CodeRegion* code_region = (*code_region_table_)[i];
-      if (code_region->contains(pc)) {
-        return i;
-      }
+  intptr_t FindIndex(uword pc) const {
+    intptr_t index = FindRegionIndex(pc, &CompareLowerBound);
+    const CodeRegion* code_region = NULL;
+    if (index == code_region_table_->length()) {
+      // Not present.
+      return -1;
+    }
+    code_region = (*code_region_table_)[index];
+    if (code_region->contains(pc)) {
+      // Found at index.
+      return index;
     }
     return -1;
   }
 
-  CodeRegion* CreateCodeRegion(uintptr_t pc) {
+#if defined(DEBUG)
+  void Verify() {
+    VerifyOrder();
+    VerifyOverlap();
+  }
+#endif
+
+ private:
+  intptr_t FindRegionIndex(uword pc, RegionCompare comparator) const {
+    ASSERT(comparator != NULL);
+    intptr_t count = code_region_table_->length();
+    intptr_t first = 0;
+    while (count > 0) {
+      intptr_t it = first;
+      intptr_t step = count / 2;
+      it += step;
+      const CodeRegion* code_region = (*code_region_table_)[it];
+      if (comparator(pc, code_region->start(), code_region->end())) {
+        first = ++it;
+        count -= (step + 1);
+      } else {
+        count = step;
+      }
+    }
+    return first;
+  }
+
+  static bool CompareUpperBound(uword pc, uword start, uword end) {
+    return pc >= end;
+  }
+
+  static bool CompareLowerBound(uword pc, uword start, uword end) {
+    return end <= pc;
+  }
+
+  CodeRegion* CreateCodeRegion(uword pc) {
     Code& code = Code::Handle(Code::LookupCode(pc));
     if (!code.IsNull()) {
       return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(),
@@ -448,8 +555,7 @@
     if (heap_->CodeContains(pc)) {
       const intptr_t kDartCodeAlignment = 0x10;
       const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
-      return new CodeRegion(CodeRegion::kCollectedCode,
-                            (pc & kDartCodeAlignmentMask),
+      return new CodeRegion(CodeRegion::kCollectedCode, pc,
                             (pc & kDartCodeAlignmentMask) + kDartCodeAlignment);
     }
     uintptr_t native_start = 0;
@@ -466,39 +572,172 @@
     return code_region;
   }
 
+  void HandleOverlap(CodeRegion* region, CodeRegion* code_region,
+                     uword start, uword end) {
+    // We should never see overlapping Dart code regions.
+    ASSERT(region->kind() != CodeRegion::kDartCode);
+    // When code regions overlap, they should be of the same kind.
+    ASSERT(region->kind() == code_region->kind());
+    region->AdjustExtent(start, end);
+  }
+
   intptr_t InsertCodeRegion(CodeRegion* code_region) {
+    const uword start = code_region->start();
+    const uword end = code_region->end();
     const intptr_t length = code_region_table_->length();
-    const uintptr_t start = code_region->start();
-    const uintptr_t end = code_region->end();
-    intptr_t i = 0;
-    for (; i < length; i++) {
-      CodeRegion* region = (*code_region_table_)[i];
-      if (region->contains(start) || region->contains(end - 1)) {
-        // We should only see overlapping native code regions.
-        ASSERT(region->kind() == CodeRegion::kNativeCode);
-        // When code regions overlap, they should be of the same kind.
-        ASSERT(region->kind() == code_region->kind());
-        // Overlapping code region.
-        region->AdjustExtent(start, end);
-        return i;
-      } else if (start >= region->end()) {
-        // Insert here.
-        break;
+    if (length == 0) {
+      code_region_table_->Add(code_region);
+      return length;
+    }
+    // Determine the correct place to insert or merge code_region into table.
+    intptr_t lo = FindRegionIndex(start, &CompareLowerBound);
+    intptr_t hi = FindRegionIndex(end - 1, &CompareUpperBound);
+    if ((lo == length) && (hi == length)) {
+      lo = length - 1;
+    }
+    if (lo == length) {
+      CodeRegion* region = (*code_region_table_)[hi];
+      if (region->overlaps(code_region)) {
+        HandleOverlap(region, code_region, start, end);
+        return hi;
+      }
+      code_region_table_->Add(code_region);
+      return length;
+    } else if (hi == length) {
+      CodeRegion* region = (*code_region_table_)[lo];
+      if (region->overlaps(code_region)) {
+        HandleOverlap(region, code_region, start, end);
+        return lo;
+      }
+      code_region_table_->Add(code_region);
+      return length;
+    } else if (lo == hi) {
+      CodeRegion* region = (*code_region_table_)[lo];
+      if (region->overlaps(code_region)) {
+        HandleOverlap(region, code_region, start, end);
+        return lo;
+      }
+      code_region_table_->InsertAt(lo, code_region);
+      return lo;
+    } else {
+      CodeRegion* region = (*code_region_table_)[lo];
+      if (region->overlaps(code_region)) {
+        HandleOverlap(region, code_region, start, end);
+        return lo;
+      }
+      region = (*code_region_table_)[hi];
+      if (region->overlaps(code_region)) {
+        HandleOverlap(region, code_region, start, end);
+        return hi;
+      }
+      code_region_table_->InsertAt(hi, code_region);
+      return hi;
+    }
+    UNREACHABLE();
+  }
+
+#if defined(DEBUG)
+  void VerifyOrder() {
+    const intptr_t length = code_region_table_->length();
+    if (length == 0) {
+      return;
+    }
+    uword last = (*code_region_table_)[0]->end();
+    for (intptr_t i = 1; i < length; i++) {
+      CodeRegion* a = (*code_region_table_)[i];
+      ASSERT(last <= a->start());
+      last = a->end();
+    }
+  }
+
+  void VerifyOverlap() {
+    const intptr_t length = code_region_table_->length();
+    for (intptr_t i = 0; i < length; i++) {
+      CodeRegion* a = (*code_region_table_)[i];
+      for (intptr_t j = i+1; j < length; j++) {
+        CodeRegion* b = (*code_region_table_)[j];
+        ASSERT(!a->contains(b->start()) &&
+               !a->contains(b->end() - 1) &&
+               !b->contains(a->start()) &&
+               !b->contains(a->end() - 1));
       }
     }
-    if (i != length) {
-      code_region_table_->InsertAt(i, code_region);
-      return i;
-    }
-    code_region_table_->Add(code_region);
-    return code_region_table_->length() - 1;
   }
+#endif
 
   Heap* heap_;
   ZoneGrowableArray<CodeRegion*>* code_region_table_;
 };
 
 
+class CodeRegionTableBuilder : public SampleVisitor {
+ public:
+  CodeRegionTableBuilder(Isolate* isolate,
+                         ProfilerCodeRegionTable* code_region_table)
+      : SampleVisitor(isolate), code_region_table_(code_region_table) {
+    frames_ = 0;
+  }
+
+  void VisitSample(Sample* sample) {
+    // Give the bottom frame an exclusive tick.
+    code_region_table_->AddTick(sample->At(0), true, -1);
+    // Give all frames (including the bottom) an inclusive tick.
+    for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
+      if (sample->At(i) == 0) {
+        break;
+      }
+      frames_++;
+      code_region_table_->AddTick(sample->At(i), false, visited());
+    }
+  }
+
+  intptr_t frames() const { return frames_; }
+
+ private:
+  intptr_t frames_;
+  ProfilerCodeRegionTable* code_region_table_;
+};
+
+
+class CodeRegionTableCallersBuilder : public SampleVisitor {
+ public:
+  CodeRegionTableCallersBuilder(Isolate* isolate,
+                                ProfilerCodeRegionTable* code_region_table)
+      : SampleVisitor(isolate), code_region_table_(code_region_table) {
+    ASSERT(code_region_table_ != NULL);
+  }
+
+  void VisitSample(Sample* sample) {
+    intptr_t current_index = code_region_table_->FindIndex(sample->At(0));
+    ASSERT(current_index != -1);
+    CodeRegion* current = code_region_table_->At(current_index);
+    intptr_t caller_index = -1;
+    CodeRegion* caller = NULL;
+    intptr_t callee_index = -1;
+    CodeRegion* callee = NULL;
+    for (intptr_t i = 1; i < FLAG_profile_depth; i++) {
+      if (sample->At(i) == 0) {
+        break;
+      }
+      caller_index = code_region_table_->FindIndex(sample->At(i));
+      ASSERT(caller_index != -1);
+      caller = code_region_table_->At(caller_index);
+      current->AddCaller(caller_index);
+      if (callee != NULL) {
+        current->AddCallee(callee_index);
+      }
+      // Move cursors.
+      callee_index = current_index;
+      callee = current;
+      current_index = caller_index;
+      current = caller;
+    }
+  }
+
+ private:
+  ProfilerCodeRegionTable* code_region_table_;
+};
+
 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream,
                                  bool full) {
   ASSERT(isolate == Isolate::Current());
@@ -519,9 +758,28 @@
     {
       // Build code region table.
       ProfilerCodeRegionTable code_region_table(isolate);
-      intptr_t samples =
-          ProcessSamples(isolate, &code_region_table, sample_buffer);
+      CodeRegionTableBuilder builder(isolate, &code_region_table);
+      CodeRegionTableCallersBuilder build_callers(isolate, &code_region_table);
       {
+        ScopeStopwatch sw("CodeTableBuild");
+        sample_buffer->VisitSamples(&builder);
+      }
+#if defined(DEBUG)
+      code_region_table.Verify();
+#endif
+      {
+        ScopeStopwatch sw("CodeTableCallersBuild");
+        sample_buffer->VisitSamples(&build_callers);
+      }
+      // Number of samples we processed.
+      intptr_t samples = builder.visited();
+      intptr_t frames = builder.frames();
+      if (FLAG_trace_profiled_isolates) {
+        OS::Print("%" Pd " frames produced %" Pd " code objects.\n",
+                  frames, code_region_table.Length());
+      }
+      {
+        ScopeStopwatch sw("CodeTableStream");
         // Serialize to JSON.
         JSONObject obj(stream);
         obj.AddProperty("type", "Profile");
@@ -540,58 +798,6 @@
 }
 
 
-intptr_t Profiler::ProcessSamples(Isolate* isolate,
-                                  ProfilerCodeRegionTable* code_region_table,
-                                  SampleBuffer* sample_buffer) {
-  int64_t start = OS::GetCurrentTimeMillis();
-  intptr_t samples = 0;
-  Sample* sample = Sample::Allocate();
-  for (intptr_t i = 0; i < sample_buffer->capacity(); i++) {
-    sample_buffer->CopySample(i, sample);
-    if (sample->isolate() != isolate) {
-      continue;
-    }
-    if (sample->timestamp() == 0) {
-      continue;
-    }
-    samples += ProcessSample(isolate, code_region_table, sample);
-  }
-  free(sample);
-  int64_t end = OS::GetCurrentTimeMillis();
-  if (FLAG_trace_profiled_isolates) {
-    int64_t delta = end - start;
-    OS::Print("Processed %" Pd " samples from %s in %" Pd64 " milliseconds.\n",
-        samples,
-        isolate->name(),
-        delta);
-  }
-  return samples;
-}
-
-
-intptr_t Profiler::ProcessSample(Isolate* isolate,
-                                 ProfilerCodeRegionTable* code_region_table,
-                                Sample* sample) {
-  if (sample->type() != Sample::kIsolateSample) {
-    return 0;
-  }
-  if (sample->At(0) == 0) {
-    // No frames in this sample.
-    return 0;
-  }
-  // i points to the leaf (exclusive) PC sample. Do not tick the address.
-  code_region_table->AddTick(sample->At(0), true, false);
-  // Give all frames an inclusive tick and tick the address.
-  for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
-    if (sample->At(i) == 0) {
-      break;
-    }
-    code_region_table->AddTick(sample->At(i), false, true);
-  }
-  return 1;
-}
-
-
 void Profiler::WriteProfile(Isolate* isolate) {
   if (isolate == NULL) {
     return;
@@ -650,76 +856,6 @@
 }
 
 
-intptr_t Sample::instance_size_ = 0;
-
-void Sample::InitOnce() {
-  ASSERT(FLAG_profile_depth >= 1);
-  instance_size_ =
-     sizeof(Sample) + (sizeof(intptr_t) * FLAG_profile_depth);  // NOLINT.
-}
-
-
-uintptr_t Sample::At(intptr_t i) const {
-  ASSERT(i >= 0);
-  ASSERT(i < FLAG_profile_depth);
-  return pcs_[i];
-}
-
-
-void Sample::SetAt(intptr_t i, uintptr_t pc) {
-  ASSERT(i >= 0);
-  ASSERT(i < FLAG_profile_depth);
-  pcs_[i] = pc;
-}
-
-
-void Sample::Init(SampleType type, Isolate* isolate, int64_t timestamp,
-                  ThreadId tid) {
-  timestamp_ = timestamp;
-  tid_ = tid;
-  isolate_ = isolate;
-  type_ = type;
-  for (int i = 0; i < FLAG_profile_depth; i++) {
-    pcs_[i] = 0;
-  }
-}
-
-
-void Sample::CopyInto(Sample* dst) const {
-  ASSERT(dst != NULL);
-  dst->timestamp_ = timestamp_;
-  dst->tid_ = tid_;
-  dst->isolate_ = isolate_;
-  dst->type_ = type_;
-  for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
-    dst->pcs_[i] = pcs_[i];
-  }
-}
-
-
-Sample* Sample::Allocate() {
-  return reinterpret_cast<Sample*>(malloc(instance_size()));
-}
-
-
-SampleBuffer::SampleBuffer(intptr_t capacity) {
-  capacity_ = capacity;
-  samples_ = reinterpret_cast<Sample*>(
-      calloc(capacity, Sample::instance_size()));
-  cursor_ = 0;
-}
-
-
-SampleBuffer::~SampleBuffer() {
-  if (samples_ != NULL) {
-    free(samples_);
-    samples_ = NULL;
-    cursor_ = 0;
-    capacity_ = 0;
-  }
-}
-
-
 Sample* SampleBuffer::ReserveSample() {
   ASSERT(samples_ != NULL);
   uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_);
@@ -728,38 +864,6 @@
   return At(cursor);
 }
 
-
-void SampleBuffer::CopySample(intptr_t i, Sample* sample) const {
-  At(i)->CopyInto(sample);
-}
-
-
-Sample* SampleBuffer::At(intptr_t idx) const {
-  ASSERT(idx >= 0);
-  ASSERT(idx < capacity_);
-  intptr_t offset = idx * Sample::instance_size();
-  uint8_t* samples = reinterpret_cast<uint8_t*>(samples_);
-  return reinterpret_cast<Sample*>(samples + offset);
-}
-
-
-ProfilerSampleStackWalker::ProfilerSampleStackWalker(Sample* sample,
-                                                     uintptr_t stack_lower,
-                                                     uintptr_t stack_upper,
-                                                     uintptr_t pc,
-                                                     uintptr_t fp,
-                                                     uintptr_t sp) :
-    sample_(sample),
-    stack_lower_(stack_lower),
-    stack_upper_(stack_upper),
-    original_pc_(pc),
-    original_fp_(fp),
-    original_sp_(sp),
-    lower_bound_(stack_lower) {
-  ASSERT(sample_ != NULL);
-}
-
-
 // Notes on stack frame walking:
 //
 // The sampling profiler will collect up to Sample::kNumStackFrames stack frames
@@ -768,77 +872,128 @@
 // recent GCC versions with optimizing enabled) the stack walking code may
 // fail (sometimes leading to a crash).
 //
+class ProfilerSampleStackWalker : public ValueObject {
+ public:
+  ProfilerSampleStackWalker(Sample* sample,
+                            uword stack_lower,
+                            uword stack_upper,
+                            uword pc,
+                            uword fp,
+                            uword sp)
+      : sample_(sample),
+        stack_upper_(stack_upper),
+        original_pc_(pc),
+        original_fp_(fp),
+        original_sp_(sp),
+        lower_bound_(stack_lower) {
+    ASSERT(sample_ != NULL);
+  }
 
-int ProfilerSampleStackWalker::walk() {
-  const intptr_t kMaxStep = 0x1000;  // 4K.
-  const bool kWalkStack = true;  // Walk the stack.
-  // Always store the exclusive PC.
-  sample_->SetAt(0, original_pc_);
-  if (!kWalkStack) {
-    // Not walking the stack, only took exclusive sample.
-    return 1;
-  }
-  uword* pc = reinterpret_cast<uword*>(original_pc_);
-  uword* fp = reinterpret_cast<uword*>(original_fp_);
-  uword* previous_fp = fp;
-  if (original_sp_ > original_fp_) {
-    // Stack pointer should not be above frame pointer.
-    return 1;
-  }
-  intptr_t gap = original_fp_ - original_sp_;
-  if (gap >= kMaxStep) {
-    // Gap between frame pointer and stack pointer is
-    // too large.
-    return 1;
-  }
-  if (original_sp_ < lower_bound_) {
-    // The stack pointer gives us a better lower bound than
-    // the isolates stack limit.
-    lower_bound_ = original_sp_;
-  }
-  int i = 0;
-  for (; i < FLAG_profile_depth; i++) {
-    sample_->SetAt(i, reinterpret_cast<uintptr_t>(pc));
-    if (!ValidFramePointer(fp)) {
-      return i + 1;
+  int walk() {
+    const intptr_t kMaxStep = 0x1000;  // 4K.
+    const bool kWalkStack = true;  // Walk the stack.
+    // Always store the exclusive PC.
+    sample_->SetAt(0, original_pc_);
+    if (!kWalkStack) {
+      // Not walking the stack, only took exclusive sample.
+      return 1;
     }
-    pc = CallerPC(fp);
-    previous_fp = fp;
-    fp = CallerFP(fp);
-    intptr_t step = fp - previous_fp;
-    if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) {
-      // Frame pointer step is too large.
-      // Frame pointer did not move to a higher address.
-      // Frame pointer is outside of isolate stack bounds.
-      return i + 1;
+    uword* pc = reinterpret_cast<uword*>(original_pc_);
+    uword* fp = reinterpret_cast<uword*>(original_fp_);
+    uword* previous_fp = fp;
+    if (original_sp_ > original_fp_) {
+      // Stack pointer should not be above frame pointer.
+      return 1;
     }
-    // Move the lower bound up.
-    lower_bound_ = reinterpret_cast<uintptr_t>(fp);
+    intptr_t gap = original_fp_ - original_sp_;
+    if (gap >= kMaxStep) {
+      // Gap between frame pointer and stack pointer is
+      // too large.
+      return 1;
+    }
+    if (original_sp_ < lower_bound_) {
+      // The stack pointer gives us a better lower bound than
+      // the isolates stack limit.
+      lower_bound_ = original_sp_;
+    }
+    int i = 0;
+    for (; i < FLAG_profile_depth; i++) {
+      sample_->SetAt(i, reinterpret_cast<uword>(pc));
+      if (!ValidFramePointer(fp)) {
+        return i + 1;
+      }
+      pc = CallerPC(fp);
+      previous_fp = fp;
+      fp = CallerFP(fp);
+      intptr_t step = fp - previous_fp;
+      if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) {
+        // Frame pointer step is too large.
+        // Frame pointer did not move to a higher address.
+        // Frame pointer is outside of isolate stack bounds.
+        return i + 1;
+      }
+      // Move the lower bound up.
+      lower_bound_ = reinterpret_cast<uword>(fp);
+    }
+    return i;
   }
-  return i;
-}
 
-
-uword* ProfilerSampleStackWalker::CallerPC(uword* fp) {
-  ASSERT(fp != NULL);
-  return reinterpret_cast<uword*>(*(fp + kSavedCallerPcSlotFromFp));
-}
-
-
-uword* ProfilerSampleStackWalker::CallerFP(uword* fp) {
-  ASSERT(fp != NULL);
-  return reinterpret_cast<uword*>(*(fp + kSavedCallerFpSlotFromFp));
-}
-
-
-bool ProfilerSampleStackWalker::ValidFramePointer(uword* fp) {
-  if (fp == NULL) {
-    return false;
+ private:
+  uword* CallerPC(uword* fp) const {
+    ASSERT(fp != NULL);
+    return reinterpret_cast<uword*>(*(fp + kSavedCallerPcSlotFromFp));
   }
-  uintptr_t cursor = reinterpret_cast<uintptr_t>(fp);
-  cursor += sizeof(fp);
-  bool r = cursor >= lower_bound_ && cursor < stack_upper_;
-  return r;
+
+  uword* CallerFP(uword* fp) const {
+    ASSERT(fp != NULL);
+    return reinterpret_cast<uword*>(*(fp + kSavedCallerFpSlotFromFp));
+  }
+
+  bool ValidFramePointer(uword* fp) const {
+    if (fp == NULL) {
+      return false;
+    }
+    uword cursor = reinterpret_cast<uword>(fp);
+    cursor += sizeof(fp);
+    bool r = cursor >= lower_bound_ && cursor < stack_upper_;
+    return r;
+  }
+
+  Sample* sample_;
+  const uword stack_upper_;
+  const uword original_pc_;
+  const uword original_fp_;
+  const uword original_sp_;
+  uword lower_bound_;
+};
+
+void Profiler::RecordSampleInterruptCallback(
+    const InterruptedThreadState& state,
+    void* data) {
+  Isolate* isolate = reinterpret_cast<Isolate*>(data);
+  if (isolate == NULL) {
+    return;
+  }
+  IsolateProfilerData* profiler_data = isolate->profiler_data();
+  if (profiler_data == NULL) {
+    return;
+  }
+  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+  if (sample_buffer == NULL) {
+    return;
+  }
+  Sample* sample = sample_buffer->ReserveSample();
+  sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
+  uword stack_lower = 0;
+  uword stack_upper = 0;
+  isolate->GetStackBounds(&stack_lower, &stack_upper);
+  if ((stack_lower == 0) || (stack_upper == 0)) {
+    stack_lower = 0;
+    stack_upper = 0;
+  }
+  ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
+                                        state.pc, state.fp, state.sp);
+  stackWalker.walk();
 }
 
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 1e7c527..9fb098a 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -26,6 +26,9 @@
   static void InitOnce();
   static void Shutdown();
 
+  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);
@@ -45,17 +48,6 @@
   static bool initialized_;
   static Monitor* monitor_;
 
-  static intptr_t ProcessSamples(Isolate* isolate,
-                                 ProfilerCodeRegionTable* code_region_table,
-                                 SampleBuffer* sample_buffer);
-
-  static intptr_t ProcessSample(Isolate* isolate,
-                                ProfilerCodeRegionTable* code_region_table,
-                                Sample* sample);
-
-  static void RecordTickInterruptCallback(const InterruptedThreadState& state,
-                                          void* data);
-
   static void RecordSampleInterruptCallback(const InterruptedThreadState& state,
                                             void* data);
 
@@ -81,63 +73,132 @@
 };
 
 
-// Profile sample.
-class Sample {
+class SampleVisitor {
  public:
-  enum SampleType {
-    kIsolateSample,
-  };
+  explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) { }
+  virtual ~SampleVisitor() {}
 
-  static void InitOnce();
+  virtual void VisitSample(Sample* sample) = 0;
 
-  uintptr_t At(intptr_t i) const;
-  void SetAt(intptr_t i, uintptr_t pc);
-  void Init(SampleType type, Isolate* isolate, int64_t timestamp, ThreadId tid);
-  void CopyInto(Sample* dst) const;
-
-  static Sample* Allocate();
-  static intptr_t instance_size() {
-    return instance_size_;
+  intptr_t visited() const {
+    return visited_;
   }
 
-  SampleType type() const {
-    return type_;
+  void IncrementVisited() {
+    visited_++;
   }
 
   Isolate* isolate() const {
     return isolate_;
   }
 
+ private:
+  Isolate* isolate_;
+  intptr_t visited_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor);
+};
+
+// The maximum number of stack frames a sample can hold.
+#define kSampleFramesSize 256
+
+// Each Sample holds a stack trace from an isolate.
+class Sample {
+ public:
+  void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) {
+    timestamp_ = timestamp;
+    tid_ = tid;
+    isolate_ = isolate;
+    for (intptr_t i = 0; i < kSampleFramesSize; i++) {
+      pcs_[i] = 0;
+    }
+  }
+
+  // Isolate sample was taken from.
+  Isolate* isolate() const {
+    return isolate_;
+  }
+
+  // Timestamp sample was taken at.
   int64_t timestamp() const {
     return timestamp_;
   }
 
+  // Get stack trace entry.
+  uword At(intptr_t i) const {
+    ASSERT(i >= 0);
+    ASSERT(i < kSampleFramesSize);
+    return pcs_[i];
+  }
+
+  // Set stack trace entry.
+  void SetAt(intptr_t i, uword pc) {
+    ASSERT(i >= 0);
+    ASSERT(i < kSampleFramesSize);
+    pcs_[i] = pc;
+  }
+
  private:
-  static intptr_t instance_size_;
   int64_t timestamp_;
   ThreadId tid_;
   Isolate* isolate_;
-  SampleType type_;
-  // Note: This class has a size determined at run-time. The pcs_ array
-  // must be the final field.
-  uintptr_t pcs_[0];
-
-  DISALLOW_COPY_AND_ASSIGN(Sample);
+  uword pcs_[kSampleFramesSize];
 };
 
 
-// Ring buffer of samples.
+// Ring buffer of Samples that is (usually) shared by many isolates.
 class SampleBuffer {
  public:
   static const intptr_t kDefaultBufferCapacity = 120000;  // 2 minutes @ 1000hz.
 
-  explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity);
-  ~SampleBuffer();
+  explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity) {
+    samples_ = reinterpret_cast<Sample*>(calloc(capacity, sizeof(*samples_)));
+    capacity_ = capacity;
+    cursor_ = 0;
+  }
+
+  ~SampleBuffer() {
+    if (samples_ != NULL) {
+      free(samples_);
+      samples_ = NULL;
+      cursor_ = 0;
+      capacity_ = 0;
+    }
+  }
 
   intptr_t capacity() const { return capacity_; }
+
   Sample* ReserveSample();
-  void CopySample(intptr_t i, Sample* sample) const;
-  Sample* At(intptr_t idx) const;
+
+  Sample* At(intptr_t idx) const {
+    ASSERT(idx >= 0);
+    ASSERT(idx < capacity_);
+    return &samples_[idx];
+  }
+
+  void VisitSamples(SampleVisitor* visitor) {
+    ASSERT(visitor != NULL);
+    Sample sample;
+    const intptr_t length = capacity();
+    for (intptr_t i = 0; i < length; i++) {
+      // Copy the sample.
+      sample = *At(i);
+      if (sample.isolate() != visitor->isolate()) {
+        // Another isolate.
+        continue;
+      }
+      if (sample.timestamp() == 0) {
+        // Empty.
+        continue;
+      }
+      if (sample.At(0) == 0) {
+        // No frames.
+        continue;
+      }
+      visitor->IncrementVisited();
+      visitor->VisitSample(&sample);
+    }
+  }
 
  private:
   Sample* samples_;
@@ -148,35 +209,6 @@
 };
 
 
-class ProfilerSampleStackWalker : public ValueObject {
- public:
-  ProfilerSampleStackWalker(Sample* sample,
-                            uintptr_t stack_lower,
-                            uintptr_t stack_upper,
-                            uintptr_t pc,
-                            uintptr_t fp,
-                            uintptr_t sp);
-
-  int walk();
-
- private:
-  uword* CallerPC(uword* fp);
-  uword* CallerFP(uword* fp);
-
-  bool ValidInstructionPointer(uword* pc);
-
-  bool ValidFramePointer(uword* fp);
-
-  Sample* sample_;
-  const uintptr_t stack_lower_;
-  const uintptr_t stack_upper_;
-  const uintptr_t original_pc_;
-  const uintptr_t original_fp_;
-  const uintptr_t original_sp_;
-  uintptr_t lower_bound_;
-};
-
-
 }  // namespace dart
 
 #endif  // VM_PROFILER_H_
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index ffa9ab3..63b77d4 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -17,15 +17,13 @@
   static intptr_t IterateCount(const Isolate* isolate,
                                const SampleBuffer& sample_buffer) {
     intptr_t c = 0;
-    Sample* sample = Sample::Allocate();
     for (intptr_t i = 0; i < sample_buffer.capacity(); i++) {
-      sample_buffer.CopySample(i, sample);
+      Sample* sample = sample_buffer.At(i);
       if (sample->isolate() != isolate) {
         continue;
       }
       c++;
     }
-    free(sample);
     return c;
   }
 
@@ -33,15 +31,13 @@
   static intptr_t IterateSumPC(const Isolate* isolate,
                                const SampleBuffer& sample_buffer) {
     intptr_t c = 0;
-    Sample* sample = Sample::Allocate();
     for (intptr_t i = 0; i < sample_buffer.capacity(); i++) {
-      sample_buffer.CopySample(i, sample);
+      Sample* sample = sample_buffer.At(i);
       if (sample->isolate() != isolate) {
         continue;
       }
       c += sample->At(0);
     }
-    free(sample);
     return c;
   }
 };
@@ -53,19 +49,19 @@
   EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
   Sample* s;
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   s->SetAt(0, 2);
   EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   s->SetAt(0, 4);
   EXPECT_EQ(6, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   s->SetAt(0, 6);
   EXPECT_EQ(12, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   s->SetAt(0, 8);
   EXPECT_EQ(18, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
   delete sample_buffer;
@@ -78,16 +74,16 @@
   EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
   Sample* s;
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   EXPECT_EQ(1, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
   s = sample_buffer->ReserveSample();
-  s->Init(Sample::kIsolateSample, i, 0, 0);
+  s->Init(i, 0, 0);
   EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
   delete sample_buffer;
 }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 83e88f4..a3700d6 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1135,6 +1135,7 @@
  protected:
   enum TypeState {
     kAllocated,  // Initial state.
+    kResolved,  // Type class and type arguments resolved.
     kBeingFinalized,  // In the process of being finalized.
     kFinalizedInstantiated,  // Instantiated type ready for use.
     kFinalizedUninstantiated,  // Uninstantiated type ready for use.
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 433bce8..e917e67 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -453,8 +453,7 @@
     *reader->ArrayHandle() ^= reader->ReadObjectImpl();
     type_arguments.set_instantiations(*reader->ArrayHandle());
   } else {
-    // TODO(regis): Change to Object::zero_array() once supported.
-    type_arguments.set_instantiations(Object::empty_array());
+    type_arguments.set_instantiations(Object::zero_array());
   }
 
   // Now set all the type fields.
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 34675b2..cedc6ba 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -28,6 +28,8 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests.");
+
 struct ResourcesEntry {
   const char* path_;
   const char* resource_;
@@ -102,6 +104,45 @@
 };
 
 
+class EmbedderServiceHandler {
+ public:
+  explicit EmbedderServiceHandler(const char* name) : name_(NULL),
+                                                      callback_(NULL),
+                                                      user_data_(NULL),
+                                                      next_(NULL) {
+    ASSERT(name != NULL);
+    name_ = strdup(name);
+  }
+
+  ~EmbedderServiceHandler() {
+    free(name_);
+  }
+
+  const char* name() const { return name_; }
+
+  Dart_ServiceRequestCallback callback() const { return callback_; }
+  void set_callback(Dart_ServiceRequestCallback callback) {
+    callback_ = callback;
+  }
+
+  void* user_data() const { return user_data_; }
+  void set_user_data(void* user_data) {
+    user_data_ = user_data;
+  }
+
+  EmbedderServiceHandler* next() const { return next_; }
+  void set_next(EmbedderServiceHandler* next) {
+    next_ = next;
+  }
+
+ private:
+  char* name_;
+  Dart_ServiceRequestCallback callback_;
+  void* user_data_;
+  EmbedderServiceHandler* next_;
+};
+
+
 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);
@@ -184,10 +225,13 @@
 }
 
 
+EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
+EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
 Isolate* Service::service_isolate_ = NULL;
 Dart_LibraryTagHandler Service::default_handler_ = NULL;
 Dart_Port Service::port_ = ILLEGAL_PORT;
 
+
 static Dart_Port ExtractPort(Dart_Handle receivePort) {
   HANDLESCOPE(Isolate::Current());
   const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
@@ -439,68 +483,6 @@
 static RootMessageHandler FindRootMessageHandler(const char* command);
 
 
-static void PostReply(JSONStream* js) {
-  Dart_Port reply_port = js->reply_port();
-  ASSERT(reply_port != ILLEGAL_PORT);
-  js->set_reply_port(ILLEGAL_PORT);  // Prevent double replies.
-
-  const String& reply = String::Handle(String::New(js->ToCString()));
-  ASSERT(!reply.IsNull());
-
-  uint8_t* data = NULL;
-  MessageWriter writer(&data, &allocator);
-  writer.WriteMessage(reply);
-  PortMap::PostMessage(new Message(reply_port, data,
-                                   writer.BytesWritten(),
-                                   Message::kNormalPriority));
-}
-
-
-static void SetupJSONStream(JSONStream* js, Zone* zone,
-                            const Instance& reply_port,
-                            const GrowableObjectArray& path,
-                            const GrowableObjectArray& option_keys,
-                            const GrowableObjectArray& option_values) {
-  // Setup the reply port.
-  const Object& id_obj = Object::Handle(
-      DartLibraryCalls::PortGetId(reply_port));
-  if (id_obj.IsError()) {
-    Exceptions::PropagateError(Error::Cast(id_obj));
-  }
-  const Integer& id = Integer::Cast(id_obj);
-  Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
-  ASSERT(port != ILLEGAL_PORT);
-  js->set_reply_port(port);
-
-  // Setup JSONStream arguments and options. The arguments and options
-  // are zone allocated and will be freed immediately after handling the
-  // message.
-  const char** arguments = zone->Alloc<const char*>(path.Length());
-  String& string_iterator = String::Handle();
-  for (intptr_t i = 0; i < path.Length(); i++) {
-    string_iterator ^= path.At(i);
-    arguments[i] = zone->MakeCopyOfString(string_iterator.ToCString());
-  }
-  js->SetArguments(arguments, path.Length());
-  if (option_keys.Length() > 0) {
-    const char** option_keys_native =
-        zone->Alloc<const char*>(option_keys.Length());
-    const char** option_values_native =
-        zone->Alloc<const char*>(option_keys.Length());
-    for (intptr_t i = 0; i < option_keys.Length(); i++) {
-      string_iterator ^= option_keys.At(i);
-      option_keys_native[i] =
-          zone->MakeCopyOfString(string_iterator.ToCString());
-      string_iterator ^= option_values.At(i);
-      option_values_native[i] =
-          zone->MakeCopyOfString(string_iterator.ToCString());
-    }
-    js->SetOptions(option_keys_native, option_values_native,
-                  option_keys.Length());
-  }
-}
-
-
 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) {
   JSONObject jsobj(&obj, "message");
   {
@@ -573,27 +555,35 @@
     // Same number of option keys as values.
     ASSERT(option_keys.Length() == option_values.Length());
 
-    String& pathSegment = String::Handle();
+    String& path_segment = String::Handle();
     if (path.Length() > 0) {
-      pathSegment ^= path.At(0);
+      path_segment ^= path.At(0);
     } else {
-      pathSegment ^= Symbols::Empty().raw();
+      path_segment ^= Symbols::Empty().raw();
     }
-    ASSERT(!pathSegment.IsNull());
+    ASSERT(!path_segment.IsNull());
+    const char* path_segment_c = path_segment.ToCString();
 
     IsolateMessageHandler handler =
-        FindIsolateMessageHandler(pathSegment.ToCString());
+        FindIsolateMessageHandler(path_segment_c);
     {
       JSONStream js;
-      SetupJSONStream(&js, zone.GetZone(),
-                      reply_port, path, option_keys, option_values);
+      js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
       if (handler == NULL) {
-        PrintError(&js, "Unrecognized path");
-        PostReply(&js);
+        // Check for an embedder handler.
+        EmbedderServiceHandler* e_handler =
+            FindIsolateEmbedderHandler(path_segment_c);
+        if (e_handler != NULL) {
+          EmbedderHandleMessage(e_handler, &js);
+        } else {
+          PrintError(&js, "Unrecognized path");
+        }
+        js.PostReply();
       } else {
         if (handler(isolate, &js)) {
           // Handler returns true if the reply is ready to be posted.
-          PostReply(&js);
+          // TODO(johnmccutchan): Support asynchronous replies.
+          js.PostReply();
         }
       }
     }
@@ -890,7 +880,8 @@
   // special nulls.
   if (strcmp(arg, "null") == 0 ||
       strcmp(arg, "not-initialized") == 0 ||
-      strcmp(arg, "being-initialized") == 0) {
+      strcmp(arg, "being-initialized") == 0 ||
+      strcmp(arg, "optimized-out") == 0) {
     Object::null_object().PrintToJSONStream(js, false);
     return true;
 
@@ -1057,6 +1048,15 @@
 }
 
 
+static bool HandleCpu(Isolate* isolate, JSONStream* js) {
+  JSONObject jsobj(js);
+  jsobj.AddProperty("type", "CPU");
+  jsobj.AddProperty("targetCPU", CPU::Id());
+  jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware());
+  return true;
+}
+
+
 static bool HandleCode(Isolate* isolate, JSONStream* js) {
   REQUIRE_COLLECTION_ID("code");
   uintptr_t pc;
@@ -1098,6 +1098,7 @@
   { "classes", HandleClasses },
   { "code", HandleCode },
   { "coverage", HandleCoverage },
+  { "cpu", HandleCpu },
   { "debug", HandleDebug },
   { "libraries", HandleLibraries },
   { "objecthistogram", HandleObjectHistogram},
@@ -1117,6 +1118,9 @@
       return entry.handler;
     }
   }
+  if (FLAG_trace_service) {
+    OS::Print("Service has no isolate message handler for <%s>\n", command);
+  }
   return NULL;
 }
 
@@ -1151,23 +1155,35 @@
     // Same number of option keys as values.
     ASSERT(option_keys.Length() == option_values.Length());
 
-    String& pathSegment = String::Handle();
-    pathSegment ^= path.At(0);
-    ASSERT(!pathSegment.IsNull());
+    String& path_segment = String::Handle();
+    if (path.Length() > 0) {
+      path_segment ^= path.At(0);
+    } else {
+      path_segment ^= Symbols::Empty().raw();
+    }
+    ASSERT(!path_segment.IsNull());
+    const char* path_segment_c = path_segment.ToCString();
 
     RootMessageHandler handler =
-        FindRootMessageHandler(pathSegment.ToCString());
+        FindRootMessageHandler(path_segment_c);
     {
       JSONStream js;
-      SetupJSONStream(&js, zone.GetZone(),
-                      reply_port, path, option_keys, option_values);
+      js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
       if (handler == NULL) {
-        PrintError(&js, "Unrecognized path");
-        PostReply(&js);
+        // Check for an embedder handler.
+        EmbedderServiceHandler* e_handler =
+            FindRootEmbedderHandler(path_segment_c);
+        if (e_handler != NULL) {
+          EmbedderHandleMessage(e_handler, &js);
+        } else {
+          PrintError(&js, "Unrecognized path");
+        }
+        js.PostReply();
       } else {
         if (handler(&js)) {
           // Handler returns true if the reply is ready to be posted.
-          PostReply(&js);
+          // TODO(johnmccutchan): Support asynchronous replies.
+          js.PostReply();
         }
       }
     }
@@ -1206,6 +1222,105 @@
       return entry.handler;
     }
   }
+  if (FLAG_trace_service) {
+    OS::Print("Service has no root message handler for <%s>\n", command);
+  }
+  return NULL;
+}
+
+
+void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler,
+                                    JSONStream* js) {
+  ASSERT(handler != NULL);
+  Dart_ServiceRequestCallback callback = handler->callback();
+  ASSERT(callback != NULL);
+  const char* r = NULL;
+  const char* name = js->command();
+  const char** arguments = js->arguments();
+  const char** keys = js->option_keys();
+  const char** values = js->option_values();
+  r = callback(name, arguments, js->num_arguments(), keys, values,
+               js->num_options(), handler->user_data());
+  ASSERT(r != NULL);
+  // TODO(johnmccutchan): Allow for NULL returns?
+  TextBuffer* buffer = js->buffer();
+  buffer->AddString(r);
+  free(const_cast<char*>(r));
+}
+
+
+void Service::RegisterIsolateEmbedderCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  if (name == NULL) {
+    return;
+  }
+  EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(name);
+  if (handler != NULL) {
+    // Update existing handler entry.
+    handler->set_callback(callback);
+    handler->set_user_data(user_data);
+    return;
+  }
+  // Create a new handler.
+  handler = new EmbedderServiceHandler(name);
+  handler->set_callback(callback);
+  handler->set_user_data(user_data);
+
+  // Insert into isolate_service_handler_head_ list.
+  handler->set_next(isolate_service_handler_head_);
+  isolate_service_handler_head_ = handler;
+}
+
+
+EmbedderServiceHandler* Service::FindIsolateEmbedderHandler(
+    const char* name) {
+  EmbedderServiceHandler* current = isolate_service_handler_head_;
+  while (current != NULL) {
+    if (!strcmp(name, current->name())) {
+      return current;
+    }
+    current = current->next();
+  }
+  return NULL;
+}
+
+
+void Service::RegisterRootEmbedderCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  if (name == NULL) {
+    return;
+  }
+  EmbedderServiceHandler* handler = FindRootEmbedderHandler(name);
+  if (handler != NULL) {
+    // Update existing handler entry.
+    handler->set_callback(callback);
+    handler->set_user_data(user_data);
+    return;
+  }
+  // Create a new handler.
+  handler = new EmbedderServiceHandler(name);
+  handler->set_callback(callback);
+  handler->set_user_data(user_data);
+
+  // Insert into root_service_handler_head_ list.
+  handler->set_next(root_service_handler_head_);
+  root_service_handler_head_ = handler;
+}
+
+
+EmbedderServiceHandler* Service::FindRootEmbedderHandler(
+    const char* name) {
+  EmbedderServiceHandler* current = root_service_handler_head_;
+  while (current != NULL) {
+    if (!strcmp(name, current->name())) {
+      return current;
+    }
+    current = current->next();
+  }
   return NULL;
 }
 
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 8806b46..1df8a94 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -11,8 +11,10 @@
 
 namespace dart {
 
+class EmbedderServiceHandler;
 class Instance;
 class Isolate;
+class JSONStream;
 class RawInstance;
 
 class Service : public AllStatic {
@@ -26,8 +28,25 @@
   static Isolate* GetServiceIsolate(void* callback_data);
   static bool SendIsolateStartupMessage();
   static bool SendIsolateShutdownMessage();
- private:
   static bool IsRunning();
+
+  static void RegisterIsolateEmbedderCallback(
+      const char* name,
+      Dart_ServiceRequestCallback callback,
+      void* user_data);
+
+  static void RegisterRootEmbedderCallback(
+      const char* name,
+      Dart_ServiceRequestCallback callback,
+      void* user_data);
+
+ private:
+  static void EmbedderHandleMessage(EmbedderServiceHandler* handler,
+                                    JSONStream* js);
+  static EmbedderServiceHandler* FindIsolateEmbedderHandler(const char* name);
+  static EmbedderServiceHandler* isolate_service_handler_head_;
+  static EmbedderServiceHandler* FindRootEmbedderHandler(const char* name);
+  static EmbedderServiceHandler* root_service_handler_head_;
   static Isolate* service_isolate_;
   static Dart_LibraryTagHandler default_handler_;
   static Dart_Port port_;
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index e89cc65..43dec6b 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -614,4 +614,106 @@
       "[3,0,3,1,5,1,5,1,5,1,6,1,6,1]}", handler.msg());
 }
 
+
+static const char* alpha_callback(
+    const char* name,
+    const char** arguments,
+    intptr_t num_arguments,
+    const char** option_keys,
+    const char** option_values,
+    intptr_t num_options,
+    void* user_data) {
+  return strdup("alpha");
+}
+
+
+static const char* beta_callback(
+    const char* name,
+    const char** arguments,
+    intptr_t num_arguments,
+    const char** option_keys,
+    const char** option_values,
+    intptr_t num_options,
+    void* user_data) {
+  return strdup("beta");
+}
+
+
+TEST_CASE(Service_EmbedderRootHandler) {
+  const char* kScript =
+    "var port;\n"  // Set to our mock port by C++.
+    "\n"
+    "var x = 7;\n"
+    "main() {\n"
+    "  x = x * x;\n"
+    "  x = x / 13;\n"
+    "}";
+
+  Dart_RegisterRootServiceRequestCallback("alpha", alpha_callback, NULL);
+  Dart_RegisterRootServiceRequestCallback("beta", beta_callback, NULL);
+
+  Isolate* isolate = Isolate::Current();
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  // Build a mock message handler and wrap it in a dart port.
+  ServiceTestMessageHandler handler;
+  Dart_Port port_id = PortMap::CreatePort(&handler);
+  Dart_Handle port =
+      Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
+  EXPECT_VALID(port);
+  EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
+
+
+  Instance& service_msg = Instance::Handle();
+  service_msg = Eval(lib, "[port, ['alpha'], [], []]");
+  Service::HandleRootMessage(service_msg);
+  handler.HandleNextMessage();
+  EXPECT_STREQ("alpha", handler.msg());
+  service_msg = Eval(lib, "[port, ['beta'], [], []]");
+  Service::HandleRootMessage(service_msg);
+  handler.HandleNextMessage();
+  EXPECT_STREQ("beta", handler.msg());
+}
+
+TEST_CASE(Service_EmbedderIsolateHandler) {
+  const char* kScript =
+    "var port;\n"  // Set to our mock port by C++.
+    "\n"
+    "var x = 7;\n"
+    "main() {\n"
+    "  x = x * x;\n"
+    "  x = x / 13;\n"
+    "}";
+
+  Dart_RegisterIsolateServiceRequestCallback("alpha", alpha_callback, NULL);
+  Dart_RegisterIsolateServiceRequestCallback("beta", beta_callback, NULL);
+
+  Isolate* isolate = Isolate::Current();
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  // Build a mock message handler and wrap it in a dart port.
+  ServiceTestMessageHandler handler;
+  Dart_Port port_id = PortMap::CreatePort(&handler);
+  Dart_Handle port =
+      Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
+  EXPECT_VALID(port);
+  EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
+
+  Instance& service_msg = Instance::Handle();
+  service_msg = Eval(lib, "[port, ['alpha'], [], []]");
+  Service::HandleIsolateMessage(isolate, service_msg);
+  handler.HandleNextMessage();
+  EXPECT_STREQ("alpha", handler.msg());
+  service_msg = Eval(lib, "[port, ['beta'], [], []]");
+  Service::HandleIsolateMessage(isolate, service_msg);
+  handler.HandleNextMessage();
+  EXPECT_STREQ("beta", handler.msg());
+}
+
 }  // namespace dart
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 0e22187..1ff3848 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -16,6 +16,7 @@
 
 #include "vm/assembler.h"
 #include "vm/constants_arm.h"
+#include "vm/cpu.h"
 #include "vm/disassembler.h"
 #include "vm/native_arguments.h"
 #include "vm/stack_frame.h"
@@ -2303,7 +2304,7 @@
 
 
 void Simulator::DoDivision(Instr* instr) {
-  ASSERT(CPUFeatures::integer_division_supported());
+  ASSERT(TargetCPUFeatures::integer_division_supported());
   Register rd = instr->DivRdField();
   Register rn = instr->DivRnField();
   Register rm = instr->DivRmField();
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 7499d0f..dec7c90 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -117,7 +117,7 @@
   ASSERT(raw_memory != NULL);
   ASSERT(kHeaderSize == sizeof(Snapshot));
   ASSERT(kLengthIndex == length_offset());
-  ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset());
+  ASSERT((kSnapshotFlagIndex * sizeof(int64_t)) == kind_offset());
   ASSERT((kHeapObjectTag & kInlined));
   // The kWatchedBit and kMarkBit are only set during GC operations. This
   // allows the two low bits in the header to be used for snapshotting.
@@ -759,6 +759,9 @@
   if (object_id == kEmptyArrayObject) {
     return Object::empty_array().raw();
   }
+  if (object_id == kZeroArrayObject) {
+    return Object::zero_array().raw();
+  }
   if (object_id == kDynamicType) {
     return Object::dynamic_type();
   }
@@ -958,6 +961,12 @@
     return;
   }
 
+  // Check if it is a singleton zero array object.
+  if (rawobj == Object::zero_array().raw()) {
+    WriteVMIsolateObject(kZeroArrayObject);
+    return;
+  }
+
   // Check if it is a singleton dyanmic Type object.
   if (rawobj == Object::dynamic_type()) {
     WriteVMIsolateObject(kDynamicType);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 3f88f74..1530b65 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -129,7 +129,7 @@
     kMessage,   // A partial snapshot used only for isolate messaging.
   };
 
-  static const int kHeaderSize = 2 * sizeof(int32_t);
+  static const int kHeaderSize = 2 * sizeof(int64_t);
   static const int kLengthIndex = 0;
   static const int kSnapshotFlagIndex = 1;
 
@@ -137,7 +137,7 @@
 
   // Getters.
   const uint8_t* content() const { return content_; }
-  int32_t length() const { return length_; }
+  int64_t length() const { return length_; }
   Kind kind() const { return static_cast<Kind>(kind_); }
 
   bool IsMessageSnapshot() const { return kind_ == kMessage; }
@@ -153,8 +153,8 @@
  private:
   Snapshot() : length_(0), kind_(kFull) {}
 
-  int32_t length_;  // Stream length.
-  int32_t kind_;  // Kind of snapshot.
+  int64_t length_;  // Stream length.
+  int64_t kind_;  // Kind of snapshot.
   uint8_t content_[];  // Stream content.
 
   DISALLOW_COPY_AND_ASSIGN(Snapshot);
@@ -436,7 +436,7 @@
   }
 
   void FillHeader(Snapshot::Kind kind) {
-    int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer());
+    int64_t* data = reinterpret_cast<int64_t*>(stream_.buffer());
     data[Snapshot::kLengthIndex] = stream_.bytes_written();
     data[Snapshot::kSnapshotFlagIndex] = kind;
   }
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
index 963a83b..ad01aa0 100644
--- a/runtime/vm/snapshot_ids.h
+++ b/runtime/vm/snapshot_ids.h
@@ -14,6 +14,7 @@
   kNullObject = 0,
   kSentinelObject,
   kEmptyArrayObject,
+  kZeroArrayObject,
   kTrueValue,
   kFalseValue,
   kClassIdsOffset = kFalseValue,
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 76b4370..7c1e5e7 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -365,6 +365,7 @@
 
 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc)
   : index_(0),
+    num_materializations_(0),
     code_(Code::Handle(code.raw())),
     deopt_info_(DeoptInfo::Handle()),
     function_(Function::Handle()),
@@ -386,6 +387,7 @@
     const Array& deopt_table = Array::Handle(code_.deopt_info_array());
     ASSERT(!deopt_table.IsNull());
     deopt_info_.ToInstructions(deopt_table, &deopt_instructions_);
+    num_materializations_ = deopt_info_.NumMaterializations();
     object_table_ = code_.object_table();
     Advance();
   }
@@ -426,7 +428,7 @@
        index++) {
     DeoptInstr* deopt_instr = deopt_instructions_[index];
     if (deopt_instr->kind() == DeoptInstr::kCallerFp) {
-      return index;
+      return (index - num_materializations_);
     }
   }
   UNREACHABLE();
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 6c7b995..8de42f4 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -286,6 +286,7 @@
   void SetDone() { index_ = -1; }
 
   intptr_t index_;
+  intptr_t num_materializations_;
   Code& code_;
   DeoptInfo& deopt_info_;
   Function& function_;
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index c64f1d7..2b7e061 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1097,8 +1097,7 @@
 // Called for inline allocation of objects.
 // Input parameters:
 //   LR : return address.
-//   SP + 4 : type arguments object (only if class is parameterized).
-//   SP + 0 : type arguments of instantiator (only if class is parameterized).
+//   SP + 0 : type arguments object (only if class is parameterized).
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
   // The generated code is different if the class is parameterized.
@@ -1111,46 +1110,15 @@
   const int kInlineInstanceSize = 12;
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
-  Label slow_case_with_type_arguments;
+  if (is_cls_parameterized) {
+    __ ldr(R1, Address(SP, 0));
+    // R1: instantiated type arguments.
+  }
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
-    Label slow_case_reload_type_arguments;
-    if (is_cls_parameterized) {
-      // Instantiation of the type arguments vector is only required if an
-      // instantiator is provided (not kNoInstantiator, but may be null).
-      __ ldm(IA, SP, (1 << R0) | (1 << R1));
-      // R1: type arguments, instantiated or not.
-      // R0: instantiator type arguments or kNoInstantiator.
-      Label type_arguments_ready;
-      __ CompareImmediate(R0, Smi::RawValue(StubCode::kNoInstantiator));
-      __ b(&type_arguments_ready, EQ);
-      // Lookup instantiator R0 in instantiations array of type arguments R1
-      // and, if found, use cached instantiated type arguments.
-      __ ldr(R2, FieldAddress(R1, TypeArguments::instantiations_offset()));
-      __ ldr(R3, FieldAddress(R2, Array::length_offset()));
-      __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag);
-      __ add(R3, R2, ShifterOperand(R3, LSL, 1));  // R3 is Smi.
-      Label loop, found;
-      __ Bind(&loop);
-      __ cmp(R2, ShifterOperand(R3));
-      __ b(&slow_case_reload_type_arguments, CS);  // Unsigned higher or equal.
-      __ ldr(R1, Address(R2, 0 * kWordSize));  // Cached instantiator.
-      __ cmp(R1, ShifterOperand(R0));
-      __ b(&found, EQ);
-      __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator));
-      __ b(&slow_case_reload_type_arguments, EQ);
-      __ AddImmediate(R2, 2 * kWordSize);
-      __ b(&loop);
-      __ Bind(&found);
-      __ ldr(R1, Address(R2, 1 * kWordSize));  // Cached instantiated args.
-      __ LoadImmediate(R0, Smi::RawValue(StubCode::kNoInstantiator));
-      __ Bind(&type_arguments_ready);
-      // R1: instantiated type arguments.
-      // R0: kNoInstantiator.
-    }
+    Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     // R1: instantiated type arguments (if is_cls_parameterized).
-    // R0: kNoInstantiator (if is_cls_parameterized).
     Heap* heap = Isolate::Current()->heap();
     __ LoadImmediate(R5, heap->TopAddress());
     __ ldr(R2, Address(R5, 0));
@@ -1162,9 +1130,9 @@
     __ ldr(IP, Address(IP, 0));
     __ cmp(R3, ShifterOperand(IP));
     if (FLAG_use_slow_path) {
-      __ b(&slow_case_with_type_arguments);
+      __ b(&slow_case);
     } else {
-      __ b(&slow_case_with_type_arguments, CS);  // Unsigned higher or equal.
+      __ b(&slow_case, CS);  // Unsigned higher or equal.
     }
     __ str(R3, Address(R5, 0));
     __ UpdateAllocationStats(cls.id(), R5);
@@ -1225,15 +1193,10 @@
     // R0: new object.
     __ Ret();
 
-    __ Bind(&slow_case_reload_type_arguments);
+    __ Bind(&slow_case);
   }
-  if (is_cls_parameterized) {
-    __ ldm(IA, SP, (1 << R0) | (1 << R1));
-  }
-  __ Bind(&slow_case_with_type_arguments);
   // If is_cls_parameterized:
-  // R1: new object type arguments (instantiated or not).
-  // R0: instantiator type arguments or kNoInstantiator.
+  // R1: new object type arguments.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame(true);  // Uses pool pointer to pass cls to runtime.
@@ -1241,15 +1204,14 @@
   __ Push(R2);  // Setup space on stack for return value.
   __ PushObject(cls);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
-    // Push type arguments of object to be allocated and of instantiator.
-    __ PushList((1 << R0) | (1 << R1));
+    // Push type arguments.
+    __ Push(R1);
   } else {
-    // Push null type arguments and kNoInstantiator.
-    __ LoadImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator));
-    __ PushList((1 << R1) | (1 << R2));
+    // Push null type arguments.
+    __ Push(R2);
   }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 3);  // Allocate object.
-  __ Drop(3);  // Pop arguments.
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
+  __ Drop(2);  // Pop arguments.
   __ Pop(R0);  // Pop result (newly allocated object).
   // R0: new object
   // Restore the frame pointer.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index a40851a4..a6f3864 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1102,14 +1102,12 @@
 
 // Called for inline allocation of objects.
 // Input parameters:
-//   ESP + 8 : type arguments object (only if class is parameterized).
-//   ESP + 4 : type arguments of instantiator (only if class is parameterized).
+//   ESP + 4 : type arguments object (only if class is parameterized).
 //   ESP : points to return address.
 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
-  const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
-  const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
+  const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   // The generated code is different if the class is parameterized.
@@ -1122,45 +1120,15 @@
   const int kInlineInstanceSize = 12;  // In words.
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
-  Label slow_case_with_type_arguments;
+  if (is_cls_parameterized) {
+    __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
+    // EDX: instantiated type arguments.
+  }
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
-    Label slow_case_reload_type_arguments;
-    if (is_cls_parameterized) {
-      // Instantiation of the type arguments vector is only required if an
-      // instantiator is provided (not kNoInstantiator, but may be null).
-      __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
-      __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset));
-      Label type_arguments_ready;
-      __ cmpl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ j(EQUAL, &type_arguments_ready, Assembler::kNearJump);
-      // Lookup instantiator EDI in instantiations array of type arguments EDX
-      // and, if found, use cached instantiated type arguments.
-      __ movl(EAX, FieldAddress(EDX, TypeArguments::instantiations_offset()));
-      __ movl(EBX, FieldAddress(EAX, Array::length_offset()));
-      __ leal(EAX, FieldAddress(EAX, Array::data_offset()));
-      __ leal(EBX, Address(EAX, EBX, TIMES_2, 0));  // EBX is smi.
-      Label loop, found;
-      __ Bind(&loop);
-      __ cmpl(EAX, EBX);
-      __ j(ABOVE_EQUAL, &slow_case_reload_type_arguments);
-      __ movl(EDX, Address(EAX, 0 * kWordSize));  // Cached instantiator.
-      __ cmpl(EDX, EDI);
-      __ j(EQUAL, &found, Assembler::kNearJump);
-      __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ j(EQUAL, &slow_case_reload_type_arguments);
-      __ addl(EAX, Immediate(2 * kWordSize));
-      __ jmp(&loop, Assembler::kNearJump);
-      __ Bind(&found);
-      __ movl(EDX, Address(EAX, 1 * kWordSize));  // Cached instantiated args.
-      __ movl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ Bind(&type_arguments_ready);
-      // EDX: instantiated type arguments.
-      // EDI: kNoInstantiator.
-    }
+    Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     // EDX: instantiated type arguments (if is_cls_parameterized).
-    // EDI: kNoInstantiator (if is_cls_parameterized).
     Heap* heap = Isolate::Current()->heap();
     __ movl(EAX, Address::Absolute(heap->TopAddress()));
     __ leal(EBX, Address(EAX, instance_size));
@@ -1169,9 +1137,9 @@
     // EBX: potential next object start.
     __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
     if (FLAG_use_slow_path) {
-      __ jmp(&slow_case_with_type_arguments);
+      __ jmp(&slow_case);
     } else {
-      __ j(ABOVE_EQUAL, &slow_case_with_type_arguments);
+      __ j(ABOVE_EQUAL, &slow_case);
     }
     __ movl(Address::Absolute(heap->TopAddress()), EBX);
     __ UpdateAllocationStats(cls.id(), ECX);
@@ -1229,16 +1197,10 @@
     __ addl(EAX, Immediate(kHeapObjectTag));
     __ ret();
 
-    __ Bind(&slow_case_reload_type_arguments);
+    __ Bind(&slow_case);
   }
-  if (is_cls_parameterized) {
-    __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
-    __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset));
-  }
-  __ Bind(&slow_case_with_type_arguments);
   // If is_cls_parameterized:
-  // EDX: new object type arguments (instantiated or not).
-  // EDI: instantiator type arguments or kNoInstantiator.
+  // EDX: new object type arguments.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
@@ -1246,13 +1208,10 @@
   __ PushObject(cls);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
     __ pushl(EDX);  // Push type arguments of object to be allocated.
-    __ pushl(EDI);  // Push type arguments of instantiator.
   } else {
     __ pushl(raw_null);  // Push null type arguments.
-    __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
   }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 3);  // Allocate object.
-  __ popl(EAX);  // Pop argument (instantiator).
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
   __ popl(EAX);  // Pop argument (type arguments of object).
   __ popl(EAX);  // Pop argument (class of object).
   __ popl(EAX);  // Pop result (newly allocated object).
@@ -1263,6 +1222,9 @@
 }
 
 
+// TODO(regis): This stub is not called anymore to allocate regular closures,
+// but only implicit instance closures. Simplify.
+
 // Called for inline allocation of closures.
 // Input parameters:
 //   ESP + 8 : receiver (null if not an implicit instance closure).
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 45b8144..5ac384b 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1287,8 +1287,7 @@
 // Called for inline allocation of objects.
 // Input parameters:
 //   RA : return address.
-//   SP + 4 : type arguments object (only if class is parameterized).
-//   SP + 0 : type arguments of instantiator (only if class is parameterized).
+//   SP + 0 : type arguments object (only if class is parameterized).
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
   __ TraceSimMsg("AllocationStubForClass");
@@ -1302,46 +1301,15 @@
   const int kInlineInstanceSize = 12;
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
-  Label slow_case_with_type_arguments;
+  if (is_cls_parameterized) {
+    __ lw(T1, Address(SP, 0 * kWordSize));
+    // T1: type arguments.
+  }
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
-    Label slow_case_reload_type_arguments;
-    if (is_cls_parameterized) {
-      // Instantiation of the type arguments vector is only required if an
-      // instantiator is provided (not kNoInstantiator, but may be null).
-      __ lw(T1, Address(SP, 1 * kWordSize));
-      __ lw(T0, Address(SP, 0 * kWordSize));
-      // R1: type arguments, instantiated or not.
-      // R0: instantiator type arguments or kNoInstantiator.
-      Label type_arguments_ready;
-      __ BranchEqual(T0, Smi::RawValue(StubCode::kNoInstantiator),
-                     &type_arguments_ready);
-      // Lookup instantiator EDI in instantiations array of type arguments EDX
-      // and, if found, use cached instantiated type arguments.
-      __ lw(T2, FieldAddress(T1, TypeArguments::instantiations_offset()));
-      __ lw(T3, FieldAddress(T2, Array::length_offset()));
-      __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag);
-      __ sll(TMP, T3, 1);  // T3 is Smi.
-      __ addu(T3, T2, TMP);
-      Label loop, found;
-      __ Bind(&loop);
-      __ BranchUnsignedGreaterEqual(T2, T3, &slow_case_reload_type_arguments);
-      __ lw(T1, Address(T2, 0 * kWordSize));  // Cached instantiator.
-      __ beq(T1, T0, &found);
-      __ BranchEqual(T1, Smi::RawValue(StubCode::kNoInstantiator),
-                     &slow_case_reload_type_arguments);
-      __ b(&loop);
-      __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize));
-      __ Bind(&found);
-      __ lw(T1, Address(T2, 1 * kWordSize));  // Cached instantiated args.
-      __ LoadImmediate(T0, Smi::RawValue(StubCode::kNoInstantiator));
-      __ Bind(&type_arguments_ready);
-      // T0: instantiated type arguments.
-      // T1: kNoInstantiator.
-    }
+    Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
-    // T0: instantiated type arguments (if is_cls_parameterized).
-    // T1: kNoInstantiator (if is_cls_parameterized).
+    // T1: instantiated type arguments (if is_cls_parameterized).
     Heap* heap = Isolate::Current()->heap();
     __ LoadImmediate(T5, heap->TopAddress());
     __ lw(T2, Address(T5));
@@ -1353,10 +1321,9 @@
     __ LoadImmediate(TMP, heap->EndAddress());
     __ lw(CMPRES1, Address(TMP));
     if (FLAG_use_slow_path) {
-      __ b(&slow_case_with_type_arguments);
+      __ b(&slow_case);
     } else {
-      __ BranchUnsignedGreaterEqual(T3, CMPRES1,
-                                    &slow_case_with_type_arguments);
+      __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
     }
     // Successfully allocated the object(s), now update top to point to
     // next object start and initialize the object.
@@ -1405,7 +1372,7 @@
       __ Bind(&loop_exit);
     }
     if (is_cls_parameterized) {
-      // R1: new object type arguments.
+      // T1: new object type arguments.
       // Set the type arguments in the new object.
       __ sw(T1, Address(T2, cls.type_arguments_field_offset()));
     }
@@ -1414,42 +1381,33 @@
     __ Ret();
     __ delay_slot()->addiu(V0, T2, Immediate(kHeapObjectTag));
 
-    __ Bind(&slow_case_reload_type_arguments);
+    __ Bind(&slow_case);
   }
-  if (is_cls_parameterized) {
-    __ lw(T1, Address(SP, 1 * kWordSize));
-    __ lw(T0, Address(SP, 0 * kWordSize));
-  }
-  __ Bind(&slow_case_with_type_arguments);
   // If is_cls_parameterized:
   // T1: new object type arguments (instantiated or not).
-  // T0: instantiator type arguments or kNoInstantiator.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame(true);  // Uses pool pointer to pass cls to runtime.
   __ LoadObject(TMP, cls);
 
-  __ addiu(SP, SP, Immediate(-4 * kWordSize));
+  __ addiu(SP, SP, Immediate(-3 * kWordSize));
   // Space on stack for return value.
   __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null()));
-  __ sw(T7, Address(SP, 3 * kWordSize));
-  __ sw(TMP, Address(SP, 2 * kWordSize));  // Class of object to be allocated.
+  __ sw(T7, Address(SP, 2 * kWordSize));
+  __ sw(TMP, Address(SP, 1 * kWordSize));  // Class of object to be allocated.
 
   if (is_cls_parameterized) {
     // Push type arguments of object to be allocated and of instantiator.
-    __ sw(T1, Address(SP, 1 * kWordSize));
-    __ sw(T0, Address(SP, 0 * kWordSize));
-  } else {
-    // Push null type arguments and kNoInstantiator.
-    __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator));
-    __ sw(T7, Address(SP, 1 * kWordSize));
     __ sw(T1, Address(SP, 0 * kWordSize));
+  } else {
+    // Push null type arguments.
+    __ sw(T7, Address(SP, 0 * kWordSize));
   }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 3);  // Allocate object.
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
   __ TraceSimMsg("AllocationStubForClass return");
   // Pop result (newly allocated object).
-  __ lw(V0, Address(SP, 3 * kWordSize));
-  __ addiu(SP, SP, Immediate(4 * kWordSize));  // Pop arguments.
+  __ lw(V0, Address(SP, 2 * kWordSize));
+  __ addiu(SP, SP, Immediate(3 * kWordSize));  // Pop arguments.
   // V0: new object
   // Restore the frame pointer and return.
   __ LeaveStubFrameAndReturn(RA);
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 5066097..efdcc4f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1097,13 +1097,11 @@
 
 // Called for inline allocation of objects.
 // Input parameters:
-//   RSP + 16 : type arguments object (only if class is parameterized).
-//   RSP + 8 : type arguments of instantiator (only if class is parameterized).
+//   RSP + 8 : type arguments object (only if class is parameterized).
 //   RSP : points to return address.
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
-  const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
-  const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
+  const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
   ASSERT(!is_cls_parameterized ||
@@ -1115,45 +1113,15 @@
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
   __ LoadObject(R12, Object::null_object(), PP);
-  Label slow_case_with_type_arguments;
+  if (is_cls_parameterized) {
+    __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
+    // RDX: instantiated type arguments.
+  }
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
-    Label slow_case_reload_type_arguments;
-    if (is_cls_parameterized) {
-      // Instantiation of the type arguments vector is only required if an
-      // instantiator is provided (not kNoInstantiator, but may be null).
-      __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
-      __ movq(RDI, Address(RSP, kInstantiatorTypeArgumentsOffset));
-      Label type_arguments_ready;
-      __ cmpq(RDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ j(EQUAL, &type_arguments_ready, Assembler::kNearJump);
-      // Lookup instantiator RDI in instantiations array of type arguments RDX
-      // and, if found, use cached instantiated type arguments.
-      __ movq(RAX, FieldAddress(RDX, TypeArguments::instantiations_offset()));
-      __ movq(RBX, FieldAddress(RAX, Array::length_offset()));
-      __ leaq(RAX, FieldAddress(RAX, Array::data_offset()));
-      __ leaq(RBX, Address(RAX, RBX, TIMES_4, 0));  // RBX is smi.
-      Label loop, found;
-      __ Bind(&loop);
-      __ cmpq(RAX, RBX);
-      __ j(ABOVE_EQUAL, &slow_case_reload_type_arguments);
-      __ movq(RDX, Address(RAX, 0 * kWordSize));  // Cached instantiator.
-      __ cmpq(RDX, RDI);
-      __ j(EQUAL, &found, Assembler::kNearJump);
-      __ cmpq(RDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ j(EQUAL, &slow_case_reload_type_arguments);
-      __ addq(RAX, Immediate(2 * kWordSize));
-      __ jmp(&loop, Assembler::kNearJump);
-      __ Bind(&found);
-      __ movq(RDX, Address(RAX, 1 * kWordSize));  // Cached instantiated args.
-      __ movq(RDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-      __ Bind(&type_arguments_ready);
-      // RDX: instantiated type arguments.
-      // RDI: kNoInstantiator.
-    }
+    Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     // RDX: instantiated type arguments (if is_cls_parameterized).
-    // RDI: kNoInstantiator (if is_cls_parameterized).
     Heap* heap = Isolate::Current()->heap();
     __ movq(RCX, Immediate(heap->TopAddress()));
     __ movq(RAX, Address(RCX, 0));
@@ -1165,9 +1133,9 @@
     __ movq(R13, Immediate(heap->EndAddress()));
     __ cmpq(RBX, Address(R13, 0));
     if (FLAG_use_slow_path) {
-      __ jmp(&slow_case_with_type_arguments);
+      __ jmp(&slow_case);
     } else {
-      __ j(ABOVE_EQUAL, &slow_case_with_type_arguments);
+      __ j(ABOVE_EQUAL, &slow_case);
     }
     __ movq(Address(RCX, 0), RBX);
     __ UpdateAllocationStats(cls.id());
@@ -1223,29 +1191,20 @@
     __ addq(RAX, Immediate(kHeapObjectTag));
     __ ret();
 
-    __ Bind(&slow_case_reload_type_arguments);
+    __ Bind(&slow_case);
   }
-  if (is_cls_parameterized) {
-    __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
-    __ movq(RDI, Address(RSP, kInstantiatorTypeArgumentsOffset));
-  }
-  __ Bind(&slow_case_with_type_arguments);
   // If is_cls_parameterized:
-  // RDX: new object type arguments (instantiated or not).
-  // RDI: instantiator type arguments or kNoInstantiator.
+  // RDX: new object type arguments.
   // Create a stub frame.
   __ EnterStubFrame(true);  // Uses PP to access class object.
   __ pushq(R12);  // Setup space on stack for return value.
   __ PushObject(cls, PP);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
     __ pushq(RDX);  // Push type arguments of object to be allocated.
-    __ pushq(RDI);  // Push type arguments of instantiator.
   } else {
     __ pushq(R12);  // Push null type arguments.
-    __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
   }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 3);  // Allocate object.
-  __ popq(RAX);  // Pop argument (instantiator).
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
   __ popq(RAX);  // Pop argument (type arguments of object).
   __ popq(RAX);  // Pop argument (class of object).
   __ popq(RAX);  // Pop result (newly allocated object).
diff --git a/runtime/vm/unicode.h b/runtime/vm/unicode.h
index 3a9b862..fd7649c 100644
--- a/runtime/vm/unicode.h
+++ b/runtime/vm/unicode.h
@@ -29,7 +29,7 @@
   }
 
   // Returns true if the code point value is above Plane 17.
-  static bool IsOutOfRange(int32_t code_point) {
+  static bool IsOutOfRange(intptr_t code_point) {
     return (code_point < 0) || (code_point > kMaxCodePoint);
   }
 };
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 660cbe4..65cd91c 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -100,6 +100,14 @@
     'cpu_mips.cc',
     'cpu_test.cc',
     'cpu_x64.cc',
+    'cpuid.h',
+    'cpuid.cc',
+    'cpuinfo.h',
+    'cpuinfo_android.cc',
+    'cpuinfo_linux.cc',
+    'cpuinfo_macos.cc',
+    'cpuinfo_test.cc',
+    'cpuinfo_win.cc',
     'custom_isolate_test.cc',
     'dart.cc',
     'dart.h',
@@ -278,6 +286,8 @@
     'port.cc',
     'port.h',
     'port_test.cc',
+    'proccpuinfo.h',
+    'proccpuinfo.cc',
     'profiler.cc',
     'profiler.h',
     'profiler_test.cc',
diff --git a/sdk/bin/dartdoc b/sdk/bin/dartdoc
deleted file mode 100755
index 45ba512..0000000
--- a/sdk/bin/dartdoc
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-# 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.
-
-function follow_links() {
-  file="$1"
-  while [ -h "$file" ]; do
-    # On Mac OS, readlink -f doesn't work.
-    file="$(readlink "$file")"
-  done
-  echo "$file"
-}
-
-# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
-PROG_NAME="$(follow_links "$BASH_SOURCE")"
-
-# Handle the case where dart-sdk/bin has been symlinked to.
-BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-
-unset COLORS
-if test -t 1; then
-  # Stdout is a terminal.
-  if test 8 -le `tput colors`; then
-    # Stdout has at least 8 colors, so enable colors.
-    COLORS="--enable-diagnostic-colors"
-  fi
-fi
-
-unset SNAPSHOT
-
-SNAPSHOT="$BIN_DIR/snapshots/utils_wrapper.dart.snapshot"
-
-if test -f $SNAPSHOT; then
-  # TODO(ahe): Remove the following line when we are relatively sure it works.
-  echo Using snapshot $SNAPSHOT 1>&2
-  exec "$BIN_DIR"/dart --heap_growth_rate=32 \
-      "--package-root=$BIN_DIR/../packages/" $SNAPSHOT dartdoc $COLORS \
-      "--package-root=$BIN_DIR/../packages/" "--library-root=$BIN_DIR/.." "$@"
-else
-  exec "$BIN_DIR"/dart --heap_growth_rate=32 \
-      "--package-root=$BIN_DIR/../packages/" \
-      "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart" $COLORS "$@"
-fi
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
deleted file mode 100644
index c62fb54..0000000
--- a/sdk/bin/dartdoc.bat
+++ /dev/null
@@ -1,49 +0,0 @@
-@echo off
-REM Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-REM for details. All rights reserved. Use of this source code is governed by a
-REM BSD-style license that can be found in the LICENSE file.
-
-setlocal
-rem Handle the case where dart-sdk/bin has been symlinked to.
-set DIR_NAME_WITH_SLASH=%~dp0
-set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
-call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
-rem Get rid of surrounding quotes.
-for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
-
-rem Get absolute full name for SDK_DIR.
-for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
-
-rem Remove trailing backslash if there is one
-IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
-
-set DARTDOC=%SDK_DIR%\lib\_internal\dartdoc\bin\dartdoc.dart
-set DART=%BIN_DIR%\dart
-set SNAPSHOT=%BIN_DIR%\snapshots\utils_wrapper.dart.snapshot
-
-if not defined DART_CONFIGURATION set DART_CONFIGURATION=ReleaseIA32
-
-set BUILD_DIR=%SDK_DIR%\..\build\%DART_CONFIGURATION%
-if exist "%SNAPSHOT%" (
-  "%DART%" "%SNAPSHOT%" "dartdoc" "--library-root=%SDK_DIR%" %*
-) else (
-  "%BUILD_DIR%\dart-sdk\bin\dart" "--package-root=%BUILD_DIR%\packages" "%DARTDOC%" %*
-)
-
-endlocal
-
-exit /b %errorlevel%
-
-:follow_links
-setlocal
-for %%i in (%1) do set result=%%~fi
-set current=
-for /f "tokens=2 delims=[]" %%i in ('dir /a:l ^"%~dp1^" 2^>nul ^
-                                     ^| find ">     %~n1 ["') do (
-  set current=%%i
-)
-if not "%current%"=="" call :follow_links "%current%", result
-endlocal & set %~2=%result%
-goto :eof
-
-:end
diff --git a/sdk/bin/pub b/sdk/bin/pub
index 42f84fc..100a15b 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -25,10 +25,23 @@
 
 SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
 
+unset VM_OPTIONS
+declare -a VM_OPTIONS
+
+# Give the VM extra memory for dart2js.
+# TODO(rnystrom): Remove when #8355 is fixed.
+VM_OPTIONS+=("--old_gen_heap_size=1024")
+
+# Allow extra VM options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
 if test -f "$SNAPSHOT"; then
   # We are running the snapshot in the built SDK.
   DART="$BIN_DIR/dart"
-  exec "$DART" "$SNAPSHOT" "$@"
+  exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
 else
   # We are running pub from source in the development repo.
   if [ -z "$DART_CONFIGURATION" ];
@@ -50,5 +63,5 @@
 
   PUB="$SDK_DIR/lib/_internal/pub/bin/pub.dart"
 
-  exec "$DART" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
+  exec "$DART" "${VM_OPTIONS[@]}" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
 fi
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 9294231..4951d50 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -23,11 +23,17 @@
 set BUILD_DIR=%SDK_DIR%\..\build\ReleaseIA32
 set PACKAGES_DIR=%BUILD_DIR%\packages
 set DART_IN_BUILT_SDK=%BUILD_DIR%\dart-sdk\bin\dart
+set VM_OPTIONS=
+
+rem Give the VM extra memory for dart2js.
+rem # TODO(rnystrom): Remove when #8355 is fixed.
+rem See comments regarding options below in dart2js shell script.
+set VM_OPTIONS=%VM_OPTIONS% --old_gen_heap_size=1024
 
 if exist "%SNAPSHOT%" (
-  "%DART%" "%SNAPSHOT%" %*
+  "%DART%" %VM_OPTIONS% "%SNAPSHOT%" %*
 ) else (
-  "%DART_IN_BUILT_SDK%" --package-root="%PACKAGES_DIR%" "%PUB%" %*
+  "%DART_IN_BUILT_SDK%" %VM_OPTIONS% --package-root="%PACKAGES_DIR%" "%PUB%" %*
 )
 
 endlocal
@@ -46,4 +52,4 @@
 endlocal & set %~2=%result%
 goto :eof
 
-:end
+:end
\ No newline at end of file
diff --git a/sdk/bin/pub_developer b/sdk/bin/pub_developer
index 287bb7d..1524a4e 100755
--- a/sdk/bin/pub_developer
+++ b/sdk/bin/pub_developer
@@ -25,10 +25,25 @@
 
 SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
 
+unset VM_OPTIONS
+declare -a VM_OPTIONS
+
+# Give the VM extra memory for dart2js.
+# TODO(rnystrom): Remove when #8355 is fixed.
+VM_OPTIONS+=("--old_gen_heap_size=1024")
+
+# Allow extra VM options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+VM_OPTIONS+=("--checked")
+
 if test -f "$SNAPSHOT"; then
   # We are running the snapshot in the built SDK.
   DART="$BIN_DIR/dart"
-  exec "$DART" --checked "$SNAPSHOT" "$@"
+  exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
 else
   # We are running pub from source in the development repo.
   if [ -z "$DART_CONFIGURATION" ];
@@ -50,5 +65,5 @@
 
   PUB="$SDK_DIR/lib/_internal/pub/bin/pub.dart"
 
-  exec "$DART" "--checked" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
+  exec "$DART" "${VM_OPTIONS[@]}" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
 fi
diff --git a/sdk/bin/pub_developer.bat b/sdk/bin/pub_developer.bat
index 9c77b79..4025709 100644
--- a/sdk/bin/pub_developer.bat
+++ b/sdk/bin/pub_developer.bat
@@ -23,11 +23,17 @@
 set BUILD_DIR=%SDK_DIR%\..\build\ReleaseIA32
 set PACKAGES_DIR=%BUILD_DIR%\packages
 set DART_IN_BUILT_SDK=%BUILD_DIR%\dart-sdk\bin\dart
+set VM_OPTIONS=--checked
+
+rem Give the VM extra memory for dart2js.
+rem # TODO(rnystrom): Remove when #8355 is fixed.
+rem See comments regarding options below in dart2js shell script.
+set VM_OPTIONS=%VM_OPTIONS% --old_gen_heap_size=1024
 
 if exist "%SNAPSHOT%" (
-  "%DART%" --checked "%SNAPSHOT%" %*
+  "%DART%" %VM_OPTIONS% "%SNAPSHOT%" %*
 ) else (
-  "%DART_IN_BUILT_SDK%" --checked --package-root="%PACKAGES_DIR%" "%PUB%" %*
+  "%DART_IN_BUILT_SDK%" %VM_OPTIONS% --package-root="%PACKAGES_DIR%" "%PUB%" %*
 )
 
 endlocal
@@ -46,4 +52,4 @@
 endlocal & set %~2=%result%
 goto :eof
 
-:end
+:end
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 0afeed4..9a17d8e 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -14,6 +14,7 @@
 import '../../libraries.dart';
 import 'source_file.dart';
 
+
 class Compiler extends leg.Compiler {
   api.CompilerInputProvider provider;
   api.DiagnosticHandler handler;
@@ -61,7 +62,9 @@
             dumpInfo: hasOption(options, '--dump-info'),
             buildId: extractStringOption(
                 options, '--build-id=',
-                "build number could not be determined")) {
+                "build number could not be determined"),
+            hidePackageWarnings:
+                hasOption(options, '--hide-package-warnings')) {
     if (!libraryRoot.path.endsWith("/")) {
       throw new ArgumentError("libraryRoot must end with a /");
     }
@@ -284,8 +287,10 @@
     });
   }
 
-  void reportDiagnostic(leg.SourceSpan span, String message,
+  void reportDiagnostic(leg.Spannable node,
+                        leg.Message message,
                         api.Diagnostic kind) {
+    leg.SourceSpan span = spanFromSpannable(node);
     if (identical(kind, api.Diagnostic.ERROR)
         || identical(kind, api.Diagnostic.CRASH)) {
       compilationFailed = true;
@@ -293,10 +298,10 @@
     // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For
     // instance in the [Types] constructor in typechecker.dart.
     if (span == null || span.uri == null) {
-      callUserHandler(null, null, null, message, kind);
+      callUserHandler(null, null, null, '$message', kind);
     } else {
       callUserHandler(
-          translateUri(span.uri, null), span.begin, span.end, message, kind);
+          translateUri(span.uri, null), span.begin, span.end, '$message', kind);
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 11913ba..eacf7df 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -109,6 +109,7 @@
 class ClosureClassElement extends ClassElementX {
   DartType rawType;
   DartType thisType;
+  FunctionType callType;
   /// Node that corresponds to this closure, used for source position.
   final FunctionExpression node;
 
@@ -133,6 +134,7 @@
     thisType = rawType = new InterfaceType(this);
     allSupertypesAndSelf =
         superclass.allSupertypesAndSelf.extendClass(thisType);
+    callType = methodElement.computeType(compiler);
   }
 
   bool isClosure() => true;
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index d0bb37b..1a57ccb 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -135,7 +135,7 @@
                                           constantType, elementType)) {
               if (isConst) {
                 compiler.reportFatalError(
-                    node, MessageKind.NOT_ASSIGNABLE.error,
+                    node, MessageKind.NOT_ASSIGNABLE,
                     {'fromType': constantType, 'toType': elementType});
               } else {
                 // If the field cannot be lazily initialized, we will throw
@@ -305,7 +305,7 @@
       if (!map.containsKey(key)) {
         keys.add(key);
       } else {
-        compiler.reportWarningCode(entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY);
+        compiler.reportWarning(entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY);
       }
       map[key] = evaluateConstant(entry.value);
     }
@@ -575,7 +575,7 @@
       DartType conditionType = condition.computeType(compiler);
       if (isEvaluatingConstant) {
         compiler.reportFatalError(
-            node.condition, MessageKind.NOT_ASSIGNABLE.error,
+            node.condition, MessageKind.NOT_ASSIGNABLE,
             {'fromType': conditionType, 'toType': compiler.boolClass.rawType});
       }
       return null;
@@ -613,7 +613,7 @@
     if (!succeeded) {
       compiler.reportFatalError(
           node,
-          MessageKind.INVALID_ARGUMENTS.error, {'methodName': target.name});
+          MessageKind.INVALID_ARGUMENTS, {'methodName': target.name});
     }
     return compiledArguments;
   }
@@ -655,7 +655,7 @@
       if (firstArgument is! StringConstant) {
         DartType type = defaultValue.computeType(compiler);
         compiler.reportFatalError(
-            send.arguments.head, MessageKind.NOT_ASSIGNABLE.error,
+            send.arguments.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.stringClass.rawType});
       }
 
@@ -663,7 +663,7 @@
           && !(defaultValue is NullConstant || defaultValue is IntConstant)) {
         DartType type = defaultValue.computeType(compiler);
         compiler.reportFatalError(
-            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.intClass.rawType});
       }
 
@@ -671,7 +671,7 @@
           && !(defaultValue is NullConstant || defaultValue is BoolConstant)) {
         DartType type = defaultValue.computeType(compiler);
         compiler.reportFatalError(
-            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.boolClass.rawType});
       }
 
@@ -680,7 +680,7 @@
                || defaultValue is StringConstant)) {
         DartType type = defaultValue.computeType(compiler);
         compiler.reportFatalError(
-            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.stringClass.rawType});
       }
 
@@ -773,6 +773,13 @@
   }
 }
 
+class CompileTimeConstantError {
+  final Message message;
+  CompileTimeConstantError(MessageKind kind, Map arguments, bool terse)
+    : message = new Message(kind, arguments, terse);
+  String toString() => message.toString();
+}
+
 class ConstructorEvaluator extends CompileTimeConstantEvaluator {
   final FunctionElement constructor;
   final Map<Element, Constant> definitions;
@@ -816,7 +823,7 @@
       if (elementType.element.isTypeVariable()) return;
       if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
         compiler.reportFatalError(
-            node, MessageKind.NOT_ASSIGNABLE.error,
+            node, MessageKind.NOT_ASSIGNABLE,
             {'fromType': elementType, 'toType': constantType});
       }
     }
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index e115907..3409a8e 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -393,6 +393,13 @@
   /// Emit terse diagnostics without howToFix.
   final bool terseDiagnostics;
 
+  /// If `true`, warnings and hints not from user code are not reported.
+  final bool hidePackageWarnings;
+
+  /// `true` if the last diagnostic was filtered, in which case the
+  /// accompanying info message should be filtered as well.
+  bool lastDiagnosticWasFiltered = false;
+
   final api.CompilerOutputProvider outputProvider;
 
   bool disableInlining = false;
@@ -615,6 +622,7 @@
             this.buildId: UNDETERMINED_BUILD_ID,
             this.terseDiagnostics: false,
             this.dumpInfo: false,
+            this.hidePackageWarnings: false,
             outputProvider,
             List<String> strips: const []})
       : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly,
@@ -682,7 +690,7 @@
   void internalError(String message,
                      {Node node, Token token, HInstruction instruction,
                       Element element}) {
-    cancel('Internal Error: $message',
+    cancel(message,
            node: node, token: token,
            instruction: instruction, element: element);
   }
@@ -694,8 +702,8 @@
   void unhandledExceptionOnElement(Element element) {
     if (hasCrashed) return;
     hasCrashed = true;
-    reportDiagnostic(spanFromElement(element),
-                     MessageKind.COMPILER_CRASHED.error().toString(),
+    reportDiagnostic(element,
+                     MessageKind.COMPILER_CRASHED.message(),
                      api.Diagnostic.CRASH);
     pleaseReportCrash();
   }
@@ -720,11 +728,11 @@
     } else {
       throw 'No error location for error: $reason';
     }
-    reportError(spannable, MessageKind.GENERIC, {'text': reason});
+    reportInternalError(spannable, MessageKind.GENERIC, {'text': reason});
     throw new CompilerCancelledException(reason);
   }
 
-  SourceSpan spanFromSpannable(Spannable node, [Uri uri]) {
+  SourceSpan spanFromSpannable(Spannable node) {
     if (node == null) return null;
     if (node == CURRENT_ELEMENT_SPANNABLE) {
       node = currentElement;
@@ -732,24 +740,39 @@
     if (node is SourceSpan) {
       return node;
     } else if (node is Node) {
-      return spanFromNode(node, uri);
+      return spanFromNode(node);
     } else if (node is Token) {
-      return spanFromTokens(node, node, uri);
+      return spanFromTokens(node, node);
     } else if (node is HInstruction) {
       return spanFromHInstruction(node);
     } else if (node is Element) {
       return spanFromElement(node);
     } else if (node is MetadataAnnotation) {
-      MetadataAnnotation annotation = node;
-      uri = annotation.annotatedElement.getCompilationUnit().script.uri;
-      return spanFromTokens(annotation.beginToken, annotation.endToken, uri);
+      Uri uri = node.annotatedElement.getCompilationUnit().script.uri;
+      return spanFromTokens(node.beginToken, node.endToken, uri);
     } else {
       throw 'No error location.';
     }
   }
 
+  /// Finds the approximate [Element] for [node]. [currentElement] is used as
+  /// the default value.
+  Element elementFromSpannable(Spannable node) {
+    Element element;
+    if (node is Element) {
+      element = node;
+    } else if (node is HInstruction) {
+      element = node.sourceElement;
+    } else if (node is MetadataAnnotation) {
+      element = node.annotatedElement;
+    }
+    return element != null ? element : currentElement;
+  }
+
   void log(message) {
-    reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO);
+    reportDiagnostic(null,
+        MessageKind.GENERIC.message({'text': '$message'}),
+        api.Diagnostic.VERBOSE_INFO);
   }
 
   Future<bool> run(Uri uri) {
@@ -765,7 +788,7 @@
         if (!hasCrashed) {
           hasCrashed = true;
           reportDiagnostic(new SourceSpan(uri, 0, 0),
-                           MessageKind.COMPILER_CRASHED.error().toString(),
+                           MessageKind.COMPILER_CRASHED.message(),
                            api.Diagnostic.CRASH);
           pleaseReportCrash();
         }
@@ -1020,26 +1043,21 @@
           reportFatalError(
               mainApp,
               MessageKind.GENERIC,
-              {'text': "Error: Could not find '$MAIN'."});
+              {'text': "Could not find '$MAIN'."});
         } else if (!analyzeAll) {
-          reportFatalError(
-              mainApp,
-              MessageKind.GENERIC,
-              {'text': "Error: Could not find '$MAIN'. "
-              "No source will be analyzed. "
-              "Use '--analyze-all' to analyze all code in the library."});
+          reportFatalError(mainApp, MessageKind.GENERIC,
+              {'text': "Could not find '$MAIN'. "
+                       "No source will be analyzed. "
+                       "Use '--analyze-all' to analyze all code in the "
+                       "library."});
         }
       } else {
         if (main.isErroneous()) {
-          reportFatalError(
-              main,
-              MessageKind.GENERIC,
-              {'text': "Error: Cannot determine which '$MAIN' to use."});
+          reportFatalError(main, MessageKind.GENERIC,
+              {'text': "Cannot determine which '$MAIN' to use."});
         } else if (!main.isFunction()) {
-          reportFatalError(
-              main,
-              MessageKind.GENERIC,
-              {'text': "Error: '$MAIN' is not a function."});
+          reportFatalError(main, MessageKind.GENERIC,
+              {'text': "'$MAIN' is not a function."});
         }
         mainFunction = main;
         FunctionSignature parameters = mainFunction.computeSignature(this);
@@ -1047,11 +1065,8 @@
           int index = 0;
           parameters.forEachParameter((Element parameter) {
             if (index++ < 2) return;
-            reportError(
-                parameter,
-                MessageKind.GENERIC,
-                {'text':
-                  "Error: '$MAIN' cannot have more than two parameters."});
+            reportError(parameter, MessageKind.GENERIC,
+                {'text': "'$MAIN' cannot have more than two parameters."});
           });
         }
       }
@@ -1231,9 +1246,9 @@
     }
     log('Excess resolution work: ${resolved.length}.');
     for (Element e in resolved) {
-      SourceSpan span = spanFromElement(e);
-      reportDiagnostic(span, 'Warning: $e resolved but not compiled.',
-                       api.Diagnostic.WARNING);
+      reportWarning(e,
+          MessageKind.GENERIC,
+          {'text': 'Warning: $e resolved but not compiled.'});
     }
   }
 
@@ -1310,12 +1325,6 @@
                               () => resolver.resolveSignature(element));
   }
 
-  FunctionSignature resolveFunctionExpression(Element element,
-                                              FunctionExpression node) {
-    return withCurrentElement(element,
-        () => resolver.resolveFunctionExpression(element, node));
-  }
-
   void resolveTypedef(TypedefElement element) {
     withCurrentElement(element,
                        () => resolver.resolve(element));
@@ -1327,53 +1336,39 @@
         () => resolver.computeFunctionType(element, signature));
   }
 
-  reportWarning(Spannable node, var message) {
-    if (message is TypeWarning) {
-      // TODO(ahe): Don't supress these warning when the type checker
-      // is more complete.
-      if (message.message.kind == MessageKind.MISSING_RETURN) return;
-      if (message.message.kind == MessageKind.MAYBE_MISSING_RETURN) return;
-    }
-    SourceSpan span = spanFromSpannable(node);
-    reportDiagnostic(span, '$message', api.Diagnostic.WARNING);
-  }
-
   void reportError(Spannable node,
-                   MessageKind errorCode,
+                   MessageKind messageKind,
                    [Map arguments = const {}]) {
-    reportMessage(spanFromSpannable(node),
-                  errorCode.error(arguments, terseDiagnostics),
-                  api.Diagnostic.ERROR);
+    reportDiagnosticInternal(
+        node, messageKind, arguments, api.Diagnostic.ERROR);
   }
 
-  void reportFatalError(Spannable node, MessageKind errorCode,
+  void reportFatalError(Spannable node, MessageKind messageKind,
                         [Map arguments = const {}]) {
-    reportError(node, errorCode, arguments);
+    reportError(node, messageKind, arguments);
     // TODO(ahe): Make this only abort the current method.
     throw new CompilerCancelledException(
         'Error: Cannot continue due to previous error.');
   }
 
-  // TODO(ahe): Rename to reportWarning when that method has been removed.
-  void reportWarningCode(Spannable node, MessageKind errorCode,
-                         [Map arguments = const {}]) {
-    reportMessage(spanFromSpannable(node),
-                  errorCode.error(arguments, terseDiagnostics),
-                  api.Diagnostic.WARNING);
+  void reportWarning(Spannable node, MessageKind messageKind,
+                     [Map arguments = const {}]) {
+    // TODO(ahe): Don't suppress these warning when the type checker
+    // is more complete.
+    if (messageKind == MessageKind.MISSING_RETURN) return;
+    if (messageKind == MessageKind.MAYBE_MISSING_RETURN) return;
+    reportDiagnosticInternal(
+        node, messageKind, arguments, api.Diagnostic.WARNING);
   }
 
-  void reportInfo(Spannable node, MessageKind errorCode,
+  void reportInfo(Spannable node, MessageKind messageKind,
                   [Map arguments = const {}]) {
-    reportMessage(spanFromSpannable(node),
-                  errorCode.error(arguments, terseDiagnostics),
-                  api.Diagnostic.INFO);
+    reportDiagnosticInternal(node, messageKind, arguments, api.Diagnostic.INFO);
   }
 
-  void reportHint(Spannable node, MessageKind errorCode,
+  void reportHint(Spannable node, MessageKind messageKind,
                   [Map arguments = const {}]) {
-    reportMessage(spanFromSpannable(node),
-                  errorCode.error(arguments, terseDiagnostics),
-                  api.Diagnostic.HINT);
+    reportDiagnosticInternal(node, messageKind, arguments, api.Diagnostic.HINT);
   }
 
   /// For debugging only, print a message with a source location.
@@ -1381,18 +1376,40 @@
     reportInfo(node, MessageKind.GENERIC, {'text': 'HERE: $debugMessage'});
   }
 
-  void reportInternalError(Spannable node, String message) {
-    reportError(
-        node, MessageKind.GENERIC, {'text': 'Internal Error: $message'});
+  void reportInternalError(Spannable node, MessageKind messageKind,
+                           [Map arguments = const {}]) {
+    reportDiagnosticInternal(
+        node, messageKind, arguments, api.Diagnostic.CRASH);
   }
 
-  void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind) {
-    // TODO(ahe): The names Diagnostic and api.Diagnostic are in
-    // conflict. Fix it.
-    reportDiagnostic(span, "$message", kind);
+  void reportDiagnosticInternal(Spannable node,
+                                MessageKind messageKind,
+                                Map arguments,
+                                api.Diagnostic kind) {
+    if (hidePackageWarnings) {
+      switch (kind) {
+      case api.Diagnostic.WARNING:
+      case api.Diagnostic.HINT:
+        if (!inUserCode(elementFromSpannable(node))) {
+          lastDiagnosticWasFiltered = true;
+          return;
+        }
+        break;
+      case api.Diagnostic.INFO:
+        if (lastDiagnosticWasFiltered) {
+          return;
+        }
+        break;
+      }
+    }
+    lastDiagnosticWasFiltered = false;
+    reportDiagnostic(
+        node, messageKind.message(arguments, terseDiagnostics), kind);
   }
 
-  void reportDiagnostic(SourceSpan span, String message, api.Diagnostic kind);
+  void reportDiagnostic(Spannable span,
+                        Message message,
+                        api.Diagnostic kind);
 
   void reportAssertionFailure(SpannableAssertionFailure ex) {
     String message = (ex.message != null) ? tryToString(ex.message)
@@ -1415,8 +1432,8 @@
       (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset));
   }
 
-  SourceSpan spanFromNode(Node node, [Uri uri]) {
-    return spanFromTokens(node.getBeginToken(), node.getEndToken(), uri);
+  SourceSpan spanFromNode(Node node) {
+    return spanFromTokens(node.getBeginToken(), node.getEndToken());
   }
 
   SourceSpan spanFromElement(Element element) {
@@ -1550,16 +1567,15 @@
     });
   }
 
-  /// Debugging helper for determining whether the current element is declared
-  /// within 'user code'.
+  /// Helper for determining whether the current element is declared within
+  /// 'user code'.
   ///
   /// See [inUserCode] for what defines 'user code'.
   bool currentlyInUserCode() {
     return inUserCode(currentElement);
   }
 
-  /// Debugging helper for determining whether [element] is declared within
-  /// 'user code'.
+  /// Helper for determining whether [element] is declared within 'user code'.
   ///
   /// What constitutes 'user code' is defined by the URI(s) provided by the
   /// entry point(s) of compilation or analysis:
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index b5f7a1a..31ba869 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -17,7 +17,7 @@
   R visitConstructed(ConstructedConstant constant);
   R visitType(TypeConstant constant);
   R visitInterceptor(InterceptorConstant constant);
-  R visitDummyReceiver(DummyReceiverConstant constant);
+  R visitDummy(DummyConstant constant);
 }
 
 abstract class Constant {
@@ -42,7 +42,7 @@
   bool isType() => false;
   bool isSentinel() => false;
   bool isInterceptor() => false;
-  bool isDummyReceiver() => false;
+  bool isDummy() => false;
 
   bool isNaN() => false;
   bool isMinusZero() => false;
@@ -539,15 +539,15 @@
   }
 }
 
-class DummyReceiverConstant extends Constant {
+class DummyConstant extends Constant {
   final ti.TypeMask typeMask;
 
-  DummyReceiverConstant(this.typeMask);
+  DummyConstant(this.typeMask);
 
-  bool isDummyReceiver() => true;
+  bool isDummy() => true;
 
   bool operator ==(other) {
-    return other is DummyReceiverConstant
+    return other is DummyConstant
         && typeMask == other.typeMask;
   }
 
@@ -555,14 +555,14 @@
 
   List<Constant> getDependencies() => const <Constant>[];
 
-  accept(ConstantVisitor visitor) => visitor.visitDummyReceiver(this);
+  accept(ConstantVisitor visitor) => visitor.visitDummy(this);
 
   DartType computeType(Compiler compiler) => compiler.types.dynamicType;
 
   ti.TypeMask computeMask(Compiler compiler) => typeMask;
 
   String toString() {
-    return 'DummyReceiverConstant($typeMask)';
+    return 'DummyConstant($typeMask)';
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 2f546dc..b445415 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -7,7 +7,7 @@
 import 'dart:async'
     show Future, EventSink;
 import 'dart:io'
-    show exit, File, FileMode, Platform, RandomAccessFile;
+    show exit, File, FileMode, Platform, RandomAccessFile, FileSystemException;
 import 'dart:math' as math;
 
 import '../compiler.dart' as api;
@@ -279,6 +279,7 @@
     new OptionHandler('--dump-info', passThrough),
     new OptionHandler('--disallow-unsafe-eval',
                       (_) => hasDisallowUnsafeEval = true),
+    new OptionHandler('--hide-package-warnings', passThrough),
     new OptionHandler('-D.+=.*', addInEnvironment),
 
     // The following two options must come last.
@@ -384,8 +385,12 @@
       fail('Error: Unhandled scheme ${uri.scheme} in $uri.');
     }
 
-    RandomAccessFile output =
-        new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
+    RandomAccessFile output;
+    try {
+      output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
+    } on FileSystemException catch(e) {
+      fail('$e');
+    }
 
     allOutputFiles.add(relativize(currentDirectory, uri, isWindows));
 
@@ -553,6 +558,9 @@
     Emit diagnostics without suggestions for how to get rid of the diagnosed
     problems.
 
+  --hide-package-warnings
+    Hide warnings and hints generated from packages.
+
 The following options are only used for compiler development and may
 be removed in a future version:
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 1465f3d..ed9fd82 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -31,6 +31,7 @@
 import 'patch_parser.dart';
 import 'types/types.dart' as ti;
 import 'resolution/resolution.dart';
+import 'resolution/class_members.dart' show MembersCreator;
 import 'source_file.dart' show SourceFile;
 import 'js/js.dart' as js;
 import 'deferred_load.dart' show DeferredLoadTask;
@@ -44,6 +45,8 @@
                                       isTernaryOperator,
                                       isMinusOperator;
 export 'universe/universe.dart' show Selector, TypedSelector;
+export 'util/util.dart' show Spannable;
+
 
 part 'code_buffer.dart';
 part 'compile_time_constants.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index d41c289..04aceea 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -490,68 +490,20 @@
 
   DartType unalias(Compiler compiler) => this;
 
-  /**
-   * Finds the method, field or property named [name] declared or inherited
-   * on this interface type.
-   */
-  InterfaceTypeMember lookupMember(String name, {bool isSetter: false}) {
-    // Abstract field returned when setter was needed but only a getter was
-    // present and vice-versa.
-    InterfaceTypeMember fallbackAbstractField;
-
-    InterfaceTypeMember createMember(ClassElement classElement,
-                                     InterfaceType receiver,
-                                     InterfaceType declarer) {
-      Element member = classElement.implementation.lookupLocalMember(name);
-      if (member == null) return null;
-      if (member.isConstructor() || member.isPrefix()) return null;
-      assert(member.isFunction() ||
-             member.isAbstractField() ||
-             member.isField());
-
-      if (member.isAbstractField()) {
-        AbstractFieldElement abstractFieldElement = member;
-        if (fallbackAbstractField == null) {
-          fallbackAbstractField =
-              new InterfaceTypeMember(receiver, declarer, member,
-                                      isSetter: isSetter);
-        }
-        if (isSetter && abstractFieldElement.setter == null) {
-          // Keep searching further up the hierarchy.
-          member = null;
-        } else if (!isSetter && abstractFieldElement.getter == null) {
-          // Keep searching further up the hierarchy.
-          member = null;
-        }
-      }
-      return member != null
-          ? new InterfaceTypeMember(receiver, declarer, member,
-                                    isSetter: isSetter)
-          : null;
+  MemberSignature lookupInterfaceMember(Name name) {
+    MemberSignature member = element.lookupInterfaceMember(name);
+    if (member != null && isGeneric) {
+      return new InterfaceMember(this, member);
     }
+    return member;
+  }
 
-    ClassElement classElement = element;
-    InterfaceType receiver = this;
-    InterfaceType declarer = receiver;
-    // TODO(johnniwinther): Lookup and callers should handle private members and
-    // injected members.
-    InterfaceTypeMember member = createMember(classElement, receiver, declarer);
-    if (member != null) return member;
-
-    assert(invariant(element, classElement.allSupertypes != null,
-        message: 'Supertypes not computed for $classElement'));
-    for (InterfaceType supertype in classElement.allSupertypes) {
-      // Skip mixin applications since their supertypes are also in the list of
-      // [allSupertypes].
-      if (supertype.element.isMixinApplication) continue;
-      declarer = supertype;
-      ClassElement lookupTarget = declarer.element;
-      InterfaceTypeMember member =
-          createMember(lookupTarget, receiver, declarer);
-      if (member != null) return member;
+  MemberSignature lookupClassMember(Name name) {
+    MemberSignature member = element.lookupClassMember(name);
+    if (member != null && isGeneric) {
+      return new InterfaceMember(this, member);
     }
-
-    return fallbackAbstractField;
+    return member;
   }
 
   int get hashCode => super.hashCode;
@@ -561,6 +513,13 @@
   accept(DartTypeVisitor visitor, var argument) {
     return visitor.visitInterfaceType(this, argument);
   }
+
+  /// Returns the type of the 'call' method in this interface type, or
+  /// `null` if the interface type has no 'call' method.
+  FunctionType get callType {
+    FunctionType type = element.callType;
+    return type != null && isGeneric ? type.substByContext(this) : type;
+  }
 }
 
 /**
@@ -847,7 +806,7 @@
 }
 
 /**
- * [InterfaceTypeMember] encapsulates a member (method, field, property) with
+ * [InterfaceMember] encapsulates a member (method, field, property) with
  * the types of the declarer and receiver in order to do substitution on the
  * member type.
  *
@@ -858,67 +817,32 @@
  *     }
  *     class B<F> extends A<F> {}
  *
- * In an [InterfaceTypeMember] for `b.field` the [receiver] is the type
+ * In an [InterfaceMember] for `b.field` the [receiver] is the type
  * `B<String>` and the declarer is the type `A<F>`, which is the supertype of
  * `B<F>` from which `field` has been inherited. To compute the type of
  * `b.field` we must first substitute `E` by `F` using the relation between
  * `A<E>` and `A<F>`, and then `F` by `String` using the relation between
  * `B<F>` and `B<String>`.
  */
-// TODO(johnniwinther): Add [isReadable] and [isWritable] predicates.
-class InterfaceTypeMember {
-  final InterfaceType receiver;
-  final InterfaceType declarer;
-  final Element element;
-  DartType cachedType;
-  final bool isSetter;
+class InterfaceMember implements MemberSignature {
+  final InterfaceType instance;
+  final MemberSignature member;
 
-  InterfaceTypeMember(this.receiver, this.declarer, this.element,
-         {bool this.isSetter: false}) {
-    assert(invariant(element, element.isAbstractField() ||
-                     element.isField() ||
-                     element.isFunction(),
-                message: "Unsupported InterfaceTypeMember element: $element"));
-  }
+  InterfaceMember(this.instance, this.member);
 
-  DartType computeType(Compiler compiler) {
-    if (cachedType == null) {
-      DartType type;
-      if (element.isAbstractField()) {
-        AbstractFieldElement abstractFieldElement = element;
-        // Use setter if present and required or if no getter is available.
-        if ((isSetter && abstractFieldElement.setter != null) ||
-            abstractFieldElement.getter == null) {
-          // TODO(johnniwinther): Add check of read of field with no getter.
-          FunctionType functionType =
-              abstractFieldElement.setter.computeType(
-                  compiler);
-          type = functionType.parameterTypes.head;
-          if (type == null) {
-            type = compiler.types.dynamicType;
-          }
-        } else {
-          // TODO(johnniwinther): Add check of assignment to field with no
-          // setter.
-          FunctionType functionType =
-              abstractFieldElement.getter.computeType(compiler);
-          type = functionType.returnType;
-        }
-      } else {
-        type = element.computeType(compiler);
-      }
-      if (!declarer.element.typeVariables.isEmpty) {
-        type = type.substByContext(declarer);
-        type = type.substByContext(receiver);
-      }
-      cachedType = type;
-    }
-    return cachedType;
-  }
+  Name get name => member.name;
 
-  String toString() {
-    return '$receiver.${element.name}';
-  }
+  DartType get type => member.type.substByContext(instance);
+
+  FunctionType get functionType => member.functionType.substByContext(instance);
+
+  bool get isGetter => member.isGetter;
+
+  bool get isSetter => member.isSetter;
+
+  bool get isMethod => member.isMethod;
+
+  Iterable<Member> get declarations => member.declarations;
 }
 
 abstract class DartTypeVisitor<R, A> {
@@ -1149,6 +1073,9 @@
         identical(t.element, compiler.nullClass)) {
       return true;
     }
+    if (t.isVoid || s.isVoid) {
+      return false;
+    }
     if (t.treatAsDynamic) {
       return false;
     }
@@ -1216,22 +1143,13 @@
   bool visitInterfaceType(InterfaceType t, DartType s) {
     if (super.visitInterfaceType(t, s)) return true;
 
-    InterfaceTypeMember lookupCall(type) =>
-        type.lookupMember(Compiler.CALL_OPERATOR_NAME);
-
-    bool hasCallMethod(type) {
-      InterfaceTypeMember member = lookupCall(type);
-      return member != null && member.element.isFunction();
-    }
-
     if (s is InterfaceType &&
         s.element == compiler.functionClass &&
-        hasCallMethod(t)) {
+        t.element.callType != null) {
       return true;
     } else if (s is FunctionType) {
-      InterfaceTypeMember call = lookupCall(t);
-      if (call == null) return false;
-      return isSubtype(call.computeType(compiler), s);
+      FunctionType callType = t.callType;
+      return callType != null && isSubtype(callType, s);
     }
     return false;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index 47ea3a1b..fc1b601 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -617,21 +617,68 @@
     _allDeferredImports[_fakeMainImport] = compiler.mainApp;
     bool deferredUsedFromMain = false;
     var lastDeferred;
+    // When detecting duplicate prefixes of deferred libraries there are 4
+    // cases of duplicate prefixes:
+    // 1.
+    // @DeferredLibrary("a") import "lib.dart" as a;
+    // @DeferredLibrary("b") import "lib2.dart" as a;
+    // 2.
+    // @DeferredLibrary("a") import "lib.dart" as a;
+    // import "lib2.dart" as a;
+    // 3.
+    // import "lib.dart" as a;
+    // @DeferredLibrary("a") import "lib2.dart" as a;
+    // 4.
+    // import "lib.dart" as a;
+    // import "lib2.dart" as a;
+    // We must be able to signal error for case 1, 2, 3, but accept case 4.
+    
+    // The prefixes that have been used by any imports in this library.
+    Setlet<String> usedPrefixes = new Setlet<String>();
+    // The last deferred import we saw with a given prefix (if any).
+    Map<String, Import> prefixDeferredImport = new Map<String, Import>();
     for (LibraryElement library in compiler.libraries.values) {
-      // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List
-      // instead of a Link.
-      for (LibraryTag tag in library.tags) {
-        if (tag is! Import) continue;
-        Import import = tag;
-        if (_isImportDeferred(import)) {
-          splitProgram = true;
-          _allDeferredImports[tag] = library.getLibraryFromTag(tag);
-          lastDeferred = import.metadata.first;
-          if (library == compiler.mainApp) {
-            deferredUsedFromMain = true;
+      compiler.withCurrentElement(library, () {
+        prefixDeferredImport.clear();
+        usedPrefixes.clear();
+        // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List
+        // instead of a Link.
+        for (LibraryTag tag in library.tags) {
+          if (tag is! Import) continue;
+          Import import = tag;
+          String prefix = (import.prefix != null)
+              ? import.prefix.toString()
+              : null;
+          // The last import we saw with the same prefix.
+          Import previousDeferredImport = prefixDeferredImport[prefix];
+          bool isDeferred = _isImportDeferred(import);
+          if (isDeferred) {
+            if (prefix == null) {
+              compiler.reportError(import,
+                  MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX);
+            } else {
+              prefixDeferredImport[prefix] = import;
+            }
+            splitProgram = true;
+            _allDeferredImports[tag] = library.getLibraryFromTag(tag);
+            lastDeferred = import.metadata.first;
+            if (library == compiler.mainApp) {
+              deferredUsedFromMain = true;
+            }
+          }
+          if (prefix != null) {
+            if (previousDeferredImport != null ||
+                (isDeferred && usedPrefixes.contains(prefix))) {
+              Import failingImport = (previousDeferredImport != null)
+                  ? previousDeferredImport
+                  : import;
+              compiler.reportError(failingImport.prefix,
+                  MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
+            }
+            usedPrefixes.add(prefix);
           }
         }
-      }
+      });
     }
     if (splitProgram && !deferredUsedFromMain) {
       compiler.reportInfo(
diff --git a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
index 3b688f9..dd70c69 100644
--- a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
@@ -15,18 +15,19 @@
                      {Node node, Token token, HInstruction instruction,
                       Element element});
 
-  SourceSpan spanFromSpannable(Spannable node, [Uri uri]);
+  SourceSpan spanFromSpannable(Spannable node);
 
-  void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind);
+  void reportError(Spannable node, MessageKind errorCode,
+                   [Map arguments = const {}]);
 
-  void reportError(Spannable node, MessageKind errorCode, [Map arguments]);
+  void reportWarning(Spannable node, MessageKind errorCode,
+                     [Map arguments = const {}]);
 
-  // TODO(johnniwinther): Rename to [reportWarning] when
-  // [Compiler.reportWarning] has been removed.
-  void reportWarningCode(Spannable node, MessageKind errorCode,
-                         [Map arguments = const {}]);
+  void reportHint(Spannable node, MessageKind errorCode,
+                  [Map arguments = const {}]);
 
-  void reportInfo(Spannable node, MessageKind errorCode, [Map arguments]);
+  void reportInfo(Spannable node, MessageKind errorCode,
+                  [Map arguments = const {}]);
 
   // TODO(ahe): We should not expose this here.  Perhaps a
   // [SourceSpan] should implement [Spannable], and we should have a
diff --git a/sdk/lib/_internal/compiler/implementation/dump_info.dart b/sdk/lib/_internal/compiler/implementation/dump_info.dart
index 5cc562d..8f6c8e6 100644
--- a/sdk/lib/_internal/compiler/implementation/dump_info.dart
+++ b/sdk/lib/_internal/compiler/implementation/dump_info.dart
@@ -121,7 +121,9 @@
         extraString].join(' ');
 
     if (contents != null) {
+      buffer.write('\n');
       buffer.write(div("+$describe", cls: "container"));
+      buffer.write('\n');
       buffer.write('<div class="contained">');
       if (contents.isEmpty) {
         buffer.writeln("No members");
@@ -131,7 +133,7 @@
       }
       buffer.write("</div>");
     } else {
-      buffer.writeln(describe);
+      buffer.writeln(div('$describe', cls: "element"));
     }
   }
 }
@@ -150,6 +152,7 @@
   CodeInfoNode({this.description: "", this.generatedCode});
 
   void emitHtml(ProgramInfo programInfo, StringBuffer buffer) {
+    buffer.write('\n');
     buffer.write(div(description + ' ' +
                      sizeDescription(generatedCode.length, programInfo),
                      cls: 'kind') +
@@ -175,10 +178,12 @@
   InferredInfoNode({this.name: "", this.description, this.type});
 
   void emitHtml(ProgramInfo programInfo, StringSink buffer) {
-    buffer.write(div('${span("Inferred " + description, cls: "kind")} '
-                     '${span(esc(name),
-                     cls: "name")} '
-        '${span(esc(type), cls: 'type')} '));
+    buffer.write('\n');
+    buffer.write(
+        div('${span("Inferred " + description, cls: "kind")} '
+            '${span(esc(name), cls: "name")} '
+            '${span(esc(type), cls: "type")} ',
+            cls: "attr"));
   }
 }
 
@@ -453,11 +458,16 @@
   <head>
     <title>Dart2JS compilation information</title>
        <style>
-         code {margin-left: 20px; display: block;}
+         code {margin-left: 20px; display: block; white-space: pre; }
+         div.container, div.contained, div.element, div.attr {
+           margin-top:0px;
+           margin-bottom: 0px;
+         }
+         div.container, div.element, div.attr {
+           white-space: pre;
+         }
          div.contained {margin-left: 20px;}
-         div {margin-top:0px;
-         margin-bottom: 0px;
-         white-space: pre; /*border: 1px solid;*/}
+         div {/*border: 1px solid;*/}
          span.kind {}
          span.modifiers {font-weight:bold;}
          span.name {font-weight:bold; font-family: monospace;}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 3243e90..902ca67 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -626,7 +626,7 @@
 }
 
 abstract class AmbiguousElement extends Element {
-  DualKind get messageKind;
+  MessageKind get messageKind;
   Map get messageArguments;
   Element get existingElement;
   Element get newElement;
@@ -766,6 +766,7 @@
   VariableElement get fieldElement;
 }
 
+// TODO(johnniwinther): Remove this interface.
 abstract class VariableListElement extends Element {
   DartType get type;
   FunctionSignature get functionSignature;
@@ -974,6 +975,10 @@
 
   /// Calls [f] with each member of the interface of this class.
   void forEachInterfaceMember(f(MemberSignature member));
+
+  /// Returns the type of the 'call' method in the interface of this class, or
+  /// `null` if the interface has no 'call' method.
+  FunctionType get callType;
 }
 
 abstract class MixinApplicationElement extends ClassElement {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 6a96ee9..9a226bc 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -5,7 +5,6 @@
 library elements.modelx;
 
 import 'elements.dart';
-import '../../compiler.dart' as api;
 import '../tree/tree.dart';
 import '../util/util.dart';
 import '../resolution/resolution.dart';
@@ -407,7 +406,7 @@
     if (warning != null) {
       Spannable spannable = warning.spannable;
       if (spannable == null) spannable = usageSpannable;
-      listener.reportWarningCode(
+      listener.reportWarning(
           spannable, warning.messageKind, warning.messageArguments);
     }
     if (info != null) {
@@ -436,7 +435,7 @@
   /**
    * The message to report on resolving this element.
    */
-  final DualKind messageKind;
+  final MessageKind messageKind;
 
   /**
    * The message arguments to report on resolving this element.
@@ -513,10 +512,8 @@
       if (!identical(existing, element)) {
         listener.reportError(
             element, MessageKind.DUPLICATE_DEFINITION, {'name': name});
-        listener.reportMessage(
-            listener.spanFromSpannable(existing),
-            MessageKind.EXISTING_DEFINITION.error({'name': name}),
-            api.Diagnostic.INFO);
+        listener.reportInfo(existing,
+            MessageKind.EXISTING_DEFINITION, {'name': name});
       }
     }
   }
@@ -616,10 +613,7 @@
       return;
     }
     if (partTag != null) {
-      listener.reportMessage(
-          listener.spanFromSpannable(tag),
-          MessageKind.DUPLICATED_PART_OF.error(),
-          api.Diagnostic.WARNING);
+      listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF);
       return;
     }
     partTag = tag;
@@ -628,12 +622,12 @@
     if (libraryTag != null) {
       String expectedName = libraryTag.name.toString();
       if (expectedName != actualName) {
-        listener.reportWarningCode(tag.name,
+        listener.reportWarning(tag.name,
             MessageKind.LIBRARY_NAME_MISMATCH,
             {'libraryName': expectedName});
       }
     } else {
-      listener.reportWarningCode(getLibrary(),
+      listener.reportWarning(getLibrary(),
           MessageKind.MISSING_LIBRARY_NAME,
           {'libraryName': actualName});
       listener.reportInfo(tag.name,
@@ -1123,7 +1117,12 @@
   accept(ElementVisitor visitor) => visitor.visitTypedefElement(this);
 }
 
-class VariableElementX extends ElementX implements VariableElement {
+abstract class MetadataContainer extends Element {
+  Link<MetadataAnnotation> metadata;
+}
+
+class VariableElementX extends ElementX implements VariableElement,
+    MetadataContainer {
   final VariableListElement variables;
   Expression cachedNode; // The send or the identifier in the variables list.
 
@@ -1178,20 +1177,6 @@
   Token position() => findMyName(variables.position());
 
   accept(ElementVisitor visitor) => visitor.visitVariableElement(this);
-
-  // TODO(johnniwinther): Move the patch/origin implementation to a parameter
-  // specific element when added.
-
-  /**
-   * A function declaration that should be parsed instead of the current one.
-   * The patch should be parsed as if it was in the current scope. Its
-   * signature must match this function's signature.
-   */
-  VariableElementX patch = null;
-  VariableElementX origin = null;
-
-  bool get isPatch => origin != null;
-  bool get isPatched => patch != null;
 }
 
 class FieldElementX extends VariableElementX implements FieldElement {
@@ -1209,18 +1194,19 @@
  * Parameters in constructors that directly initialize fields. For example:
  * [:A(this.field):].
  */
-class FieldParameterElementX extends VariableElementX
+class FieldParameterElementX extends ParameterElementX
     implements FieldParameterElement {
   VariableElement fieldElement;
 
   FieldParameterElementX(String name,
-                         this.fieldElement,
-                         VariableListElement variables,
-                         Node node)
-      : super(name, variables, ElementKind.FIELD_PARAMETER, node);
+                         Element enclosingElement,
+                         VariableDefinitions variables,
+                         Expression node,
+                         this.fieldElement)
+      : super(name, enclosingElement, ElementKind.FIELD_PARAMETER,
+          variables, node);
 
   DartType computeType(Compiler compiler) {
-    VariableDefinitions definitions = variables.parseNode(compiler);
     if (definitions.type == null) {
       return fieldElement.computeType(compiler);
     }
@@ -1234,17 +1220,13 @@
 // It contains the node, and the type. A [VariableElement] always
 // references its [VariableListElement]. It forwards its
 // [computeType] and [parseNode] methods to this element.
-class VariableListElementX extends ElementX implements VariableListElement {
+class VariableListElementX extends ElementX implements VariableListElement,
+    MetadataContainer {
   VariableDefinitions cachedNode;
   DartType type;
   final Modifiers modifiers;
 
-  /**
-   * Function signature for a variable with a function type. The signature is
-   * kept to provide full information about parameter names through the mirror
-   * system.
-   */
-  FunctionSignature functionSignature;
+  FunctionSignature get functionSignature => null;
 
   VariableListElementX(ElementKind kind,
                        Modifiers this.modifiers,
@@ -1271,22 +1253,7 @@
       if (node.type != null) {
         type = compiler.resolveTypeAnnotation(this, node.type);
       } else {
-        // Is node.definitions exactly one FunctionExpression?
-        Link<Node> link = node.definitions.nodes;
-        if (!link.isEmpty &&
-            link.head.asFunctionExpression() != null &&
-            link.tail.isEmpty) {
-          FunctionExpression functionExpression = link.head;
-          // We found exactly one FunctionExpression
-          functionSignature =
-              compiler.resolveFunctionExpression(this, functionExpression);
-          // TODO(johnniwinther): Use the parameter's [VariableElement] instead
-          // of [functionClass].
-          type = compiler.computeFunctionType(compiler.functionClass,
-                                              functionSignature);
-        } else {
-          type = compiler.types.dynamicType;
-        }
+        type = compiler.types.dynamicType;
       }
     });
     assert(type != null);
@@ -1302,6 +1269,59 @@
   accept(ElementVisitor visitor) => visitor.visitVariableListElement(this);
 }
 
+/// [Element] for a formal parameter.
+///
+/// A [ParameterElementX] can be patched. A parameter of an external method is
+/// patched with the corresponding parameter of the patch method. This is done
+/// to ensure that default values on parameters are computed once (on the
+/// origin parameter) but can be found through both the origin and the patch.
+class ParameterElementX extends ElementX
+    implements VariableElement, VariableListElement, MetadataContainer {
+  VariableDefinitions definitions;
+  Expression cachedNode;
+  DartType type;
+
+  /**
+   * Function signature for a variable with a function type. The signature is
+   * kept to provide full information about parameter names through the mirror
+   * system.
+   */
+  FunctionSignature functionSignature;
+
+  ParameterElementX(String name,
+                    Element enclosingElement,
+                    ElementKind elementKind,
+                    VariableDefinitions definitions,
+                    Expression node)
+      : this.definitions = definitions,
+        this.cachedNode = node,
+        super(name, elementKind, enclosingElement);
+
+  VariableListElement get variables => this;
+
+  Modifiers get modifiers => definitions.modifiers;
+
+  Token position() => cachedNode.getBeginToken();
+
+  Node parseNode(DiagnosticListener listener) => cachedNode;
+
+  DartType computeType(Compiler compiler) {
+    assert(invariant(this, type != null,
+        message: "Parameter type has not been set for $this."));
+    return type;
+  }
+
+  FunctionType get functionType => type;
+
+  accept(ElementVisitor visitor) => visitor.visitVariableElement(this);
+
+  ParameterElementX patch = null;
+  ParameterElementX origin = null;
+
+  bool get isPatch => origin != null;
+  bool get isPatched => patch != null;
+}
+
 class AbstractFieldElementX extends ElementX implements AbstractFieldElement {
   FunctionElement getter;
   FunctionElement setter;
@@ -2202,6 +2222,12 @@
   void forEachInterfaceMember(f(MemberSignature member)) {
     interfaceMembers.forEach((_, member) => f(member));
   }
+
+  FunctionType get callType {
+    MemberSignature member =
+        lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
+    return member != null && member.isMethod ? member.type : null;
+  }
 }
 
 abstract class ClassElementX extends BaseClassElementX {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/names.dart b/sdk/lib/_internal/compiler/implementation/elements/names.dart
index 910f488..7dfdf3a 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/names.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/names.dart
@@ -35,9 +35,16 @@
   /// is returned.
   Name get setter;
 
-  /// Returned `true` an entity of this name is accessible from library
+  /// Returns `true` if an entity of this name is accessible from library
   /// [element].
   bool isAccessibleFrom(LibraryElement element);
+
+  /// Returns `true` if this name is private.
+  bool get isPrivate;
+
+  /// Returns `true` if this name is the same as [other] not taking the library
+  /// privacy into account.
+  bool isSimilarTo(Name other);
 }
 
 class PublicName implements Name {
@@ -52,13 +59,18 @@
 
   bool isAccessibleFrom(LibraryElement element) => true;
 
+  bool get isPrivate => false;
+
   int get hashCode => text.hashCode + 11 * isSetter.hashCode;
 
   bool operator ==(other) {
     if (other is! PublicName) return false;
-    return text == other.text && isSetter == other.isSetter;
+    return isSimilarTo(other);
   }
 
+  bool isSimilarTo(Name other) =>
+      text == other.text && isSetter == other.isSetter;
+
   String toString() => isSetter ? '$text=' : text;
 }
 
@@ -76,6 +88,8 @@
 
   bool isAccessibleFrom(LibraryElement element) => library == element;
 
+  bool get isPrivate => true;
+
   int get hashCode => super.hashCode + 13 * library.hashCode;
 
   bool operator ==(other) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart
new file mode 100644
index 0000000..e45a345
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart
@@ -0,0 +1,2328 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library concrete_types_inferrer;
+
+import 'dart:collection' show Queue, IterableBase;
+import '../native_handler.dart' as native;
+import '../dart2jslib.dart' hide Selector, TypedSelector;
+import '../dart_types.dart' show DartType, TypeKind;
+import '../elements/elements.dart';
+import '../tree/tree.dart';
+import '../universe/universe.dart';
+import '../util/util.dart';
+
+import 'inferrer_visitor.dart';
+import '../types/types.dart' show TypeMask, FlatTypeMask, UnionTypeMask,
+                                  TypesInferrer;
+import 'simple_types_inferrer.dart';
+
+/**
+ * A singleton concrete type. More precisely, a [BaseType] is one of the
+ * following:
+ *
+ *   - a non-asbtract class like [:int:] or [:Uri:] (but not [:List:])
+ *   - the null base type
+ *   - the unknown base type
+ */
+abstract class BaseType {
+  bool isClass();
+  bool isUnknown();
+  bool isNull();
+}
+
+/**
+ * A non-asbtract class like [:int:] or [:Uri:] (but not [:List:]).
+ */
+class ClassBaseType implements BaseType {
+  final ClassElement element;
+
+  ClassBaseType(this.element);
+
+  bool operator ==(var other) {
+    if (identical(this, other)) return true;
+    if (other is! ClassBaseType) return false;
+    return element == other.element;
+  }
+  int get hashCode => element.hashCode;
+  String toString() {
+    return element == null ? 'toplevel' : element.name;
+  }
+  bool isClass() => true;
+  bool isUnknown() => false;
+  bool isNull() => false;
+}
+
+/**
+ * The unknown base type.
+ */
+class UnknownBaseType implements BaseType {
+  const UnknownBaseType();
+  bool operator ==(BaseType other) => other is UnknownBaseType;
+  int get hashCode => 0;
+  bool isClass() => false;
+  bool isUnknown() => true;
+  bool isNull() => false;
+  toString() => "unknown";
+}
+
+/**
+ * The null base type.
+ */
+class NullBaseType implements BaseType {
+  const NullBaseType();
+  bool operator ==(BaseType other) => identical(other, this);
+  int get hashCode => 1;
+  bool isClass() => false;
+  bool isUnknown() => false;
+  bool isNull() => true;
+  toString() => "null";
+}
+
+/**
+ * An immutable set of base types like [:{int, bool}:], or the unknown concrete
+ * type.
+ */
+abstract class ConcreteType {
+  ConcreteType();
+
+  factory ConcreteType.empty(int maxConcreteTypeSize,
+                             BaseTypes classBaseTypes) {
+    return new UnionType(maxConcreteTypeSize, classBaseTypes,
+                         new Set<BaseType>());
+  }
+
+  /**
+   * The singleton constituted of the unknown base type is the unknown concrete
+   * type.
+   */
+  factory ConcreteType.singleton(int maxConcreteTypeSize,
+                                 BaseTypes classBaseTypes,
+                                 BaseType baseType) {
+    if (baseType.isUnknown() || maxConcreteTypeSize < 1) {
+      return const UnknownConcreteType();
+    }
+    Set<BaseType> singletonSet = new Set<BaseType>();
+    singletonSet.add(baseType);
+    return new UnionType(maxConcreteTypeSize, classBaseTypes, singletonSet);
+  }
+
+  factory ConcreteType.unknown() {
+    return const UnknownConcreteType();
+  }
+
+  ConcreteType union(ConcreteType other);
+  ConcreteType intersection(ConcreteType other);
+  ConcreteType refine(Selector selector, Compiler compiler);
+  bool isUnknown();
+  bool isEmpty();
+  Set<BaseType> get baseTypes;
+
+  /**
+   * Returns the unique element of [:this:] if [:this:] is a singleton, null
+   * otherwise.
+   */
+  ClassElement getUniqueType();
+}
+
+/**
+ * The unkown concrete type: it is absorbing for the union.
+ */
+class UnknownConcreteType implements ConcreteType {
+  const UnknownConcreteType();
+  bool isUnknown() => true;
+  bool isEmpty() => false;
+  bool operator ==(ConcreteType other) => identical(this, other);
+  Set<BaseType> get baseTypes =>
+      new Set<BaseType>.from([const UnknownBaseType()]);
+  int get hashCode => 0;
+  ConcreteType union(ConcreteType other) => this;
+  ConcreteType intersection(ConcreteType other) => other;
+  ConcreteType refine(Selector selector, Compiler compiler) => this;
+  ClassElement getUniqueType() => null;
+  toString() => "unknown";
+}
+
+/**
+ * An immutable set of base types, like [: {int, bool} :].
+ */
+class UnionType implements ConcreteType {
+  final int maxConcreteTypeSize;
+  final BaseTypes classBaseTypes;
+
+  final Set<BaseType> baseTypes;
+
+  /**
+   * The argument should NOT be mutated later. Do not call directly, use
+   * ConcreteType.singleton instead.
+   */
+  UnionType(this.maxConcreteTypeSize, this.classBaseTypes, this.baseTypes);
+
+  bool isUnknown() => false;
+  bool isEmpty() => baseTypes.isEmpty;
+
+  bool operator ==(ConcreteType other) {
+    if (other is! UnionType) return false;
+    if (baseTypes.length != other.baseTypes.length) return false;
+    return baseTypes.containsAll(other.baseTypes);
+  }
+
+  int get hashCode {
+    int result = 1;
+    for (final baseType in baseTypes) {
+      result = 31 * result + baseType.hashCode;
+    }
+    return result;
+  }
+
+  ConcreteType _simplify(Set<BaseType> baseTypes) {
+    // normalize all flavors of ints to int
+    // TODO(polux): handle different ints better
+    if (baseTypes.contains(classBaseTypes.uint31Type)) {
+      baseTypes.remove(classBaseTypes.uint31Type);
+      baseTypes.add(classBaseTypes.intBaseType);
+    }
+    if (baseTypes.contains(classBaseTypes.uint32Type)) {
+      baseTypes.remove(classBaseTypes.uint32Type);
+      baseTypes.add(classBaseTypes.intBaseType);
+    }
+    if (baseTypes.contains(classBaseTypes.positiveIntType)) {
+      baseTypes.remove(classBaseTypes.positiveIntType);
+      baseTypes.add(classBaseTypes.intBaseType);
+    }
+    // normalize {int, float}, {int, num} or {float, num} into num
+    // TODO(polux): generalize this to all types when we extend the concept of
+    //     "concrete type" to other abstract classes than num
+    if (baseTypes.contains(classBaseTypes.numBaseType) ||
+        (baseTypes.contains(classBaseTypes.intBaseType)
+            && baseTypes.contains(classBaseTypes.doubleBaseType))) {
+      baseTypes.remove(classBaseTypes.intBaseType);
+      baseTypes.remove(classBaseTypes.doubleBaseType);
+      baseTypes.add(classBaseTypes.numBaseType);
+    }
+
+    // widen big types to dynamic
+    return baseTypes.length > maxConcreteTypeSize
+        ? const UnknownConcreteType()
+        : new UnionType(maxConcreteTypeSize, classBaseTypes, baseTypes);
+  }
+
+  ConcreteType union(ConcreteType other) {
+    if (other.isUnknown()) {
+      return const UnknownConcreteType();
+    }
+    UnionType otherUnion = other;  // cast
+    Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes);
+    newBaseTypes.addAll(otherUnion.baseTypes);
+    return _simplify(newBaseTypes);
+  }
+
+  ConcreteType intersection(ConcreteType other) {
+    if (other.isUnknown()) {
+      return this;
+    }
+    Set<BaseType> thisBaseTypes = new Set<BaseType>.from(baseTypes);
+    Set<BaseType> otherBaseTypes = new Set<BaseType>.from(other.baseTypes);
+    return _simplify(thisBaseTypes.intersection(otherBaseTypes));
+  }
+
+  ConcreteType refine(Selector selector, Compiler compiler) {
+    Set<BaseType> newBaseTypes = new Set<BaseType>();
+    for (BaseType baseType in baseTypes) {
+      if (baseType.isClass()) {
+        ClassBaseType classBaseType = baseType;
+        if (classBaseType.element.lookupSelector(selector, compiler) != null) {
+          newBaseTypes.add(baseType);
+        }
+      } else {
+        newBaseTypes.add(baseType);
+      }
+    }
+    return _simplify(newBaseTypes);
+  }
+
+  ClassElement getUniqueType() {
+    if (baseTypes.length == 1) {
+      var iterator = baseTypes.iterator;
+      iterator.moveNext();
+      BaseType uniqueBaseType = iterator.current;
+      if (uniqueBaseType.isClass()) {
+        ClassBaseType uniqueClassType = uniqueBaseType;
+        return uniqueClassType.element;
+      }
+    }
+    return null;
+  }
+
+  String toString() => baseTypes.toString();
+}
+
+class ConcreteTypeSystem extends TypeSystem<ConcreteType> {
+  final Compiler compiler;
+  final ConcreteTypesInferrer inferrer;
+  final BaseTypes baseTypes;
+
+  final ConcreteType nullType;
+  final ConcreteType _intType;
+  final ConcreteType _uint31Type;
+  final ConcreteType _uint32Type;
+  final ConcreteType _positiveIntType;
+  final ConcreteType _doubleType;
+  final ConcreteType _numType;
+  final ConcreteType _boolType;
+  final ConcreteType _functionType;
+  final ConcreteType _listType;
+  final ConcreteType _constListType;
+  final ConcreteType _fixedListType;
+  final ConcreteType _growableListType;
+  final ConcreteType _mapType;
+  final ConcreteType _constMapType;
+  final ConcreteType _stringType;
+
+  final ConcreteType dynamicType;
+  final ConcreteType typeType;
+  final ConcreteType nonNullEmptyType;
+
+  ConcreteTypeSystem.internal(ConcreteTypesInferrer inferrer,
+                              BaseTypes baseTypes,
+                              ConcreteType singleton(BaseType baseType))
+      : this.compiler = inferrer.compiler
+      , this.inferrer = inferrer
+      , this.baseTypes = baseTypes
+      , this._constListType = singleton(baseTypes.constMapBaseType)
+      , this._constMapType = singleton(baseTypes.constMapBaseType)
+      , this._doubleType = singleton(baseTypes.doubleBaseType)
+      , this._fixedListType = singleton(baseTypes.fixedListBaseType)
+      , this._functionType = singleton(baseTypes.functionBaseType)
+      , this._growableListType = singleton(baseTypes.growableListBaseType)
+      , this._intType = singleton(baseTypes.intBaseType)
+      , this._listType = singleton(baseTypes.listBaseType)
+      , this._mapType = singleton(baseTypes.mapBaseType)
+      , this._numType = singleton(baseTypes.numBaseType)
+      , this._boolType = singleton(baseTypes.boolBaseType)
+      , this._stringType = singleton(baseTypes.stringBaseType)
+      , this.typeType = singleton(baseTypes.typeBaseType)
+      , this.dynamicType = const UnknownConcreteType()
+      , this.nullType = singleton(const NullBaseType())
+      , this.nonNullEmptyType = new ConcreteType.empty(
+          inferrer.compiler.maxConcreteTypeSize, baseTypes)
+      // TODO(polux): have better types here
+      , this._uint31Type = singleton(baseTypes.intBaseType)
+      , this._uint32Type = singleton(baseTypes.intBaseType)
+      , this._positiveIntType = singleton(baseTypes.intBaseType);
+
+  factory ConcreteTypeSystem(ConcreteTypesInferrer inferrer) {
+    Compiler compiler = inferrer.compiler;
+    BaseTypes baseTypes = new BaseTypes(compiler);
+    return new ConcreteTypeSystem.internal(
+        inferrer,
+        baseTypes,
+        (BaseType baseType) => new ConcreteType.singleton(
+            compiler.maxConcreteTypeSize, baseTypes, baseType));
+  }
+
+  @override
+  ConcreteType get intType {
+    inferrer.augmentSeenClasses(compiler.backend.intImplementation);
+    return _intType;
+  }
+
+  @override
+  ConcreteType get uint31Type {
+    inferrer.augmentSeenClasses(compiler.backend.uint31Implementation);
+    return _uint31Type;
+  }
+
+  @override
+  ConcreteType get uint32Type {
+    inferrer.augmentSeenClasses(compiler.backend.uint32Implementation);
+    return _uint32Type;
+  }
+
+  @override
+  ConcreteType get positiveIntType {
+    inferrer.augmentSeenClasses(compiler.backend.positiveIntImplementation);
+    return _positiveIntType;
+  }
+
+  @override
+  ConcreteType get doubleType {
+    inferrer.augmentSeenClasses(compiler.backend.doubleImplementation);
+    return _doubleType;
+  }
+
+  @override
+  ConcreteType get numType {
+    inferrer.augmentSeenClasses(compiler.backend.numImplementation);
+    return _numType;
+  }
+
+  @override
+  ConcreteType get boolType {
+    inferrer.augmentSeenClasses(compiler.backend.boolImplementation);
+    return _boolType;
+  }
+
+  @override
+  ConcreteType get functionType {
+    inferrer.augmentSeenClasses(compiler.backend.functionImplementation);
+    return _functionType;
+  }
+
+  @override
+  ConcreteType get listType {
+    inferrer.augmentSeenClasses(compiler.backend.listImplementation);
+    return _listType;
+  }
+
+  @override
+  ConcreteType get constListType {
+    inferrer.augmentSeenClasses(compiler.backend.constListImplementation);
+    return _constListType;
+  }
+
+  @override
+  ConcreteType get fixedListType {
+    inferrer.augmentSeenClasses(compiler.backend.fixedListImplementation);
+    return _fixedListType;
+  }
+
+  @override
+  ConcreteType get growableListType {
+    inferrer.augmentSeenClasses(compiler.backend.growableListImplementation);
+    return _growableListType;
+  }
+
+  @override
+  ConcreteType get mapType {
+    inferrer.augmentSeenClasses(compiler.backend.mapImplementation);
+    return _mapType;
+  }
+
+  @override
+  ConcreteType get constMapType {
+    inferrer.augmentSeenClasses(compiler.backend.constMapImplementation);
+    return _constMapType;
+  }
+
+  @override
+  ConcreteType get stringType {
+    inferrer.augmentSeenClasses(compiler.backend.stringImplementation);
+    return _stringType;
+  }
+
+  /**
+   * Returns the [TypeMask] representation of [baseType].
+   */
+  TypeMask baseTypeToTypeMask(BaseType baseType) {
+    if (baseType.isUnknown()) {
+      return const DynamicTypeMask();
+    } else if (baseType.isNull()) {
+      return new TypeMask.empty();
+    } else {
+      ClassBaseType classBaseType = baseType;
+      final element = classBaseType.element;
+      assert(element != null);
+      if (element == compiler.backend.numImplementation) {
+        return new TypeMask.nonNullSubclass(compiler.backend.numImplementation);
+      } else if (element == compiler.backend.intImplementation) {
+        return new TypeMask.nonNullSubclass(compiler.backend.intImplementation);
+      } else if (element == compiler.dynamicClass) {
+        return new TypeMask.nonNullSubclass(compiler.objectClass);
+      } else {
+        return new TypeMask.nonNullExact(element.declaration);
+      }
+    }
+  }
+
+  /**
+   * Returns the [TypeMask] representation of [concreteType].
+   */
+  TypeMask concreteTypeToTypeMask(ConcreteType concreteType) {
+    if (concreteType == null) return null;
+    TypeMask typeMask = new TypeMask.nonNullEmpty();
+    for (BaseType baseType in concreteType.baseTypes) {
+      TypeMask baseMask = baseTypeToTypeMask(baseType);
+      if (baseMask == const DynamicTypeMask()) return baseMask;
+      typeMask = typeMask.union(baseMask, compiler);
+    }
+    return typeMask;
+  }
+
+  @override
+  ConcreteType addPhiInput(Element element,
+                           ConcreteType phiType,
+                           ConcreteType newType) {
+    return computeLUB(phiType, newType);
+  }
+
+  @override
+  ConcreteType allocateDiamondPhi(ConcreteType firstInput,
+                                  ConcreteType secondInput) {
+    return computeLUB(firstInput, secondInput);
+  }
+
+  @override
+  ConcreteType allocatePhi(Node node, Element element, ConcreteType inputType) {
+    return inputType;
+  }
+
+  @override
+  ConcreteType computeLUB(ConcreteType firstType, ConcreteType secondType) {
+    if (firstType == null) {
+      return secondType;
+    } else if (secondType == null) {
+      return firstType;
+    } else {
+      return firstType.union(secondType);
+    }
+  }
+
+  // Implementation Inspired by
+  // type_graph_inferrer.TypeInformationSystem.narrowType
+  @override
+  ConcreteType narrowType(ConcreteType type,
+                          DartType annotation,
+                          {bool isNullable: true}) {
+    if (annotation.treatAsDynamic) return type;
+    if (annotation.isVoid) return nullType;
+    if (annotation.element == compiler.objectClass) return type;
+    ConcreteType otherType;
+    if (annotation.kind == TypeKind.TYPEDEF
+        || annotation.kind == TypeKind.FUNCTION) {
+      otherType = functionType;
+    } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
+      // TODO(polux): Narrow to bound.
+      return type;
+    } else {
+      assert(annotation.kind == TypeKind.INTERFACE);
+      otherType = nonNullSubtype(annotation.element);
+    }
+    if (isNullable) otherType = otherType.union(nullType);
+    if (type == null) return otherType;
+    return type.intersection(otherType);
+  }
+
+  @override
+  Selector newTypedSelector(ConcreteType receiver, Selector selector) {
+    return new TypedSelector(concreteTypeToTypeMask(receiver), selector);
+  }
+
+  @override
+  ConcreteType nonNullEmpty() {
+    return nonNullEmptyType;
+  }
+
+  @override
+  ConcreteType nonNullExact(ClassElement cls) {
+    return nonNullSubtype(cls);
+  }
+
+  /**
+   * Helper method for [nonNullSubtype] and [nonNullSubclass].
+   */
+  ConcreteType nonNullSubX(ClassElement cls,
+                           Set<ClassElement> extractor(ClassElement cls)) {
+    if (cls == compiler.objectClass) {
+      return dynamicType;
+    }
+    ConcreteType result = nonNullEmptyType;
+    void registerClass(ClassElement element) {
+      if (!element.isAbstract) {
+        result = result.union(
+            new ConcreteType.singleton(compiler.maxConcreteTypeSize,
+                                       baseTypes,
+                                       new ClassBaseType(element)));
+        inferrer.augmentSeenClasses(element);
+      }
+    }
+    registerClass(cls);
+    Set<ClassElement> subtypes = extractor(cls);
+    if (subtypes != null) {
+      subtypes.forEach(registerClass);
+    }
+    return result;
+  }
+
+  @override
+  ConcreteType nonNullSubclass(ClassElement cls) {
+    return nonNullSubX(cls, compiler.world.subclassesOf);
+  }
+
+  @override
+  ConcreteType nonNullSubtype(ClassElement cls) {
+    return nonNullSubX(cls, compiler.world.subtypesOf);
+  }
+
+  @override
+  ConcreteType simplifyPhi(Node node, Element element, ConcreteType phiType) {
+    return phiType;
+  }
+
+  @override
+  ConcreteType refineReceiver(Selector selector, ConcreteType receiverType) {
+    return receiverType.refine(selector, compiler);
+  }
+
+  @override
+  bool isNull(ConcreteType type) {
+    return (type.baseTypes.length == 1) && (type.baseTypes.first.isNull());
+  }
+
+  @override
+  ConcreteType allocateClosure(Node node, Element element) {
+    // TODO(polux): register closure here instead of in visitor?
+    return functionType;
+  }
+
+  @override
+  ConcreteType allocateList(ConcreteType type,
+                            Node node,
+                            Element enclosing,
+                            [ConcreteType elementType, int length]) {
+    if (elementType != null) {
+      inferrer.augmentListElementType(elementType);
+    }
+    return type;
+  }
+
+  @override
+  ConcreteType allocateMap(ConcreteType type,
+                           Node node,
+                           Element element,
+                           [ConcreteType keyType,
+                            ConcreteType valueType]) {
+    // TODO(polux): treat maps the same way we treat lists
+    return type;
+  }
+
+  @override
+  ConcreteType getConcreteTypeFor(TypeMask mask) {
+    if (mask.isUnion) {
+      UnionTypeMask union = mask;
+      return union.disjointMasks.fold(
+          nonNullEmptyType,
+          (type1, type2) => type1.union(getConcreteTypeFor(type2)));
+    } else {
+      FlatTypeMask flat = mask;
+      ConcreteType result;
+      if (flat.isEmpty) {
+        result = nonNullEmptyType;
+      } else if (flat.isExact) {
+        result = nonNullExact(flat.base);
+      } else if (flat.isSubclass) {
+        result = nonNullSubclass(flat.base);
+      } else if (flat.isSubtype) {
+        result = nonNullSubtype(flat.base);
+      } else {
+        throw new ArgumentError("unexpected mask");
+      }
+      return flat.isNullable ? result.union(nullType) : result;
+    }
+  }
+}
+
+/**
+ * The cartesian product of concrete types: an iterable of
+ * [ConcreteTypesEnvironment]s.
+ */
+class ConcreteTypeCartesianProduct
+    extends IterableBase<ConcreteTypesEnvironment> {
+  final ConcreteTypesInferrer inferrer;
+  final ClassElement typeOfThis;
+  final Map<Element, ConcreteType> concreteTypes;
+  ConcreteTypeCartesianProduct(this.inferrer, this.typeOfThis,
+                               this.concreteTypes);
+  Iterator get iterator => concreteTypes.isEmpty
+      ? [new ConcreteTypesEnvironment(typeOfThis)].iterator
+      : new ConcreteTypeCartesianProductIterator(inferrer, typeOfThis,
+                                                 concreteTypes);
+  String toString() => this.toList().toString();
+}
+
+/**
+ * An helper class for [ConcreteTypeCartesianProduct].
+ */
+class ConcreteTypeCartesianProductIterator
+    implements Iterator<ConcreteTypesEnvironment> {
+  final ConcreteTypesInferrer inferrer;
+  final ClassElement classOfThis;
+  final Map<Element, ConcreteType> concreteTypes;
+  final Map<Element, BaseType> nextValues;
+  final Map<Element, Iterator> state;
+  int size = 1;
+  int counter = 0;
+  ConcreteTypesEnvironment _current;
+
+  ConcreteTypeCartesianProductIterator(this.inferrer, this.classOfThis,
+      Map<Element, ConcreteType> concreteTypes)
+      : this.concreteTypes = concreteTypes,
+        nextValues = new Map<Element, BaseType>(),
+        state = new Map<Element, Iterator>() {
+    if (concreteTypes.isEmpty) {
+      size = 0;
+      return;
+    }
+    for (final e in concreteTypes.keys) {
+      final baseTypes = concreteTypes[e].baseTypes;
+      size *= baseTypes.length;
+    }
+  }
+
+  ConcreteTypesEnvironment get current => _current;
+
+  ConcreteTypesEnvironment takeSnapshot() {
+    Map<Element, ConcreteType> result = new Map<Element, ConcreteType>();
+    nextValues.forEach((k, v) {
+      result[k] = inferrer.singletonConcreteType(v);
+    });
+    return new ConcreteTypesEnvironment.of(result, classOfThis);
+  }
+
+  bool moveNext() {
+    if (counter >= size) {
+      _current = null;
+      return false;
+    }
+    Element keyToIncrement = null;
+    for (final key in concreteTypes.keys) {
+      final iterator = state[key];
+      if (iterator != null && iterator.moveNext()) {
+        nextValues[key] = state[key].current;
+        break;
+      }
+      Iterator newIterator = concreteTypes[key].baseTypes.iterator;
+      state[key] = newIterator;
+      newIterator.moveNext();
+      nextValues[key] = newIterator.current;
+    }
+    counter++;
+    _current = takeSnapshot();
+    return true;
+  }
+}
+
+/**
+ * [BaseType] Constants.
+ */
+class BaseTypes {
+  final ClassBaseType intBaseType;
+  final ClassBaseType doubleBaseType;
+  final ClassBaseType numBaseType;
+  final ClassBaseType boolBaseType;
+  final ClassBaseType stringBaseType;
+  final ClassBaseType listBaseType;
+  final ClassBaseType growableListBaseType;
+  final ClassBaseType fixedListBaseType;
+  final ClassBaseType constListBaseType;
+  final ClassBaseType mapBaseType;
+  final ClassBaseType constMapBaseType;
+  final ClassBaseType objectBaseType;
+  final ClassBaseType typeBaseType;
+  final ClassBaseType functionBaseType;
+  final ClassBaseType uint31Type;
+  final ClassBaseType uint32Type;
+  final ClassBaseType positiveIntType;
+
+  BaseTypes(Compiler compiler) :
+    intBaseType = new ClassBaseType(compiler.backend.intImplementation),
+    doubleBaseType = new ClassBaseType(compiler.backend.doubleImplementation),
+    numBaseType = new ClassBaseType(compiler.backend.numImplementation),
+    boolBaseType = new ClassBaseType(compiler.backend.boolImplementation),
+    stringBaseType = new ClassBaseType(compiler.backend.stringImplementation),
+    listBaseType = new ClassBaseType(compiler.backend.listImplementation),
+    growableListBaseType =
+        new ClassBaseType(compiler.backend.growableListImplementation),
+    fixedListBaseType =
+        new ClassBaseType(compiler.backend.fixedListImplementation),
+    constListBaseType =
+        new ClassBaseType(compiler.backend.constListImplementation),
+    mapBaseType = new ClassBaseType(compiler.backend.mapImplementation),
+    constMapBaseType =
+        new ClassBaseType(compiler.backend.constMapImplementation),
+    objectBaseType = new ClassBaseType(compiler.objectClass),
+    typeBaseType = new ClassBaseType(compiler.backend.typeImplementation),
+    functionBaseType =
+        new ClassBaseType(compiler.backend.functionImplementation),
+    uint31Type = new ClassBaseType(compiler.backend.uint31Implementation),
+    uint32Type = new ClassBaseType(compiler.backend.uint32Implementation),
+    positiveIntType =
+        new ClassBaseType(compiler.backend.positiveIntImplementation);
+}
+
+/**
+ * An immutable mapping from method arguments to [ConcreteTypes].
+ */
+class ConcreteTypesEnvironment {
+  final Map<Element, ConcreteType> environment;
+  final ClassElement classOfThis;
+
+  ConcreteTypesEnvironment([this.classOfThis]) :
+      environment = new Map<Element, ConcreteType>();
+  ConcreteTypesEnvironment.of(this.environment, this.classOfThis);
+
+  ConcreteType lookupType(Element element) => environment[element];
+
+  bool operator ==(ConcreteTypesEnvironment other) {
+    if (other is! ConcreteTypesEnvironment) return false;
+    if (classOfThis != other.classOfThis) return false;
+    if (environment.length != other.environment.length) return false;
+    for (Element key in environment.keys) {
+      if (!other.environment.containsKey(key)
+          || (environment[key] != other.environment[key])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  int get hashCode {
+    int result = (classOfThis != null) ? classOfThis.hashCode : 1;
+    environment.forEach((element, concreteType) {
+      result = 31 * (31 * result + element.hashCode) + concreteType.hashCode;
+    });
+    return result;
+  }
+
+  String toString() => "{ this: $classOfThis, env: $environment }";
+}
+
+class ClosureEnvironment {
+  ConcreteType thisType;
+  final LocalsHandler locals;
+
+  ClosureEnvironment(this.thisType, this.locals);
+
+  bool mergeLocals(LocalsHandler newLocals) {
+    assert((locals == null) == (newLocals == null));
+    return (locals != null) ? locals.mergeAll([newLocals]) : false;
+  }
+
+  /// Returns true if changed.
+  bool merge(ConcreteType thisType, LocalsHandler locals) {
+    ConcreteType oldThisType = this.thisType;
+    if (this.thisType == null) {
+      this.thisType = thisType;
+    } else if (thisType != null) {
+      this.thisType = this.thisType.union(thisType);
+    }
+    return mergeLocals(locals) || (this.thisType != oldThisType);
+  }
+
+  toString() => "ClosureEnvironment { thisType = $thisType, locals = ... }";
+}
+
+/**
+ * A set of encoutered closures.
+ */
+class Closures {
+  final Compiler compiler;
+  final Map<FunctionElement, ClosureEnvironment> closures =
+      new Map<FunctionElement, ClosureEnvironment>();
+
+  Closures(this.compiler);
+
+  /// Returns true if the environment of the closure has changed.
+  bool put(FunctionElement closure,
+           ConcreteType typeOfThis,
+           LocalsHandler locals) {
+    ClosureEnvironment oldEnvironent = closures[closure];
+    if (oldEnvironent == null) {
+      closures[closure] = new ClosureEnvironment(typeOfThis, locals);
+      return true;
+    } else {
+      return oldEnvironent.merge(typeOfThis, locals);
+    }
+  }
+
+  ClosureEnvironment getEnvironmentOrNull(FunctionElement function) {
+    return closures[function];
+  }
+
+  Iterable<FunctionElement> get functionElements => closures.keys;
+
+  bool contains(FunctionElement function) => closures.containsKey(function);
+
+  String toString() => closures.toString();
+}
+
+/**
+ * A work item for the type inference queue.
+ */
+class InferenceWorkItem {
+  Element method;
+  ConcreteTypesEnvironment environment;
+  InferenceWorkItem(this.method, this.environment);
+
+  toString() => "{ method = $method, environment = $environment }";
+
+  bool operator ==(other) {
+    return (other is InferenceWorkItem)
+        && method == other.method
+        && environment == other.environment;
+  }
+
+  int get hashCode => 31 * method.hashCode + environment.hashCode;
+}
+
+/**
+ * A sentinel type mask class representing the dynamicType. It is absorbing
+ * for [:ConcreteTypesEnvironment.typeMaskUnion:].
+ */
+class DynamicTypeMask implements TypeMask {
+  const DynamicTypeMask();
+
+  String toString() => 'sentinel type mask';
+
+  TypeMask nullable() {
+    throw new UnsupportedError("");
+  }
+
+  TypeMask nonNullable() {
+    throw new UnsupportedError("");
+  }
+
+  bool get isEmpty {
+    throw new UnsupportedError("");
+  }
+
+  bool get isNullable {
+    throw new UnsupportedError("");
+  }
+
+  bool get isExact {
+    throw new UnsupportedError("");
+  }
+
+  bool get isUnion {
+    throw new UnsupportedError("");
+  }
+
+  bool get isContainer {
+    throw new UnsupportedError("");
+  }
+
+  bool get isForwarding {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnlyInt(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnlyDouble(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnlyNum(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnlyBool(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnlyString(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsOnly(ClassElement element) {
+    throw new UnsupportedError("");
+  }
+
+  bool satisfies(ClassElement cls, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool contains(ClassElement type, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsAll(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  ClassElement singleClass(Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  TypeMask union(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  TypeMask intersection(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool canHit(Element element, Selector selector, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  Element locateSingleElement(Selector selector, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool isInMask(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsMask(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool get isMap {
+    throw new UnsupportedError("");
+  }
+}
+
+class WorkQueue {
+  final Queue<InferenceWorkItem> queue = new Queue<InferenceWorkItem>();
+
+  void add(InferenceWorkItem workItem) {
+    if (!queue.contains(workItem)) {
+      queue.addLast(workItem);
+    }
+  }
+
+  InferenceWorkItem remove() {
+    return queue.removeFirst();
+  }
+
+  bool get isEmpty => queue.isEmpty;
+}
+
+/**
+ * A task which conservatively infers a [ConcreteType] for each sub expression
+ * of the program. The entry point is [analyzeMain].
+ */
+class ConcreteTypesInferrer
+    extends InferrerEngine<ConcreteType, ConcreteTypeSystem>
+    implements TypesInferrer {
+
+  final String name = "Type inferrer";
+
+  /**
+   * When true, the string literal [:"__dynamic_for_test":] is inferred to
+   * have the unknown type.
+   */
+  // TODO(polux): get rid of this hack once we have a natural way of inferring
+  // the unknown type.
+  bool testMode = false;
+
+  // --- constants ---
+
+  /**
+   * Constants representing builtin base types. Initialized by [initialize]
+   * and not by the constructor because the compiler elements are not yet
+   * populated.
+   */
+  BaseTypes baseTypes;
+
+  /** The associated type system */
+  ConcreteTypeSystem types;
+
+  /**
+   * Constant representing [:ConcreteList#[]:] where [:ConcreteList:] is the
+   * concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listIndex;
+
+  /**
+   * Constant representing [:ConcreteList#[]=:] where [:ConcreteList:] is the
+   * concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listIndexSet;
+
+  /**
+   * Constant representing [:ConcreteList#add:] where [:ConcreteList:] is the
+   * concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listAdd;
+
+  /**
+   * Constant representing [:ConcreteList#removeAt:] where [:ConcreteList:] is
+   * the concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listRemoveAt;
+
+  /**
+   * Constant representing [:ConcreteList#insert:] where [:ConcreteList:] is
+   * the concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listInsert;
+
+  /**
+   * Constant representing [:ConcreteList#removeLast:] where [:ConcreteList:] is
+   * the concrete implementation of lists for the selected backend.
+   */
+  FunctionElement listRemoveLast;
+
+  /** Constant representing [:List():]. */
+  FunctionElement listConstructor;
+
+  /** The unknown concrete type */
+  final ConcreteType unknownConcreteType;
+
+  /** The empty concrete type */
+  ConcreteType emptyConcreteType;
+
+  /** The null concrete type */
+  ConcreteType nullConcreteType;
+
+  // --- state updated by the inference ---
+
+  /**
+   * A map from (function x argument base types) to their inferred concrete
+   * type. Another way of seeing [methodToTemplates] is as a map from
+   * [FunctionElement]s to "templates" in the sense of "The Cartesian Product
+   * Algorithm - Simple and Precise Type Inference of Parametric Polymorphism"
+   * by Ole Agesen.
+   */
+  // TODO(polux): build a better abstraction, like Closures
+  final Map<FunctionElement, Map<ConcreteTypesEnvironment, ConcreteType>>
+      methodToTemplates;
+
+  /** The set of encountered closures. */
+  final Closures closures;
+
+  /** A map from expressions to their inferred concrete types. */
+  final Map<Node, ConcreteType> inferredTypes;
+
+  /** A map from fields to their inferred concrete types. */
+  final Map<Element, ConcreteType> inferredFieldTypes;
+
+  /**
+   * [:callers[f]:] is the list of [:f:]'s possible callers or fields
+   * whose initialization is a call to [:f:].
+   */
+  final Map<FunctionElement, Set<Element>> callers;
+
+  /**
+   * [:readers[field]:] is the list of [:field:]'s possible readers or fields
+   * whose initialization is a read of [:field:].
+   */
+  final Map<Element, Set<Element>> fieldReaders;
+
+  /**
+   * [:readers[local]:] is the list of [:local:]'s possible readers.
+   */
+  final Map<Element, Set<Element>> capuredLocalsReaders;
+
+  /// The set of classes encountered so far.
+  final Set<ClassElement> seenClasses;
+
+  /**
+   * A map from selector names to callers of methods with this name on objects
+   * of unknown inferred type.
+   */
+  final Map<String, Set<FunctionElement>> dynamicCallers;
+
+  /** The inferred type of elements stored in Lists. */
+  ConcreteType listElementType;
+
+  /**
+   * A map from parameters to their inferred concrete types. It plays no role
+   * in the analysis, it is write only.
+   */
+  final Map<VariableElement, ConcreteType> inferredParameterTypes;
+
+  /**
+   * A map from selectors to their inferred type masks, indexed by the mask
+   * of the receiver. It plays no role in the analysis, it is write only.
+   */
+  final Map<Selector, Map<TypeMask, TypeMask>> inferredSelectorTypes;
+
+  /** The work queue consumed by [analyzeMain]. */
+  final WorkQueue workQueue;
+
+  /** The item being worked on. */
+  InferenceWorkItem currentWorkItem;
+
+  ConcreteTypesInferrer(Compiler compiler)
+      : methodToTemplates = new Map<FunctionElement,
+            Map<ConcreteTypesEnvironment, ConcreteType>>(),
+        closures = new Closures(compiler),
+        inferredTypes = new Map<Node, ConcreteType>(),
+        inferredFieldTypes = new Map<Element, ConcreteType>(),
+        inferredParameterTypes = new Map<VariableElement, ConcreteType>(),
+        workQueue = new WorkQueue(),
+        callers = new Map<FunctionElement, Set<Element>>(),
+        fieldReaders = new Map<Element, Set<Element>>(),
+        capuredLocalsReaders = new Map<VariableElement,
+            Set<FunctionElement>>(),
+        seenClasses = new Set<ClassElement>(),
+        dynamicCallers = new Map<String, Set<FunctionElement>>(),
+        inferredSelectorTypes = new Map<Selector, Map<TypeMask, TypeMask>>(),
+        unknownConcreteType = new ConcreteType.unknown(),
+        super(compiler, null);
+
+  /* Initialization code that cannot be run in the constructor because it
+   * requires the compiler's elements to be populated.
+   */
+  void initialize() {
+    baseTypes = new BaseTypes(compiler);
+    types = new ConcreteTypeSystem(this);
+    ClassElement jsArrayClass = baseTypes.listBaseType.element;
+    listIndex = jsArrayClass.lookupMember('[]');
+    listIndexSet = jsArrayClass.lookupMember('[]=');
+    listAdd = jsArrayClass.lookupMember('add');
+    listRemoveAt = jsArrayClass.lookupMember('removeAt');
+    listInsert = jsArrayClass.lookupMember('insert');
+    listRemoveLast =
+        jsArrayClass.lookupMember('removeLast');
+    List<String> typePreservingOps = const ['+', '-', '*'];
+    listConstructor =
+        compiler.listClass.lookupConstructor(
+            new Selector.callConstructor(
+                '',
+                compiler.listClass.getLibrary())).implementation;
+    emptyConcreteType = new ConcreteType.empty(compiler.maxConcreteTypeSize,
+                                               baseTypes);
+    nullConcreteType = singletonConcreteType(const NullBaseType());
+    listElementType = emptyConcreteType;
+  }
+
+  // --- utility methods ---
+
+  /** Creates a singleton concrete type containing [baseType]. */
+  ConcreteType singletonConcreteType(BaseType baseType) {
+    return new ConcreteType.singleton(compiler.maxConcreteTypeSize, baseTypes,
+                                      baseType);
+  }
+
+  /**
+   * Computes the union of [mask1] and [mask2] where [mask1] and [mask2] are
+   * possibly equal to [: DynamicTypeMask.instance :].
+   */
+  TypeMask typeMaskUnion(TypeMask mask1, TypeMask mask2) {
+    if (mask1 == const DynamicTypeMask() || mask2 == const DynamicTypeMask()) {
+      return const DynamicTypeMask();
+    }
+    return mask1.union(mask2, compiler);
+  }
+
+  /**
+   * Returns all the members matching [selector].
+   */
+  Set<Element> getMembersBySelector(Selector selector) {
+    // TODO(polux): memoize?
+    Set<Element> result = new Set<Element>();
+    for (ClassElement cls in seenClasses) {
+      Element elem = cls.lookupSelector(selector, compiler);
+      if (elem != null) {
+        result.add(elem.implementation);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns all the subtypes of [cls], [cls] included.
+   */
+  Set<ClassElement> getReflexiveSubtypesOf(ClassElement cls) {
+    // TODO(polux): memoize?
+    Set<ClassElement> result = new Set<ClassElement>()..add(cls);
+    for (ClassElement candidate in seenClasses) {
+      if (compiler.world.isSubtype(cls, candidate)) {
+        result.add(candidate);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Sets the concrete type associated to [node] to the union of the inferred
+   * concrete type so far and of [type].
+   */
+  void augmentInferredType(Node node, ConcreteType type) {
+    ConcreteType currentType = inferredTypes[node];
+    inferredTypes[node] =
+        (currentType == null) ? type : currentType.union(type);
+  }
+
+  /**
+   * Sets the concrete type associated to [selector] to the union of the
+   * inferred concrete type so far and of [returnType].
+   *
+   * Precondition: [:(typeOfThis != null) && (returnType != null):]
+   */
+  void augmentInferredSelectorType(Selector selector, TypeMask typeOfThis,
+                                   TypeMask returnType) {
+    assert(returnType != null);
+    assert(typeOfThis != null);
+
+    selector = selector.asUntyped;
+    Map<TypeMask, TypeMask> currentMap = inferredSelectorTypes.putIfAbsent(
+        selector, () => new Map<TypeMask, TypeMask>());
+    TypeMask currentReturnType = currentMap[typeOfThis];
+    currentMap[typeOfThis] = (currentReturnType == null)
+        ? returnType
+        : typeMaskUnion(currentReturnType, returnType);
+  }
+
+  /**
+   * Returns the current inferred concrete type of [field].
+   */
+  ConcreteType getFieldType(Selector selector, Element field) {
+    ConcreteType result = inferredFieldTypes[field];
+    if (result == null) {
+      // field is a toplevel variable, we trigger its analysis because no object
+      // creation is ever going to trigger it
+      result = analyzeFieldInitialization(field);
+      return (result == null) ? emptyConcreteType : result;
+    }
+    if (selector != null) {
+      Element enclosing = field.enclosingElement;
+      if (enclosing.isClass()) {
+        ClassElement cls = enclosing;
+        TypeMask receiverMask = new TypeMask.exact(cls.declaration);
+        TypeMask resultMask = types.concreteTypeToTypeMask(result);
+        augmentInferredSelectorType(selector, receiverMask, resultMask);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Sets the concrete type associated to [field] to the union of the inferred
+   * concrete type so far and of [type].
+   */
+  void augmentFieldType(Element field, ConcreteType type) {
+    ConcreteType oldType = inferredFieldTypes[field];
+    ConcreteType newType = (oldType != null) ? oldType.union(type) : type;
+    if (oldType != newType) {
+      inferredFieldTypes[field] = newType;
+      final readers = fieldReaders[field];
+      if (readers != null) {
+        readers.forEach(invalidate);
+      }
+    }
+  }
+
+  /** Augment the inferred type of elements stored in Lists. */
+  void augmentListElementType(ConcreteType type) {
+    ConcreteType newType = listElementType.union(type);
+    if (newType != listElementType) {
+      invalidateCallers(listIndex);
+      listElementType = newType;
+    }
+  }
+
+  /**
+   * Sets the concrete type associated to [parameter] to the union of the
+   * inferred concrete type so far and of [type].
+   */
+  void augmentParameterType(VariableElement parameter, ConcreteType type) {
+    ConcreteType oldType = inferredParameterTypes[parameter];
+    inferredParameterTypes[parameter] =
+        (oldType == null) ? type : oldType.union(type);
+  }
+
+  /** Augments the set of classes encountered so far. */
+  void augmentSeenClasses(ClassElement cls) {
+    if (!seenClasses.contains(cls)) {
+      seenClasses.add(cls);
+      cls.forEachMember((_, Element member) {
+        Set<FunctionElement> functions = dynamicCallers[member.name];
+        if (functions != null) {
+          functions.forEach(invalidate);
+        }
+      }, includeSuperAndInjectedMembers: true);
+    }
+  }
+
+  /**
+   * Add [caller] to the set of [callee]'s callers.
+   */
+  void addCaller(FunctionElement callee, Element caller) {
+    callers.putIfAbsent(callee, () => new Set<Element>())
+           .add(caller);
+  }
+
+  /**
+   * Add [caller] to the set of [callee]'s dynamic callers.
+   */
+  void addDynamicCaller(Selector callee, FunctionElement caller) {
+      dynamicCallers
+          .putIfAbsent(callee.name, () => new Set<FunctionElement>())
+          .add(caller);
+  }
+
+  /**
+   * Add [reader] to the set of [field]'s readers.
+   */
+  void addFieldReader(Element field, Element reader) {
+    fieldReaders.putIfAbsent(field, () => new Set<Element>())
+                .add(reader);
+  }
+
+  /**
+   * Add [reader] to the set of [local]'s readers.
+   */
+  void addCapturedLocalReader(VariableElement local, FunctionElement reader) {
+    capuredLocalsReaders.putIfAbsent(local, () => new Set<FunctionElement>())
+                        .add(reader);
+  }
+
+  /**
+   * Add a closure to the set of seen closures. Invalidate callers if
+   * the set of locals has changed.
+   */
+  void addClosure(FunctionElement closure,
+                  ConcreteType typeOfThis,
+                  LocalsHandler locals) {
+    if (closures.put(closure, typeOfThis, locals)) {
+      invalidateCallers(closure);
+    }
+  }
+
+  /**
+   * Invalidate all callers of [function].
+   */
+  void invalidateCallers(FunctionElement function) {
+    Set<Element> methodCallers = callers[function];
+    if (methodCallers != null) {
+      methodCallers.forEach(invalidate);
+    }
+  }
+
+  /**
+   * Add all templates of [methodOrField] to the workqueue.
+   */
+  void invalidate(Element methodOrField) {
+    if (methodOrField.isField()) {
+      workQueue.add(new InferenceWorkItem(
+          methodOrField, new ConcreteTypesEnvironment()));
+    } else {
+      Map<ConcreteTypesEnvironment, ConcreteType> templates =
+          methodToTemplates[methodOrField];
+      if (templates != null) {
+        templates.forEach((environment, _) {
+          workQueue.add(
+              new InferenceWorkItem(methodOrField, environment));
+        });
+      }
+    }
+  }
+
+  /**
+   * Returns the template associated to [function] or create an empty template
+   * for [function] return it.
+   */
+  // TODO(polux): encapsulate this in an abstraction for templates
+  Map<ConcreteTypesEnvironment, ConcreteType>
+      getTemplatesOrEmpty(FunctionElement function) {
+    return methodToTemplates.putIfAbsent(
+        function,
+        () => new Map<ConcreteTypesEnvironment, ConcreteType>());
+  }
+
+  // -- methods of types.TypesInferrer (interface with the backend) --
+
+  /** Get the inferred concrete type of [node]. */
+  @override
+  TypeMask getTypeOfNode(Element owner, Node node) {
+    TypeMask result = types.concreteTypeToTypeMask(inferredTypes[node]);
+    return (result == const DynamicTypeMask()) ? null : result;
+  }
+
+  /** Get the inferred concrete type of [element]. */
+  @override
+  TypeMask getTypeOfElement(Element element) {
+    final result = types.concreteTypeToTypeMask(typeOfElement(element));
+    return (result == const DynamicTypeMask()) ? null : result;
+  }
+
+  /**
+   * Get the inferred concrete return type of [element]. A null return value
+   * means "I don't know".
+   */
+  @override
+  TypeMask getReturnTypeOfElement(Element element) {
+    assert(element is FunctionElement);
+    Map<ConcreteTypesEnvironment, ConcreteType> templates =
+        methodToTemplates[element];
+    if (templates == null) return null;
+    ConcreteType returnType = emptyConcreteType;
+    templates.forEach((_, concreteType) {
+      returnType = returnType.union(concreteType);
+    });
+    TypeMask result = types.concreteTypeToTypeMask(returnType);
+    return (result == const DynamicTypeMask()) ? null : result;
+  }
+
+  /**
+   * Get the inferred concrete type of [selector]. A null return value means
+   * "I don't know".
+   */
+  @override
+  TypeMask getTypeOfSelector(Selector selector) {
+    Map<TypeMask, TypeMask> candidates =
+        inferredSelectorTypes[selector.asUntyped];
+    if (candidates == null) {
+      return null;
+    }
+    TypeMask result = new TypeMask.nonNullEmpty();
+    if (selector.mask == null) {
+      candidates.forEach((TypeMask receiverType, TypeMask returnType) {
+        result = typeMaskUnion(result, returnType);
+      });
+    } else {
+      candidates.forEach((TypeMask receiverType, TypeMask returnType) {
+        TypeMask intersection =
+            receiverType.intersection(selector.mask, compiler);
+        if (!intersection.isEmpty || intersection.isNullable) {
+          result = typeMaskUnion(result, returnType);
+        }
+      });
+    }
+    return result == const DynamicTypeMask() ? null : result;
+  }
+
+  @override
+  void clear() {
+    throw new UnsupportedError("clearing is not yet implemented");
+  }
+
+  @override
+  bool isCalledOnce(Element element) {
+    // Never called by SimpleTypeInferrer.
+    throw new UnsupportedError("");
+  }
+
+  @override
+  bool isFixedArrayCheckedForGrowable(Node node) {
+    // Never called by SimpleTypeInferrer.
+    throw new UnsupportedError("");
+  }
+
+  // --- analysis ---
+
+  /**
+   * Returns the concrete type returned by [function] given arguments of
+   * concrete types [argumentsTypes]. If [function] is static then
+   * [receiverType] must be null, else [function] must be a member of
+   * [receiverType].
+   */
+  ConcreteType getSendReturnType(Selector selector,
+                                 FunctionElement function,
+                                 ClassElement receiverType,
+                                 ArgumentsTypes<ConcreteType> argumentsTypes) {
+    assert(function != null);
+
+    ConcreteType result = emptyConcreteType;
+    Map<Element, ConcreteType> argumentMap =
+        associateArguments(function, argumentsTypes);
+    // if the association failed, this send will never occur or will fail
+    if (argumentMap == null) {
+      return emptyConcreteType;
+    }
+
+    argumentMap.forEach(augmentParameterType);
+    ConcreteTypeCartesianProduct product =
+        new ConcreteTypeCartesianProduct(this, receiverType, argumentMap);
+    for (ConcreteTypesEnvironment environment in product) {
+      result = result.union(
+          getMonomorphicSendReturnType(function, environment));
+    }
+
+    if (selector != null && receiverType != null) {
+      // TODO(polux): generalize to any abstract class if we ever handle other
+      // abstract classes than num.
+      TypeMask receiverMask =
+          (receiverType == compiler.backend.numImplementation
+          || receiverType == compiler.backend.intImplementation)
+              ? new TypeMask.nonNullSubclass(receiverType.declaration)
+              : new TypeMask.nonNullExact(receiverType.declaration);
+      TypeMask resultMask = types.concreteTypeToTypeMask(result);
+      augmentInferredSelectorType(selector, receiverMask, resultMask);
+    }
+
+    return result;
+  }
+
+  /**
+   * Given a method signature and a list of concrete types, builds a map from
+   * formals to their corresponding concrete types. Returns null if the
+   * association is impossible (for instance: too many arguments).
+   */
+  Map<Element, ConcreteType> associateArguments(
+      FunctionElement function,
+      ArgumentsTypes<ConcreteType> argumentsTypes) {
+    final Map<Element, ConcreteType> result = new Map<Element, ConcreteType>();
+    final FunctionSignature signature = function.computeSignature(compiler);
+
+    // guard 1: too many arguments
+    if (argumentsTypes.length > signature.parameterCount) {
+      return null;
+    }
+    // guard 2: not enough arguments
+    if (argumentsTypes.positional.length < signature.requiredParameterCount) {
+      return null;
+    }
+    // guard 3: too many positional arguments
+    if (signature.optionalParametersAreNamed &&
+        argumentsTypes.positional.length > signature.requiredParameterCount) {
+      return null;
+    }
+
+    handleLeftoverOptionalParameter(Element parameter) {
+      Send send = parameter.parseNode(compiler).asSendSet();
+      result[parameter] = (send == null)
+          ? nullConcreteType
+          : analyzeDefaultValue(function, send.arguments.head);
+    }
+
+    final Iterator<ConcreteType> remainingPositionalArguments =
+        argumentsTypes.positional.iterator;
+    // we attach each positional parameter to its corresponding positional
+    // argument
+    for (Link<Element> requiredParameters = signature.requiredParameters;
+        !requiredParameters.isEmpty;
+        requiredParameters = requiredParameters.tail) {
+      final Element requiredParameter = requiredParameters.head;
+      // we know moveNext() succeeds because of guard 2
+      remainingPositionalArguments.moveNext();
+      result[requiredParameter] = remainingPositionalArguments.current;
+    }
+    if (signature.optionalParametersAreNamed) {
+      // we build a map out of the remaining named parameters
+      Link<Element> remainingOptionalParameters = signature.optionalParameters;
+      final Map<String, Element> leftOverNamedParameters =
+          new Map<String, Element>();
+      for (;
+           !remainingOptionalParameters.isEmpty;
+           remainingOptionalParameters = remainingOptionalParameters.tail) {
+        final Element namedParameter = remainingOptionalParameters.head;
+        leftOverNamedParameters[namedParameter.name] = namedParameter;
+      }
+      // we attach the named arguments to their corresponding optional
+      // parameters
+      for (String source in argumentsTypes.named.keys) {
+        final ConcreteType concreteType = argumentsTypes.named[source];
+        final Element namedParameter = leftOverNamedParameters[source];
+        // unexisting or already used named parameter
+        if (namedParameter == null) return null;
+        result[namedParameter] = concreteType;
+        leftOverNamedParameters.remove(source);
+      }
+      leftOverNamedParameters.forEach((_, Element parameter) {
+        handleLeftoverOptionalParameter(parameter);
+      });
+    } else { // optional parameters are positional
+      // we attach the remaining positional arguments to their corresponding
+      // optional parameters
+      Link<Element> remainingOptionalParameters = signature.optionalParameters;
+      while (remainingPositionalArguments.moveNext()) {
+        final Element optionalParameter = remainingOptionalParameters.head;
+        result[optionalParameter] = remainingPositionalArguments.current;
+        // we know tail is defined because of guard 1
+        remainingOptionalParameters = remainingOptionalParameters.tail;
+      }
+      for (;
+           !remainingOptionalParameters.isEmpty;
+           remainingOptionalParameters = remainingOptionalParameters.tail) {
+        handleLeftoverOptionalParameter(remainingOptionalParameters.head);
+      }
+    }
+    return result;
+  }
+
+  ConcreteType getMonomorphicSendReturnType(
+      FunctionElement function,
+      ConcreteTypesEnvironment environment) {
+    Map<ConcreteTypesEnvironment, ConcreteType> template =
+        getTemplatesOrEmpty(function);
+    ConcreteType type = template[environment];
+    ConcreteType specialType = getSpecialCaseReturnType(function, environment);
+    if (type != null) {
+      return specialType != null ? specialType : type;
+    } else {
+      workQueue.add(new InferenceWorkItem(function, environment));
+      return specialType != null ? specialType : emptyConcreteType;
+    }
+  }
+
+  /**
+   * Handles external methods that cannot be cached because they depend on some
+   * other state of [ConcreteTypesInferrer] like [:List#[]:] and
+   * [:List#[]=:]. Returns null if [function] and [environment] don't form a
+   * special case
+   */
+  ConcreteType getSpecialCaseReturnType(FunctionElement function,
+                                        ConcreteTypesEnvironment environment) {
+    // Handles int + int, double + double, int - int, ...
+    // We cannot compare function to int#+, int#-, etc. because int and double
+    // don't override these methods. So for 1+2, getSpecialCaseReturnType will
+    // be invoked with function = num#+. We use environment.typeOfThis instead.
+    ClassElement cls = environment.classOfThis;
+    if (cls != null) {
+      String name = function.name;
+      if ((cls == baseTypes.intBaseType.element
+          || cls == baseTypes.doubleBaseType.element)
+          && (name == '+' || name == '-' || name == '*')) {
+        Link<Element> parameters =
+            function.functionSignature.requiredParameters;
+        ConcreteType argumentType = environment.lookupType(parameters.head);
+        if (argumentType.getUniqueType() == cls) {
+          return singletonConcreteType(new ClassBaseType(cls));
+        }
+      }
+    }
+
+    if (function == listIndex || function == listRemoveAt) {
+      Link<Element> parameters = function.functionSignature.requiredParameters;
+      ConcreteType indexType = environment.lookupType(parameters.head);
+      if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
+        return emptyConcreteType;
+      }
+      return listElementType;
+    } else if (function == listIndexSet || function == listInsert) {
+      Link<Element> parameters = function.functionSignature.requiredParameters;
+      ConcreteType indexType = environment.lookupType(parameters.head);
+      if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
+        return emptyConcreteType;
+      }
+      ConcreteType elementType = environment.lookupType(parameters.tail.head);
+      augmentListElementType(elementType);
+      return emptyConcreteType;
+    } else if (function == listAdd) {
+      Link<Element> parameters = function.functionSignature.requiredParameters;
+      ConcreteType elementType = environment.lookupType(parameters.head);
+      augmentListElementType(elementType);
+      return emptyConcreteType;
+    } else if (function == listRemoveLast) {
+      return listElementType;
+    }
+    return null;
+  }
+
+  ConcreteType analyzeMethodOrClosure(Element element,
+      ConcreteTypesEnvironment environment) {
+    ConcreteType specialResult = handleSpecialMethod(element, environment);
+    if (specialResult != null) return specialResult;
+    ClosureEnvironment closureEnv = closures.getEnvironmentOrNull(element);
+    return (closureEnv == null)
+        ? analyzeMethod(element, environment)
+        : analyzeClosure(element, closureEnv, environment);
+  }
+
+  ConcreteType analyzeMethod(Element element,
+                             ConcreteTypesEnvironment environment) {
+    TypeInferrerVisitor visitor = new TypeInferrerVisitor(
+        element,
+        this,
+        singletonConcreteType(new ClassBaseType(environment.classOfThis)),
+        environment.environment);
+    visitor.run();
+    return visitor.returnType;
+  }
+
+  ConcreteType analyzeClosure(Element element,
+                              ClosureEnvironment closureEnv,
+                              ConcreteTypesEnvironment environment) {
+    assert(environment.classOfThis == null);
+    LocalsHandler locals = (closureEnv.locals != null)
+        ? new LocalsHandler.deepCopyOf(closureEnv.locals)
+        : null;
+    TypeInferrerVisitor visitor = new TypeInferrerVisitor(element, this,
+        closureEnv.thisType, environment.environment, locals);
+    visitor.run();
+    return visitor.returnType;
+  }
+
+  /**
+   * Analyzes the initialization of a field. Returns [:null:] if and only if
+   * [element] has no initialization expression.
+   */
+  ConcreteType analyzeFieldInitialization(VariableElement element) {
+    TreeElements elements =
+        compiler.enqueuer.resolution.resolvedElements[element];
+    assert(elements != null);
+    Visitor visitor = new TypeInferrerVisitor(element, this, null, new Map());
+    Node tree = element.parseNode(compiler);
+    ConcreteType type = initializerDo(tree, (node) => node.accept(visitor));
+    if (type != null) {
+      augmentFieldType(element, type);
+    }
+    return type;
+  }
+
+  /**
+   * Analyze a default value.
+   */
+  ConcreteType analyzeDefaultValue(Element function, Node expression) {
+    assert((function != null) && (expression != null));
+    Visitor visitor = new TypeInferrerVisitor(function, this, null, {});
+    return expression.accept(visitor);
+  }
+
+  /**
+   * Hook that performs side effects on some special method calls (like
+   * [:List(length):]) and possibly returns a concrete type.
+   */
+  ConcreteType handleSpecialMethod(FunctionElement element,
+                                   ConcreteTypesEnvironment environment) {
+    // We trust the return type of native elements
+    if (isNativeElement(element)) {
+      var elementType = element.computeType(compiler);
+      assert(elementType.kind == TypeKind.FUNCTION);
+      return typeOfNativeBehavior(
+          native.NativeBehavior.ofMethod(element, compiler));
+    }
+    // When List([length]) is called with some length, we must augment
+    // listElementType with {null}.
+    if (element == listConstructor) {
+      Link<Element> parameters =
+          listConstructor.functionSignature.optionalParameters;
+      ConcreteType lengthType = environment.lookupType(parameters.head);
+      if (lengthType.baseTypes.contains(baseTypes.intBaseType)) {
+        augmentListElementType(nullConcreteType);
+      }
+    }
+  }
+
+  /**
+   * Performs concrete type inference of the code reachable from [element].
+   */
+  @override
+  bool analyzeMain(Element element) {
+    initialize();
+    workQueue.add(
+        new InferenceWorkItem(element, new ConcreteTypesEnvironment()));
+    while (!workQueue.isEmpty) {
+      currentWorkItem = workQueue.remove();
+      if (currentWorkItem.method.isField()) {
+        analyzeFieldInitialization(currentWorkItem.method);
+      } else {
+        Map<ConcreteTypesEnvironment, ConcreteType> template =
+            getTemplatesOrEmpty(currentWorkItem.method);
+        template.putIfAbsent(
+            currentWorkItem.environment, () => emptyConcreteType);
+        recordReturnType(
+            currentWorkItem.method,
+            analyzeMethodOrClosure(currentWorkItem.method,
+                                   currentWorkItem.environment));
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Dumps debugging information on the standard output.
+   */
+  void debug() {
+    print("queue:");
+    for (InferenceWorkItem workItem in workQueue.queue) {
+      print("  $workItem");
+    }
+    print("seen classes:");
+    for (ClassElement cls in seenClasses) {
+      print("  ${cls.name}");
+    }
+    print("callers:");
+    callers.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("dynamic callers:");
+    dynamicCallers.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("readers:");
+    fieldReaders.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("readers of captured locals:");
+    capuredLocalsReaders.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("inferredFieldTypes:");
+    inferredFieldTypes.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("listElementType:");
+    print("  $listElementType");
+    print("inferredParameterTypes:");
+    inferredParameterTypes.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("inferred selector types:");
+    inferredSelectorTypes.forEach((selector, map) {
+      print("  $selector:");
+      map.forEach((k, v) {
+        print("    $k: $v");
+      });
+    });
+    print("cache:");
+    methodToTemplates.forEach((k,v) {
+      print("  $k: $v");
+    });
+    print("closures:");
+    closures.closures.forEach((k, ClosureEnvironment v) {
+      print("  $k");
+      print("    this: ${v.thisType}");
+      if (v.locals != null) {
+        v.locals.locals.forEachLocal((local, type) {
+          print("    $local: $type");
+        });
+      }
+    });
+    print("inferred expression types:");
+    inferredTypes.forEach((k,v) {
+      print("  $k: $v");
+    });
+  }
+
+  @override
+  ConcreteType addReturnTypeFor(Element analyzedElement,
+                                ConcreteType currentType,
+                                ConcreteType newType) {
+    return (currentType == null) ? newType : currentType.union(newType);
+  }
+
+  @override
+  void forEachElementMatching(Selector selector, bool f(Element element)) {
+    getMembersBySelector(selector).forEach(f);
+  }
+
+  @override
+  void recordReturnType(Element element, ConcreteType type) {
+    assert((type != null) && (element == currentWorkItem.method));
+    Map<ConcreteTypesEnvironment, ConcreteType> template =
+        getTemplatesOrEmpty(element);
+    if (template[currentWorkItem.environment] != type) {
+      template[currentWorkItem.environment] = type;
+      invalidateCallers(element);
+    }
+  }
+
+  @override
+  bool recordType(Element element, ConcreteType type) {
+    assert(element is FieldElement);
+    augmentFieldType(element, type);
+  }
+
+  @override
+  void recordTypeOfFinalField(Node node,
+                              Element nodeHolder,
+                              Element field,
+                              ConcreteType type) {
+    augmentFieldType(field, type);
+  }
+
+  @override
+  void recordTypeOfNonFinalField(Spannable node, Element field,
+                                 ConcreteType type) {
+    augmentFieldType(field, type);
+  }
+
+  @override
+  void recordCapturedLocalRead(Element local) {
+    addCapturedLocalReader(local, currentWorkItem.method);
+  }
+
+  @override
+  void recordLocalUpdate(Element local, ConcreteType type) {
+    Set<Element> localReaders = capuredLocalsReaders[local];
+    if (localReaders != null) {
+      localReaders.forEach(invalidate);
+    }
+  }
+
+  /**
+   * Returns the caller of the current analyzed element, given the alleged
+   * caller provided by SimpleTypeInferrer.
+   *
+   * SimpleTypeInferrer lies about the caller when it's a closure.
+   * Unfortunately we cannot always trust currentWorkItem.method either because
+   * it is wrong for fields initializers.
+   */
+  Element getRealCaller(Element allegedCaller) {
+    Element currentMethod = currentWorkItem.method;
+    if ((currentMethod != allegedCaller)
+        && currentMethod.isFunction()
+        && closures.contains(currentMethod)) {
+      return currentMethod;
+    } else {
+      return allegedCaller;
+    }
+  }
+
+  @override
+  ConcreteType registerCalledElement(Spannable node,
+                                     Selector selector,
+                                     Element caller,
+                                     Element callee,
+                                     ArgumentsTypes<ConcreteType> arguments,
+                                     SideEffects sideEffects,
+                                     bool inLoop) {
+
+    caller = getRealCaller(caller);
+    if ((selector == null) || (selector.kind == SelectorKind.CALL)) {
+      callee = callee.implementation;
+      if (selector != null && selector.name == 'JS') {
+        return null;
+      }
+      if (callee.isField()) {  // toplevel closure call
+        getFieldType(selector, callee);  // trigger toplevel field analysis
+        addFieldReader(callee, caller);
+        ConcreteType result = emptyConcreteType;
+        for (FunctionElement function in closures.functionElements) {
+          addCaller(function, caller);
+          result = result.union(
+              getSendReturnType(selector, function, null, arguments));
+        }
+        return result;
+      } else {  // method or constructor call
+        addCaller(callee, caller);
+        ClassElement receiverClass = null;
+        if (callee.isGenerativeConstructor()) {
+          receiverClass = callee.getEnclosingClass();
+        } else if (node is Send) {
+          Send send = node;
+          if (send.receiver != null) {
+            if (send.receiver.isSuper()) {
+              receiverClass = currentWorkItem.environment.classOfThis.superclass;
+            } else {
+              receiverClass = currentWorkItem.environment.classOfThis;
+            }
+          }
+        }
+        return getSendReturnType(selector, callee, receiverClass, arguments);
+      }
+    } else if (selector.kind == SelectorKind.GETTER) {
+      if (callee.isField()) {
+        addFieldReader(callee, caller);
+        return getFieldType(selector, callee);
+      } else if (callee.isGetter()) {
+        Element enclosing = callee.enclosingElement.isCompilationUnit()
+            ? null : callee.enclosingElement;
+        addCaller(callee, caller);
+        ArgumentsTypes noArguments = new ArgumentsTypes([], new Map());
+        return getSendReturnType(selector, callee, enclosing, noArguments);
+      } else if (callee.isFunction()) {
+        addClosure(callee, null, null);
+        return singletonConcreteType(baseTypes.functionBaseType);
+      }
+    } else if (selector.kind == SelectorKind.SETTER) {
+      ConcreteType argumentType = arguments.positional.first;
+      if (callee.isField()) {
+        augmentFieldType(callee, argumentType);
+      } else if (callee.isSetter()) {
+        FunctionElement setter = callee;
+        // TODO(polux): A setter always returns void so there's no need to
+        // invalidate its callers even if it is called with new arguments.
+        // However, if we start to record more than returned types, like
+        // exceptions for instance, we need to do it by uncommenting the
+        // following line.
+        // inferrer.addCaller(setter, currentMethod);
+        return getSendReturnType(selector, setter, callee.enclosingElement,
+            new ArgumentsTypes([argumentType], new Map()));
+      }
+    } else {
+      throw new ArgumentError("unexpected selector kind");
+    }
+  }
+
+  @override
+  ConcreteType registerCalledSelector(Node node,
+                                      Selector selector,
+                                      ConcreteType receiverType,
+                                      Element caller,
+                                      ArgumentsTypes<ConcreteType> arguments,
+                                      SideEffects sideEffects,
+                                      bool inLoop) {
+    caller = getRealCaller(caller);
+    switch (selector.kind) {
+      case SelectorKind.GETTER:
+        return registerDynamicGetterSend(selector, receiverType, caller);
+      case SelectorKind.SETTER:
+        return registerDynamicSetterSend(
+            selector, receiverType, caller, arguments);
+      default:
+        return registerDynamicSend(selector, receiverType, caller, arguments);
+    }
+  }
+
+  ConcreteType registerDynamicGetterSend(Selector selector,
+                                         ConcreteType receiverType,
+                                         Element caller) {
+    caller = getRealCaller(caller);
+    ConcreteType result = emptyConcreteType;
+
+    void augmentResult(ClassElement baseReceiverType, Element member) {
+      if (member.isField()) {
+        addFieldReader(member, caller);
+        result = result.union(getFieldType(selector, member));
+      } else if (member.isGetter()) {
+        addCaller(member, caller);
+        ArgumentsTypes noArguments = new ArgumentsTypes([], new Map());
+        result = result.union(
+            getSendReturnType(selector, member, baseReceiverType, noArguments));
+      } else if (member.isFunction()) {
+        addClosure(member, receiverType, null);
+        result = result.union(
+            singletonConcreteType(baseTypes.functionBaseType));
+      } else {
+        throw new ArgumentError("unexpected element type");
+      }
+    }
+
+    if (receiverType.isUnknown()) {
+      addDynamicCaller(selector, caller);
+      Set<Element> members = getMembersBySelector(selector);
+      for (Element member in members) {
+        if (!(member.isField() || member.isGetter())) continue;
+        for (ClassElement cls in
+            getReflexiveSubtypesOf(member.enclosingElement)) {
+          augmentResult(cls, member);
+        }
+      }
+    } else {
+      for (BaseType baseReceiverType in receiverType.baseTypes) {
+        if (!baseReceiverType.isNull()) {
+          ClassBaseType classBaseType = baseReceiverType;
+          ClassElement cls = classBaseType.element;
+          Element getterOrField = cls.lookupSelector(selector, compiler);
+          if (getterOrField != null) {
+            augmentResult(cls, getterOrField.implementation);
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  ConcreteType registerDynamicSetterSend(
+      Selector selector,
+      ConcreteType receiverType,
+      Element caller,
+      ArgumentsTypes<ConcreteType> arguments) {
+    caller = getRealCaller(caller);
+    ConcreteType argumentType = arguments.positional.first;
+
+    void augmentField(ClassElement receiverType, Element setterOrField) {
+      if (setterOrField.isField()) {
+        augmentFieldType(setterOrField, argumentType);
+      } else if (setterOrField.isSetter()) {
+        // A setter always returns void so there's no need to invalidate its
+        // callers even if it is called with new arguments. However, if we
+        // start to record more than returned types, like exceptions for
+        // instance, we need to do it by uncommenting the following line.
+        // inferrer.addCaller(setter, currentMethod);
+        getSendReturnType(selector, setterOrField, receiverType,
+            new ArgumentsTypes([argumentType], new Map()));
+      } else {
+        throw new ArgumentError("unexpected element type");
+      }
+    }
+
+    if (receiverType.isUnknown()) {
+      // Same remark as above
+      // addDynamicCaller(selector, caller);
+      for (Element member in getMembersBySelector(selector)) {
+        if (!(member.isField() || member.isSetter())) continue;
+        Element cls = member.getEnclosingClass();
+        augmentField(cls, member);
+      }
+    } else {
+      for (BaseType baseReceiverType in receiverType.baseTypes) {
+        if (!baseReceiverType.isNull()) {
+          ClassBaseType classBaseType = baseReceiverType;
+          ClassElement cls = classBaseType.element;
+          Element setterOrField = cls.lookupSelector(selector, compiler);
+          if (setterOrField != null) {
+            augmentField(cls, setterOrField.implementation);
+          }
+        }
+      }
+    }
+    return argumentType;
+  }
+
+  ConcreteType registerDynamicSend(Selector selector,
+                                   ConcreteType receiverType,
+                                   Element caller,
+                                   ArgumentsTypes<ConcreteType> arguments) {
+    caller = getRealCaller(caller);
+    ConcreteType result = emptyConcreteType;
+    if (receiverType.isUnknown()) {
+      addDynamicCaller(selector, caller);
+      Set<Element> elements = getMembersBySelector(selector);
+      for (Element element in elements) {
+        if (element.isFunction()) {
+          FunctionElement method = element;
+          addCaller(method, caller);
+          for (ClassElement cls in
+              getReflexiveSubtypesOf(method.enclosingElement)) {
+            result = result.union(
+                getSendReturnType(selector, method, cls, arguments));
+          }
+        } else { // closure call
+          assert(element.isField());
+          for (FunctionElement function in closures.functionElements) {
+            addCaller(function, caller);
+            result = result.union(
+                getSendReturnType(selector, function, null, arguments));
+          }
+        }
+      }
+    } else {
+      for (BaseType baseReceiverType in receiverType.baseTypes) {
+        if (!baseReceiverType.isNull()) {
+          ClassBaseType classBaseReceiverType = baseReceiverType;
+          ClassElement cls = classBaseReceiverType.element;
+          Element method = cls.lookupSelector(selector, compiler);
+          if (method != null) {
+            if (method.isFunction()) {
+              assert(method is FunctionElement);
+              method = method.implementation;
+              addCaller(method, caller);
+              result = result.union(
+                  getSendReturnType(selector, method, cls, arguments));
+            } else { // closure call
+              for (FunctionElement function in closures.functionElements) {
+                addCaller(function, caller);
+                result = result.union(
+                    getSendReturnType(selector, function, null, arguments));
+              }
+            }
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  @override
+  void setDefaultTypeOfParameter(Element parameter, ConcreteType type) {
+    // We handle default parameters our own way in associateArguments
+  }
+
+  @override
+  ConcreteType registerCalledClosure(Node node,
+                                     Selector selector,
+                                     ConcreteType closure,
+                                     Element caller,
+                                     ArgumentsTypes<ConcreteType> arguments,
+                                     SideEffects sideEffects,
+                                     bool inLoop) {
+    caller = getRealCaller(caller);
+    ConcreteType result = emptyConcreteType;
+    for (FunctionElement function in closures.functionElements) {
+      addCaller(function, caller);
+      result = result.union(
+          getSendReturnType(selector, function, null, arguments));
+    }
+    return result;
+  }
+
+  @override
+  ConcreteType returnTypeOfElement(Element element) {
+    // Never called by SimpleTypeInferrer.
+    throw new UnsupportedError("");
+  }
+
+  @override
+  ConcreteType typeOfElement(Element element) {
+    if (currentWorkItem != null) {
+      final result = currentWorkItem.environment.lookupType(element);
+      if (result != null) return result;
+    }
+    if (element.isParameter() || element.isFieldParameter()) {
+      return inferredParameterTypes[element];
+    } else if (element.isField()) {
+      return inferredFieldTypes[element];
+    }
+    throw new ArgumentError("unexpected element type");
+  }
+
+  @override
+  void analyze(Element element, ArgumentsTypes arguments) {
+    FunctionElement function = element;
+    getSendReturnType(
+        null, function, currentWorkItem.environment.classOfThis, arguments);
+  }
+}
+
+class TypeInferrerVisitor extends SimpleTypeInferrerVisitor<ConcreteType> {
+  final ConcreteType thisType;
+  ConcreteTypesInferrer get inferrer => super.inferrer;
+
+  TypeInferrerVisitor(Element element,
+                      ConcreteTypesInferrer inferrer,
+                      this.thisType,
+                      Map<Element, ConcreteType> environment,
+                      [LocalsHandler<ConcreteType> handler])
+      : super(element, inferrer.compiler, inferrer, handler);
+
+  @override
+  ConcreteType visitFunctionExpression(FunctionExpression node) {
+    Element element = elements[node];
+    // visitFunctionExpression should be only called for closures
+    assert(element != analyzedElement);
+    inferrer.addClosure(
+        element, thisType, new LocalsHandler.deepCopyOf(locals));
+    return types.functionType;
+  }
+
+  @override
+  ConcreteType visitLiteralString(LiteralString node) {
+    // TODO(polux): get rid of this hack once we have a natural way of inferring
+    // the unknown type.
+    if (inferrer.testMode
+        && (node.dartString.slowToString() == "__dynamic_for_test")) {
+      return inferrer.unknownConcreteType;
+    }
+    return super.visitLiteralString(node);
+  }
+
+  /**
+   * Same as super.visitLiteralList except it doesn't cache anything.
+   */
+  @override
+  ConcreteType visitLiteralList(LiteralList node) {
+    ConcreteType elementType;
+    int length = 0;
+    for (Node element in node.elements.nodes) {
+      ConcreteType type = visit(element);
+      elementType = elementType == null
+          ? types.allocatePhi(null, null, type)
+          : types.addPhiInput(null, elementType, type);
+      length++;
+    }
+    elementType = elementType == null
+        ? types.nonNullEmpty()
+        : types.simplifyPhi(null, null, elementType);
+    ConcreteType containerType = node.isConst()
+        ? types.constListType
+        : types.growableListType;
+    return types.allocateList(
+        containerType,
+        node,
+        outermostElement,
+        elementType,
+        length);
+  }
+
+  /**
+   * Same as super.visitGetterSend except it records the type of nodes in test
+   * mode.
+   */
+  @override
+  ConcreteType visitGetterSend(Send node) {
+    if (inferrer.testMode) {
+      Element element = elements[node];
+      ConcreteType type = locals.use(element);
+      if (type != null) {
+        inferrer.augmentInferredType(node, type);
+      }
+    }
+    return super.visitGetterSend(node);
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index c9646c3..86662f7 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -290,6 +290,16 @@
    * [type].
    */
   void recordTypeOfNonFinalField(Node node, Element field, T type);
+
+  /**
+   * Records that the captured variable [local] is read.
+   */
+  void recordCapturedLocalRead(Element local);
+
+  /**
+   * Records that the variable [local] is being updated.
+   */
+  void recordLocalUpdate(Element local, T type);
 }
 
 /**
@@ -300,6 +310,7 @@
   final TypeSystem<T> types;
   final MinimalInferrerEngine<T> inferrer;
   final VariableScope<T> locals;
+  final Map<Element, Element> captured;
   final Map<Element, Element> capturedAndBoxed;
   final FieldInitializationScope<T> fieldScope;
   LocalsHandler<T> tryBlock;
@@ -317,6 +328,7 @@
                 Node block,
                 [this.fieldScope])
       : locals = new VariableScope<T>(block),
+        captured = new Map<Element, Element>(),
         capturedAndBoxed = new Map<Element, Element>(),
         tryBlock = null;
 
@@ -325,6 +337,7 @@
                      {bool useOtherTryBlock: true})
       : locals = new VariableScope<T>(block, other.locals),
         fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
+        captured = other.captured,
         capturedAndBoxed = other.capturedAndBoxed,
         types = other.types,
         inferrer = other.inferrer,
@@ -335,6 +348,7 @@
   LocalsHandler.deepCopyOf(LocalsHandler<T> other)
       : locals = new VariableScope<T>.deepCopyOf(other.locals),
         fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
+        captured = other.captured,
         capturedAndBoxed = other.capturedAndBoxed,
         tryBlock = other.tryBlock,
         types = other.types,
@@ -342,9 +356,14 @@
         compiler = other.compiler;
 
   T use(Element local) {
-    return capturedAndBoxed.containsKey(local)
-        ? inferrer.typeOfElement(capturedAndBoxed[local])
-        : locals[local];
+    if (capturedAndBoxed.containsKey(local)) {
+      return inferrer.typeOfElement(capturedAndBoxed[local]);
+    } else {
+      if (captured.containsKey(local)) {
+        inferrer.recordCapturedLocalRead(local);
+      }
+      return locals[local];
+    }
   }
 
   void update(Element local, T type, Node node) {
@@ -352,6 +371,13 @@
     if (compiler.trustTypeAnnotations || compiler.enableTypeAssertions) {
       type = types.narrowType(type, local.computeType(compiler));
     }
+    updateLocal() {
+      T currentType = locals[local];
+      locals[local] = type;
+      if (currentType != type) {
+        inferrer.recordLocalUpdate(local, type);
+      }
+    }
     if (capturedAndBoxed.containsKey(local)) {
       inferrer.recordTypeOfNonFinalField(
           node, capturedAndBoxed[local], type);
@@ -369,12 +395,16 @@
       }
       // Update the current handler unconditionnally with the new
       // type.
-      locals[local] = type;
+      updateLocal();
     } else {
-      locals[local] = type;
+      updateLocal();
     }
   }
 
+  void setCaptured(Element local, Element field) {
+    captured[local] = field;
+  }
+
   void setCapturedAndBoxed(Element local, Element field) {
     capturedAndBoxed[local] = field;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart
index bae7c29..f85e1be 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart
@@ -4,7 +4,7 @@
 
 library dart2js.ir_type_inferrer;
 
-import '../ir/ir_nodes.dart';
+import '../ir/ir_nodes.dart' as ir;
 import 'inferrer_visitor.dart' show TypeSystem, ArgumentsTypes;
 import 'simple_types_inferrer.dart' show InferrerEngine;
 import '../elements/elements.dart' show
@@ -14,7 +14,7 @@
 import '../universe/universe.dart' show Selector, SideEffects;
 
 
-class IrTypeInferrerVisitor extends IrNodesVisitor {
+class IrTypeInferrerVisitor extends ir.NodesVisitor {
   final Compiler compiler;
   final Element analyzedElement;
   final Element outermostElement;
@@ -40,7 +40,7 @@
     return outermostElement;
   }
 
-  final Map<IrNode, TypeInformation> analyzed = <IrNode, TypeInformation>{};
+  final Map<ir.Node, TypeInformation> analyzed = <ir.Node, TypeInformation>{};
 
   TypeInformation returnType;
 
@@ -50,7 +50,7 @@
 
     FunctionElement function = analyzedElement;
     FunctionSignature signature = function.computeSignature(compiler);
-    IrFunction node = compiler.irBuilder.getIr(function);
+    ir.Function node = compiler.irBuilder.getIr(function);
 
     // TODO(lry): handle parameters.
     assert(function.computeSignature(compiler).parameterCount == 0);
@@ -70,7 +70,7 @@
     return inferrer.types.getConcreteTypeFor(constant.computeMask(compiler));
   }
 
-  TypeInformation handleStaticSend(IrNode node,
+  TypeInformation handleStaticSend(ir.Node node,
                                    Selector selector,
                                    Element element,
                                    ArgumentsTypes arguments) {
@@ -80,7 +80,7 @@
   }
 
   ArgumentsTypes<TypeInformation> analyzeArguments(
-      Selector selector, List<IrNode> arguments) {
+      Selector selector, List<ir.Node> arguments) {
     // TODO(lry): support named arguments, necessary information should be
     // in [selector].
     assert(selector.namedArgumentCount == 0);
@@ -89,16 +89,16 @@
     return new ArgumentsTypes<TypeInformation>(positional, null);
   }
 
-  void visitIrConstant(IrConstant node) {
+  void visitConstant(ir.Constant node) {
     analyzed[node] = typeOfConstant(node.value);
   }
 
-  void visitIrReturn(IrReturn node) {
+  void visitReturn(ir.Return node) {
     TypeInformation type = analyzed[node.value];
     returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
   }
 
-  void visitIrInvokeStatic(IrInvokeStatic node) {
+  void visitInvokeStatic(ir.InvokeStatic node) {
     FunctionElement element = node.target;
     Selector selector = node.selector;
     // TODO(lry): handle foreign functions.
@@ -113,7 +113,7 @@
     }
   }
 
-  void visitIrNode(IrNode node) {
+  void visitNode(ir.Node node) {
     compiler.internalError('Unexpected IrNode $node');
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 181dd40..3348073 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -9,8 +9,8 @@
     show DartType, InterfaceType, FunctionType, TypeKind;
 import '../elements/elements.dart';
 import '../native_handler.dart' as native;
-import '../tree/tree.dart';
-import '../ir/ir_nodes.dart' show IrNode;
+import '../tree/tree.dart' as ast;
+import '../ir/ir_nodes.dart' as ir show Node;
 import '../util/util.dart' show Link, Spannable, Setlet;
 import '../types/types.dart'
     show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask,
@@ -101,18 +101,18 @@
   TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
 
   TypeMask allocateList(TypeMask type,
-                        Node node,
+                        ast.Node node,
                         Element enclosing,
                         [TypeMask elementType, int length]) {
     return new ContainerTypeMask(type, node, enclosing, elementType, length);
   }
 
-  TypeMask allocateMap(TypeMask type, Node node, Element element,
+  TypeMask allocateMap(TypeMask type, ast.Node node, Element element,
                        [TypeMask keys, TypeMask values]) {
     return type;
   }
 
-  TypeMask allocateClosure(Node node, Element element) {
+  TypeMask allocateClosure(ast.Node node, Element element) {
     return functionType;
   }
 
@@ -124,11 +124,11 @@
     return computeLUB(phiType, newType);
   }
 
-  TypeMask allocatePhi(Node node, Element element, TypeMask inputType) {
+  TypeMask allocatePhi(ast.Node node, Element element, TypeMask inputType) {
     return inputType;
   }
 
-  TypeMask simplifyPhi(Node node, Element element, TypeMask phiType) {
+  TypeMask simplifyPhi(ast.Node node, Element element, TypeMask phiType) {
     return phiType;
   }
 
@@ -149,7 +149,7 @@
     implements MinimalInferrerEngine<T> {
   final Compiler compiler;
   final V types;
-  final Map<Node, T> concreteTypes = new Map<Node, T>();
+  final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>();
   final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
 
   InferrerEngine(this.compiler, this.types);
@@ -174,7 +174,7 @@
    *
    * [nodeHolder] is the element holder of [node].
    */
-  void recordTypeOfFinalField(Node node,
+  void recordTypeOfFinalField(ast.Node node,
                               Element nodeHolder,
                               Element field,
                               T type);
@@ -223,7 +223,7 @@
    *
    * [inLoop] tells whether the call happens in a loop.
    */
-  T registerCalledSelector(Node node,
+  T registerCalledSelector(ast.Node node,
                            Selector selector,
                            T receiverType,
                            Element caller,
@@ -239,7 +239,7 @@
    *
    * [inLoop] tells whether the call happens in a loop.
    */
-  T registerCalledClosure(Node node,
+  T registerCalledClosure(ast.Node node,
                           Selector selector,
                           T closure,
                           Element caller,
@@ -353,11 +353,11 @@
 
   void updateSelectorInTree(
       Element owner, Spannable node, Selector selector) {
-    if (node is IrNode) {
+    if (node is ir.Node) {
       // TODO(lry): update selector for IrInvokeDynamic.
       throw "updateSelector for IR node $node";
     }
-    Node astNode = node;
+    ast.Node astNode = node;
     var elements = compiler.enqueuer.resolution.getCachedElements(owner);
     if (astNode.asSendSet() != null) {
       if (selector.isSetter() || selector.isIndexSet()) {
@@ -390,7 +390,7 @@
         && element.isField();
   }
 
-  void analyze(Element element);
+  void analyze(Element element, ArgumentsTypes arguments);
 
   bool checkIfExposesThis(Element element) {
     element = element.implementation;
@@ -422,21 +422,20 @@
                                      compiler,
                                      locals)
     : super(analyzedElement, inferrer, inferrer.types, compiler, locals),
-      this.inferrer = inferrer;
-
-  factory SimpleTypeInferrerVisitor(Element element,
-                                    Compiler compiler,
-                                    InferrerEngine<T, TypeSystem<T>> inferrer,
-                                    [LocalsHandler<T> handler]) {
-    Element outermostElement =
-        element.getOutermostEnclosingMemberOrTopLevel().implementation;
+      this.inferrer = inferrer {
     assert(outermostElement != null);
-    return new SimpleTypeInferrerVisitor<T>.internal(
-        element, outermostElement, inferrer, compiler, handler);
   }
 
-  void analyzeSuperConstructorCall(Element target) {
-    inferrer.analyze(target);
+  SimpleTypeInferrerVisitor(Element element,
+                            Compiler compiler,
+                            InferrerEngine<T, TypeSystem<T>> inferrer,
+                            [LocalsHandler<T> handler])
+    : this.internal(element,
+        element.getOutermostEnclosingMemberOrTopLevel().implementation,
+        inferrer, compiler, handler);
+
+  void analyzeSuperConstructorCall(Element target, ArgumentsTypes arguments) {
+    inferrer.analyze(target, arguments);
     isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
   }
 
@@ -454,6 +453,9 @@
     ClosureClassMap closureData =
         compiler.closureToClassMapper.computeClosureToClassMapping(
             analyzedElement, node, elements);
+    closureData.forEachCapturedVariable((variable, field) {
+      locals.setCaptured(variable, field);
+    });
     closureData.forEachBoxedVariable((variable, field) {
       locals.setCapturedAndBoxed(variable, field);
     });
@@ -464,8 +466,8 @@
     FunctionElement function = analyzedElement;
     FunctionSignature signature = function.computeSignature(compiler);
     signature.forEachOptionalParameter((element) {
-      Node node = element.parseNode(compiler);
-      Send send = node.asSendSet();
+      ast.Node node = element.parseNode(compiler);
+      ast.Send send = node.asSendSet();
       T type = (send == null) ? types.nullType : visit(send.arguments.head);
       inferrer.setDefaultTypeOfParameter(element, type);
     });
@@ -515,7 +517,7 @@
           Selector selector =
               new Selector.callDefaultConstructor(analyzedElement.getLibrary());
           FunctionElement target = cls.superclass.lookupConstructor(selector);
-          analyzeSuperConstructorCall(target);
+          analyzeSuperConstructorCall(target, new ArgumentsTypes([], {}));
           synthesizeForwardingCall(analyzedElement, target);
         }
         visit(node.body);
@@ -557,7 +559,7 @@
     return returnType;
   }
 
-  T visitFunctionExpression(FunctionExpression node) {
+  T visitFunctionExpression(ast.FunctionExpression node) {
     Element element = elements[node];
     // We don't put the closure in the work queue of the
     // inferrer, because it will share information with its enclosing
@@ -591,7 +593,7 @@
     });
   }
 
-  T visitFunctionDeclaration(FunctionDeclaration node) {
+  T visitFunctionDeclaration(ast.FunctionDeclaration node) {
     Element element = elements[node];
     T type = inferrer.concreteTypes.putIfAbsent(node.function, () {
       return types.allocateClosure(node.function, element);
@@ -601,13 +603,13 @@
     return type;
   }
 
-  T visitLiteralList(LiteralList node) {
+  T visitLiteralList(ast.LiteralList node) {
     // We only set the type once. We don't need to re-visit the children
     // when re-analyzing the node.
     return inferrer.concreteTypes.putIfAbsent(node, () {
       T elementType;
       int length = 0;
-      for (Node element in node.elements.nodes) {
+      for (ast.Node element in node.elements.nodes) {
         T type = visit(element);
         elementType = elementType == null
             ? types.allocatePhi(null, null, type)
@@ -629,16 +631,16 @@
     });
   }
 
-  T visitLiteralMap(LiteralMap node) {
+  T visitLiteralMap(ast.LiteralMap node) {
     return inferrer.concreteTypes.putIfAbsent(node, () {
-      NodeList entries = node.entries;
+      ast.NodeList entries = node.entries;
       T keyType;
       T valueType;
       if (entries.isEmpty) {
         keyType = types.nonNullEmpty();
         valueType = types.nonNullEmpty();
       } else {
-        for (LiteralMapEntry entry in entries) {
+        for (ast.LiteralMapEntry entry in entries) {
           T key = visit(entry.key);
           keyType = keyType == null
               ? types.allocatePhi(null, null, key)
@@ -661,7 +663,7 @@
     });
   }
 
-  bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
+  bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper();
 
   bool isInClassOrSubclass(Element element) {
     ClassElement cls = outermostElement.getEnclosingClass();
@@ -705,7 +707,7 @@
         || (element != null && element.isInstanceMember());
   }
 
-  T visitSendSet(SendSet node) {
+  T visitSendSet(ast.SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
       node.visitChildren(this);
@@ -747,7 +749,7 @@
     }
 
     if (!visitingInitializers && !isThisExposed) {
-      for (Node node in node.arguments) {
+      for (ast.Node node in node.arguments) {
         if (isThisOrSuper(node)) {
           isThisExposed = true;
           break;
@@ -846,12 +848,12 @@
     }
   }
 
-  T handlePlainAssignment(Node node,
+  T handlePlainAssignment(ast.Node node,
                           Element element,
                           Selector setterSelector,
                           T receiverType,
                           T rhsType,
-                          Node rhs) {
+                          ast.Node rhs) {
     ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
     if (Elements.isErroneousElement(element)) {
       // Code will always throw.
@@ -897,19 +899,19 @@
     return rhsType;
   }
 
-  T visitSuperSend(Send node) {
+  T visitSuperSend(ast.Send node) {
     Element element = elements[node];
+    ArgumentsTypes arguments = node.isPropertyAccess
+        ? null
+        : analyzeArguments(node.arguments);
     if (visitingInitializers) {
       seenSuperConstructorCall = true;
-      analyzeSuperConstructorCall(element);
+      analyzeSuperConstructorCall(element, arguments);
     }
     Selector selector = elements.getSelector(node);
     // TODO(ngeoffray): We could do better here if we knew what we
     // are calling does not expose this.
     isThisExposed = true;
-    ArgumentsTypes arguments = node.isPropertyAccess
-        ? null
-        : analyzeArguments(node.arguments);
     if (Elements.isUnresolved(element)
         || !selector.applies(element, compiler)) {
       // Ensure we create a node, to make explicit the call to the
@@ -927,10 +929,10 @@
   }
 
   // Try to find the length given to a fixed array constructor call.
-  int findLength(Send node) {
-    Node firstArgument = node.arguments.head;
+  int findLength(ast.Send node) {
+    ast.Node firstArgument = node.arguments.head;
     Element element = elements[firstArgument];
-    LiteralInt length = firstArgument.asLiteralInt();
+    ast.LiteralInt length = firstArgument.asLiteralInt();
     if (length != null) {
       return length.value;
     } else if (element != null
@@ -946,23 +948,24 @@
     return null;
   }
 
-  T visitStaticSend(Send node) {
+  T visitStaticSend(ast.Send node) {
     Element element = elements[node];
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
     if (visitingInitializers) {
-      if (Initializers.isConstructorRedirect(node)) {
+      if (ast.Initializers.isConstructorRedirect(node)) {
         isConstructorRedirect = true;
-      } else if (Initializers.isSuperConstructorCall(node)) {
+      } else if (ast.Initializers.isSuperConstructorCall(node)) {
         seenSuperConstructorCall = true;
-        analyzeSuperConstructorCall(element);
+        analyzeSuperConstructorCall(element, arguments);
       }
     }
     if (element.isForeign(compiler)) {
       return handleForeignSend(node);
     }
     Selector selector = elements.getSelector(node);
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
     // In erroneous code the number of arguments in the selector might not
     // match the function element.
+    // TODO(polux): return nonNullEmpty and check it doesn't break anything
     if (!selector.applies(element, compiler)) return types.dynamicType;
 
     T returnType = handleStaticSend(node, selector, element, arguments);
@@ -1004,7 +1007,7 @@
     }
   }
 
-  T handleForeignSend(Send node) {
+  T handleForeignSend(ast.Send node) {
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
     String name = selector.name;
@@ -1025,11 +1028,11 @@
     }
   }
 
-  ArgumentsTypes analyzeArguments(Link<Node> arguments) {
+  ArgumentsTypes analyzeArguments(Link<ast.Node> arguments) {
     List<T> positional = [];
     Map<String, T> named;
     for (var argument in arguments) {
-      NamedArgument namedArgument = argument.asNamedArgument();
+      ast.NamedArgument namedArgument = argument.asNamedArgument();
       if (namedArgument != null) {
         argument = namedArgument.expression;
         if (named == null) named = new Map<String, T>();
@@ -1044,7 +1047,7 @@
     return new ArgumentsTypes<T>(positional, named);
   }
 
-  T visitGetterSend(Send node) {
+  T visitGetterSend(ast.Send node) {
     Element element = elements[node];
     Selector selector = elements.getSelector(node);
     if (Elements.isStaticOrTopLevelField(element)) {
@@ -1064,7 +1067,7 @@
     }
   }
 
-  T visitClosureSend(Send node) {
+  T visitClosureSend(ast.Send node) {
     assert(node.receiver == null);
     T closure = node.selector.accept(this);
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
@@ -1085,7 +1088,7 @@
     }
   }
 
-  T handleStaticSend(Node node,
+  T handleStaticSend(ast.Node node,
                      Selector selector,
                      Element element,
                      ArgumentsTypes arguments) {
@@ -1096,7 +1099,7 @@
         sideEffects, inLoop);
   }
 
-  T handleDynamicSend(Node node,
+  T handleDynamicSend(ast.Node node,
                       Selector selector,
                       T receiverType,
                       ArgumentsTypes arguments) {
@@ -1112,7 +1115,7 @@
     // its type by refining it with the potential targets of the
     // calls.
     if (node.asSend() != null) {
-      Node receiver = node.asSend().receiver;
+      ast.Node receiver = node.asSend().receiver;
       if (receiver != null) {
         Element element = elements[receiver];
         if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
@@ -1127,7 +1130,7 @@
         sideEffects, inLoop);
   }
 
-  T visitDynamicSend(Send node) {
+  T visitDynamicSend(ast.Send node) {
     Element element = elements[node];
     T receiverType;
     bool isCallOnThis = false;
@@ -1137,7 +1140,7 @@
         receiverType = thisType;
       }
     } else {
-      Node receiver = node.receiver;
+      ast.Node receiver = node.receiver;
       isCallOnThis = isThisOrSuper(receiver);
       receiverType = visit(receiver);
     }
@@ -1204,7 +1207,7 @@
                                           inLoop);
   }
 
-  T visitReturn(Return node) {
+  T visitReturn(ast.Return node) {
     if (node.isRedirectingFactoryBody) {
       Element element = elements[node.expression];
       if (Elements.isErroneousElement(element)) {
@@ -1218,7 +1221,7 @@
         recordReturnType(mask);
       }
     } else {
-      Node expression = node.expression;
+      ast.Node expression = node.expression;
       recordReturnType(expression == null
           ? types.nullType
           : expression.accept(this));
@@ -1227,7 +1230,7 @@
     return null;
   }
 
-  T visitForIn(ForIn node) {
+  T visitForIn(ast.ForIn node) {
     T expressionType = visit(node.expression);
     Selector iteratorSelector = elements.getIteratorSelector(node);
     Selector currentSelector = elements.getCurrentSelector(node);
@@ -1246,7 +1249,7 @@
       isThisExposed = true;
     }
 
-    Node identifier = node.declaredIdentifier;
+    ast.Node identifier = node.declaredIdentifier;
     Element element = elements[identifier];
     Selector selector = elements.getSelector(identifier);
 
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index 80d5bb6..5c3b557 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -7,8 +7,8 @@
 import 'dart:collection' show Queue, IterableBase;
 import '../dart_types.dart' show DartType, InterfaceType, TypeKind;
 import '../elements/elements.dart';
-import '../tree/tree.dart' show LiteralList, Node;
-import '../ir/ir_nodes.dart' show IrNode;
+import '../tree/tree.dart' as ast show LiteralList, Node;
+import '../ir/ir_nodes.dart' as ir show Node;
 import '../types/types.dart'
   show TypeMask, ContainerTypeMask, MapTypeMask, TypesInferrer;
 import '../universe/universe.dart' show Selector, TypedSelector, SideEffects;
@@ -64,12 +64,12 @@
       new Map<Element, TypeInformation>();
 
   /// [ListTypeInformation] for allocated lists.
-  final Map<Node, TypeInformation> allocatedLists =
-      new Map<Node, TypeInformation>();
+  final Map<ast.Node, TypeInformation> allocatedLists =
+      new Map<ast.Node, TypeInformation>();
 
   /// [MapTypeInformation] for allocated Maps.
-  final Map<Node, TypeInformation> allocatedMaps =
-      new Map<Node, TypeInformation>();
+  final Map<ast.Node, TypeInformation> allocatedMaps =
+      new Map<ast.Node, TypeInformation>();
 
   /// Closures found during the analysis.
   final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>();
@@ -291,7 +291,7 @@
   }
 
   TypeInformation allocateList(TypeInformation type,
-                               Node node,
+                               ast.Node node,
                                Element enclosing,
                                [TypeInformation elementType, int length]) {
     bool isTypedArray = (compiler.typedDataClass != null)
@@ -317,14 +317,14 @@
         new ListTypeInformation(mask, element, length);
   }
 
-  TypeInformation allocateClosure(Node node, Element element) {
+  TypeInformation allocateClosure(ast.Node node, Element element) {
     TypeInformation result = new ClosureTypeInformation(node, element);
     allocatedClosures.add(result);
     return result;
   }
 
   TypeInformation allocateMap(ConcreteTypeInformation type,
-                              Node node,
+                              ast.Node node,
                               Element element,
                               [TypeInformation keyType,
                               TypeInformation valueType]) {
@@ -374,7 +374,7 @@
     return result;
   }
 
-  PhiElementTypeInformation allocatePhi(Node node,
+  PhiElementTypeInformation allocatePhi(ast.Node node,
                                         Element element,
                                         inputType) {
     // Check if [inputType] is a phi for a local updated in
@@ -391,7 +391,7 @@
     return result;
   }
 
-  TypeInformation simplifyPhi(Node node,
+  TypeInformation simplifyPhi(ast.Node node,
                               Element element,
                               PhiElementTypeInformation phiType) {
     if (phiType.assignments.length == 1) return phiType.assignments.first;
@@ -523,7 +523,7 @@
       // Force the creation of the [ElementTypeInformation] to ensure it is
       // in the graph.
       types.getInferredTypeOf(element);
-      analyze(element);
+      analyze(element, null);
     });
     compiler.log('Added $addedInGraph elements in inferencing graph.');
 
@@ -587,7 +587,7 @@
     processLoopInformation();
   }
 
-  void analyze(Element element) {
+  void analyze(Element element, ArgumentsTypes arguments) {
     element = element.implementation;
     if (analyzedElements.contains(element)) return;
     analyzedElements.add(element);
@@ -605,7 +605,7 @@
     addedInGraph++;
 
     if (element.isField()) {
-      Node node = element.parseNode(compiler);
+      ast.Node node = element.parseNode(compiler);
       if (element.modifiers.isFinal() || element.modifiers.isConst()) {
         // If [element] is final and has an initializer, we record
         // the inferred type.
@@ -865,7 +865,7 @@
     return info;
   }
 
-  TypeInformation registerCalledSelector(Node node,
+  TypeInformation registerCalledSelector(ast.Node node,
                                          Selector selector,
                                          TypeInformation receiverType,
                                          Element caller,
@@ -889,7 +889,7 @@
     return info;
   }
 
-  TypeInformation registerCalledClosure(Node node,
+  TypeInformation registerCalledClosure(ast.Node node,
                                         Selector selector,
                                         TypeInformation closure,
                                         Element caller,
@@ -993,6 +993,10 @@
       return returnTypeOfElement(element);
     }
   }
+
+  void recordCapturedLocalRead(Element local) {}
+
+  void recordLocalUpdate(Element local, TypeInformation type) {}
 }
 
 class TypeGraphInferrer implements TypesInferrer {
@@ -1022,12 +1026,12 @@
     return inferrer.types.getInferredTypeOf(element).type;
   }
 
-  TypeMask getTypeOfNode(Element owner, Node node) {
+  TypeMask getTypeOfNode(Element owner, ast.Node node) {
     if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
     return inferrer.types.allocatedLists[node].type;
   }
 
-  bool isFixedArrayCheckedForGrowable(Node node) {
+  bool isFixedArrayCheckedForGrowable(ast.Node node) {
     if (compiler.disableTypeInference) return true;
     ListTypeInformation info = inferrer.types.allocatedLists[node];
     return info.checksGrowable;
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
index fddc6fc..92c6543b 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -229,7 +229,7 @@
    * This map contains the callers of [element]. It stores all unique call sites
    * to enable counting the global number of call sites of [element].
    *
-   * A call site is either an AST [Node], an [IrNode] or in the case of
+   * A call site is either an AST [ast.Node], an [ir.Node] or in the case of
    * synthesized calls, an [Element] (see uses of [synthesizeForwardingCall]
    * in [SimpleTypeInferrerVisitor]).
    */
@@ -248,7 +248,7 @@
   }
 
   void addCall(Element caller, Spannable node) {
-    assert(node is Node || node is IrNode || node is Element);
+    assert(node is ast.Node || node is ir.Node || node is Element);
     _callers.putIfAbsent(caller, () => new Setlet()).add(node);
   }
 
@@ -405,7 +405,7 @@
 /**
  * A [CallSiteTypeInformation] is a call found in the AST, or a
  * synthesized call for implicit calls in Dart (such as forwarding
- * factories). The [call] field is a [Node] for the former, and an
+ * factories). The [call] field is a [ast.Node] for the former, and an
  * [Element] for the latter.
  *
  * In the inferrer graph, [CallSiteTypeInformation] nodes do not have
@@ -1062,7 +1062,7 @@
  * [ElementTypeInformation], that is local to a method.
  */
 class PhiElementTypeInformation extends TypeInformation {
-  final Node branchNode;
+  final ast.Node branchNode;
   final bool isLoopPhi;
   final Element element;
 
@@ -1080,7 +1080,7 @@
 }
 
 class ClosureTypeInformation extends TypeInformation {
-  final Node node;
+  final ast.Node node;
   final Element element;
 
   ClosureTypeInformation(this.node, this.element);
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
index ee33f7d..17b37d2 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -4,24 +4,24 @@
 
 library dart2js.ir_builder;
 
-import 'ir_nodes.dart';
+import 'ir_nodes.dart' as ir;
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show FunctionElementX;
 import '../dart2jslib.dart';
 import '../source_file.dart';
-import '../tree/tree.dart';
+import '../tree/tree.dart' as ast;
 import '../scanner/scannerlib.dart' show Token;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import 'ir_pickler.dart' show Unpickler, IrConstantPool;
 
 /**
- * This task iterates through all resolved elements and builds [IrNode]s. The
+ * This task iterates through all resolved elements and builds [ir.Node]s. The
  * nodes are stored in the [nodes] map and accessible through [hasIr] and
  * [getIr].
  *
  * The functionality of the IrNodes is added gradually, therefore elements might
  * have an IR or not, depending on the language features that are used. For
- * elements that do have an IR, the tree [Node]s and the [Token]s are not used
+ * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not used
  * in the rest of the compilation. This is ensured by setting the element's
  * cached tree to [:null:] and also breaking the token stream to crash future
  * attempts to parse.
@@ -32,7 +32,7 @@
  * re-implemented to work directly on the IR.
  */
 class IrBuilderTask extends CompilerTask {
-  final Map<Element, IrNode> nodes = new Map<Element, IrNode>();
+  final Map<Element, ir.Node> nodes = new Map<Element, ir.Node>();
 
   IrBuilderTask(Compiler compiler) : super(compiler);
 
@@ -40,7 +40,7 @@
 
   bool hasIr(Element element) => nodes.containsKey(element.implementation);
 
-  IrNode getIr(Element element) => nodes[element.implementation];
+  ir.Node getIr(Element element) => nodes[element.implementation];
 
   void buildNodes() {
     if (!irEnabled()) return;
@@ -54,7 +54,7 @@
           SourceFile sourceFile = elementSourceFile(element);
           IrNodeBuilderVisitor visitor =
               new IrNodeBuilderVisitor(elementsMapping, compiler, sourceFile);
-          IrNode irNode;
+          ir.Node irNode;
           ElementKind kind = element.kind;
           if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
             // TODO(lry): build ir for constructors.
@@ -194,7 +194,7 @@
  * to the [builder] and return the last added statement for trees that represent
  * an expression.
  */
-class IrNodeBuilderVisitor extends ResolvedVisitor<IrNode> {
+class IrNodeBuilderVisitor extends ResolvedVisitor<ir.Node> {
   final SourceFile sourceFile;
 
   IrNodeBuilderVisitor(
@@ -206,25 +206,25 @@
   IrBuilder builder;
 
   /**
-   * Builds the [IrFunction] for a function element. In case the function
+   * Builds the [ir.Function] for a function element. In case the function
    * uses features that cannot be expressed in the IR, this function returns
    * [:null:].
    */
-  IrFunction buildMethod(FunctionElement functionElement) {
+  ir.Function buildMethod(FunctionElement functionElement) {
     return nullIfGiveup(() => buildMethodInternal(functionElement));
   }
 
-  IrFunction buildMethodInternal(FunctionElement functionElement) {
+  ir.Function buildMethodInternal(FunctionElement functionElement) {
     assert(invariant(functionElement, functionElement.isImplementation));
-    FunctionExpression function = functionElement.parseNode(compiler);
+    ast.FunctionExpression function = functionElement.parseNode(compiler);
     assert(function != null);
     assert(!function.modifiers.isExternal());
     assert(elements[function] != null);
 
     int endPosition = function.getEndToken().charOffset;
     int namePosition = elements[function].position().charOffset;
-    IrFunction result = new IrFunction(
-        nodePosition(function), endPosition, namePosition, <IrNode>[]);
+    ir.Function result = new ir.Function(
+        nodePosition(function), endPosition, namePosition, <ir.Node>[]);
     builder = new IrBuilder(this);
     builder.enterBlock();
     if (function.hasBody()) {
@@ -240,10 +240,10 @@
 
   ConstantSystem get constantSystem => compiler.backend.constantSystem;
 
-  /* int | PositionWithIdentifierName */ nodePosition(Node node) {
+  /* int | PositionWithIdentifierName */ nodePosition(ast.Node node) {
     Token token = node.getBeginToken();
     if (token.isIdentifier()) {
-      return new PositionWithIdentifierName(token.charOffset, token.value);
+      return new ir.PositionWithIdentifierName(token.charOffset, token.value);
     } else {
       return token.charOffset;
     }
@@ -256,24 +256,24 @@
    * statement on each branch. This includes functions with an empty body,
    * such as [:foo(){ }:].
    */
-  void ensureReturn(FunctionExpression node) {
+  void ensureReturn(ast.FunctionExpression node) {
     if (blockReturns) return;
-    IrConstant nullValue =
+    ir.Constant nullValue =
         builder.addConstant(constantSystem.createNull(), node);
-    builder.addStatement(new IrReturn(nodePosition(node), nullValue));
+    builder.addStatement(new ir.Return(nodePosition(node), nullValue));
   }
 
-  IrNode visitBlock(Block node) {
-    for (Node n in node.statements.nodes) {
+  ir.Node visitBlock(ast.Block node) {
+    for (ast.Node n in node.statements.nodes) {
       n.accept(this);
       if (blockReturns) return null;
     }
     return null;
   }
 
-  IrNode visitReturn(Return node) {
+  ir.Node visitReturn(ast.Return node) {
     assert(!blockReturns);
-    IrExpression value;
+    ir.Expression value;
     // TODO(lry): support native returns.
     if (node.beginToken.value == 'native') giveup();
     if (node.expression == null) {
@@ -281,29 +281,29 @@
     } else {
       value = node.expression.accept(this);
     }
-    builder.addStatement(new IrReturn(nodePosition(node), value));
+    builder.addStatement(new ir.Return(nodePosition(node), value));
     builder.block.hasReturn = true;
     return null;
   }
 
-  IrConstant visitLiteralBool(LiteralBool node) {
+  ir.Constant visitLiteralBool(ast.LiteralBool node) {
     return builder.addConstant(constantSystem.createBool(node.value), node);
   }
 
-  IrConstant visitLiteralDouble(LiteralDouble node) {
+  ir.Constant visitLiteralDouble(ast.LiteralDouble node) {
     return builder.addConstant(constantSystem.createDouble(node.value), node);
   }
 
-  IrConstant visitLiteralInt(LiteralInt node) {
+  ir.Constant visitLiteralInt(ast.LiteralInt node) {
     return builder.addConstant(constantSystem.createInt(node.value), node);
   }
 
-  IrConstant visitLiteralString(LiteralString node) {
+  ir.Constant visitLiteralString(ast.LiteralString node) {
     Constant value = constantSystem.createString(node.dartString);
     return builder.addConstant(value, node);
   }
 
-  IrConstant visitLiteralNull(LiteralNull node) {
+  ir.Constant visitLiteralNull(ast.LiteralNull node) {
     return builder.addConstant(constantSystem.createNull(), node);
   }
 
@@ -313,32 +313,32 @@
 //  IrNode visitLiteralMapEntry(LiteralMapEntry node) => visitNode(node);
 //  IrNode visitLiteralSymbol(LiteralSymbol node) => visitExpression(node);
 
-  IrNode visitAssert(Send node) {
+  ir.Node visitAssert(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitClosureSend(Send node) {
+  ir.Node visitClosureSend(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitDynamicSend(Send node) {
+  ir.Node visitDynamicSend(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitGetterSend(Send node) {
+  ir.Node visitGetterSend(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitOperatorSend(Send node) {
+  ir.Node visitOperatorSend(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitStaticSend(Send node) {
+  ir.Node visitStaticSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
     Element element = elements[node];
 
@@ -354,7 +354,7 @@
     // TODO(lry): support named arguments
     if (selector.namedArgumentCount != 0) giveup();
 
-    List<IrExpression> arguments = <IrExpression>[];
+    List<ir.Expression> arguments = <ir.Expression>[];
     // TODO(lry): support default arguments, need support for locals.
     bool succeeded = selector.addArgumentsToList(
         node.arguments, arguments, element.implementation,
@@ -365,26 +365,26 @@
     }
     // TODO(lry): generate IR for object identicality.
     if (element == compiler.identicalFunction) giveup();
-    IrInvokeStatic result = builder.addStatement(
-        new IrInvokeStatic(nodePosition(node), element, selector, arguments));
+    ir.InvokeStatic result = builder.addStatement(
+        new ir.InvokeStatic(nodePosition(node), element, selector, arguments));
     return result;
   }
 
-  IrNode visitSuperSend(Send node) {
+  ir.Node visitSuperSend(ast.Send node) {
     giveup();
     return null;
   }
 
-  IrNode visitTypeReferenceSend(Send node) {
+  ir.Node visitTypeReferenceSend(ast.Send node) {
     giveup();
     return null;
   }
 
   static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
 
-  IrNode giveup() => throw ABORT_IRNODE_BUILDER;
+  ir.Node giveup() => throw ABORT_IRNODE_BUILDER;
 
-  IrNode nullIfGiveup(IrNode action()) {
+  ir.Node nullIfGiveup(ir.Node action()) {
     try {
       return action();
     } catch(e) {
@@ -393,7 +393,7 @@
     }
   }
 
-  void internalError(String reason, {Node node}) {
+  void internalError(String reason, {ast.Node node}) {
     giveup();
   }
 }
@@ -406,14 +406,14 @@
 
   BlockBuilder get block => blockBuilders.last;
 
-  Map<Constant, IrConstant> constants = <Constant, IrConstant>{};
+  Map<Constant, ir.Constant> constants = <Constant, ir.Constant>{};
 
-  IrConstant addConstant(Constant value, Node node) {
+  ir.Constant addConstant(Constant value, ast.Node node) {
     return constants.putIfAbsent(
-      value, () => new IrConstant(visitor.nodePosition(node), value));
+      value, () => new ir.Constant(visitor.nodePosition(node), value));
   }
 
-  IrNode addStatement(IrNode statement) {
+  ir.Node addStatement(ir.Node statement) {
     block.statements.add(statement);
     return statement;
   }
@@ -428,6 +428,6 @@
 }
 
 class BlockBuilder {
-  List<IrNode> statements = <IrNode>[];
+  List<ir.Node> statements = <ir.Node>[];
   bool hasReturn = false;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart
index dfdadaf..1ea1611 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart
@@ -6,7 +6,7 @@
 // dependencies on other parts of the system.
 library dart2js.ir_nodes;
 
-import '../dart2jslib.dart' show Constant;
+import '../dart2jslib.dart' as dart2js show Constant;
 import '../elements/elements.dart' show FunctionElement, LibraryElement;
 import 'ir_pickler.dart' show Pickler, IrConstantPool;
 import '../universe/universe.dart' show Selector, SelectorKind;
@@ -22,13 +22,13 @@
   PositionWithIdentifierName(this.offset, this.sourceName);
 }
 
-abstract class IrNode implements Spannable {
+abstract class Node implements Spannable {
   static int hashCount = 0;
   final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
 
   final /* int | PositionWithIdentifierName */ position;
 
-  const IrNode(this.position);
+  const Node(this.position);
 
   int get offset => (position is int) ? position : position.offset;
 
@@ -38,45 +38,45 @@
     return new Pickler(constantPool).pickle(this);
   }
 
-  accept(IrNodesVisitor visitor);
+  accept(NodesVisitor visitor);
 }
 
-abstract class IrExpression extends IrNode {
-  IrExpression(position) : super(position);
+abstract class Expression extends Node {
+  Expression(position) : super(position);
 }
 
-class IrFunction extends IrExpression {
-  final List<IrNode> statements;
+class Function extends Expression {
+  final List<Node> statements;
 
   final int endOffset;
   final int namePosition;
 
-  IrFunction(position, this.endOffset, this.namePosition, this.statements)
+  Function(position, this.endOffset, this.namePosition, this.statements)
     : super(position);
 
-  accept(IrNodesVisitor visitor) => visitor.visitIrFunction(this);
+  accept(NodesVisitor visitor) => visitor.visitFunction(this);
 }
 
-class IrReturn extends IrNode {
-  final IrExpression value;
+class Return extends Node {
+  final Expression value;
 
-  IrReturn(position, this.value) : super(position);
+  Return(position, this.value) : super(position);
 
-  accept(IrNodesVisitor visitor) => visitor.visitIrReturn(this);
+  accept(NodesVisitor visitor) => visitor.visitReturn(this);
 }
 
-class IrConstant extends IrExpression {
-  final Constant value;
+class Constant extends Expression {
+  final dart2js.Constant value;
 
-  IrConstant(position, this.value) : super(position);
+  Constant(position, this.value) : super(position);
 
-  accept(IrNodesVisitor visitor) => visitor.visitIrConstant(this);
+  accept(NodesVisitor visitor) => visitor.visitConstant(this);
 }
 
-class IrInvokeStatic extends IrExpression {
+class InvokeStatic extends Expression {
   final FunctionElement target;
 
-  final List<IrExpression> arguments;
+  final List<Expression> arguments;
 
   /**
    * The selector encodes how the function is invoked: number of positional
@@ -85,37 +85,37 @@
    */
   final Selector selector;
 
-  IrInvokeStatic(position, this.target, this.selector, this.arguments)
+  InvokeStatic(position, this.target, this.selector, this.arguments)
     : super(position) {
     assert(selector.kind == SelectorKind.CALL);
     assert(selector.name == target.name);
   }
 
-  accept(IrNodesVisitor visitor) => visitor.visitIrInvokeStatic(this);
+  accept(NodesVisitor visitor) => visitor.visitInvokeStatic(this);
 }
 
 /**
  * This class is only used during SSA generation, its instances never appear in
  * the representation of a function. See [SsaFromAstInliner.enterInlinedMethod].
  */
-class IrInlinedInvocationDummy extends IrExpression {
-  IrInlinedInvocationDummy() : super(0);
-  accept(IrNodesVisitor visitor) => throw "IrInlinedInvocationDummy.accept";
+class InlinedInvocationDummy extends Expression {
+  InlinedInvocationDummy() : super(0);
+  accept(NodesVisitor visitor) => throw "IrInlinedInvocationDummy.accept";
 }
 
 
-abstract class IrNodesVisitor<T> {
-  T visit(IrNode node) => node.accept(this);
+abstract class NodesVisitor<T> {
+  T visit(Node node) => node.accept(this);
 
-  void visitAll(List<IrNode> nodes) {
-    for (IrNode n in nodes) visit(n);
+  void visitAll(List<Node> nodes) {
+    for (Node n in nodes) visit(n);
   }
 
-  T visitIrNode(IrNode node);
+  T visitNode(Node node);
 
-  T visitIrExpression(IrExpression node) => visitIrNode(node);
-  T visitIrFunction(IrFunction node) => visitIrExpression(node);
-  T visitIrReturn(IrReturn node) => visitIrNode(node);
-  T visitIrConstant(IrConstant node) => visitIrExpression(node);
-  T visitIrInvokeStatic(IrInvokeStatic node) => visitIrExpression(node);
+  T visitExpression(Expression node) => visitNode(node);
+  T visitFunction(Function node) => visitExpression(node);
+  T visitReturn(Return node) => visitNode(node);
+  T visitConstant(Constant node) => visitExpression(node);
+  T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
index bd79382..327cad3 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
@@ -4,17 +4,17 @@
 
 library dart2js.ir_pickler;
 
-import 'ir_nodes.dart';
+import 'ir_nodes.dart' as ir;
 import '../dart2jslib.dart' show
     Constant, FalseConstant, TrueConstant, IntConstant, DoubleConstant,
     StringConstant, NullConstant, ListConstant, MapConstant,
-    InterceptorConstant, DummyReceiverConstant, FunctionConstant, TypeConstant,
+    InterceptorConstant, DummyConstant, FunctionConstant, TypeConstant,
     ConstructedConstant,
     ConstantVisitor, ConstantSystem,
     Compiler;
 import 'dart:typed_data' show ByteData, Endianness, Uint8List;
 import 'dart:convert' show UTF8;
-import '../tree/tree.dart' show
+import '../tree/tree.dart' as ast show
     DartString, LiteralDartString, RawSourceDartString, EscapedSourceDartString,
     ConsDartString;
 import '../elements/elements.dart' show
@@ -150,9 +150,9 @@
 }
 
 /**
- * The [Pickler] serializes [IrNode]s to a byte array.
+ * The [Pickler] serializes [ir.Node]s to a byte array.
  */
-class Pickler extends IrNodesVisitor {
+class Pickler extends ir.NodesVisitor {
   ConstantPickler constantPickler;
 
   IrConstantPool constantPool;
@@ -182,7 +182,7 @@
    */
   ByteData doubleData = new ByteData(8);
 
-  List<int> pickle(IrNode node) {
+  List<int> pickle(ir.Node node) {
     data = new Uint8List(INITIAL_SIZE);
     offset = 0;
     emitted = <Object, int>{};
@@ -308,7 +308,7 @@
       writeByte(Pickles.POSITION_OFFSET);
       writeInt(position);
     } else {
-      PositionWithIdentifierName namedPosition = position;
+      ir.PositionWithIdentifierName namedPosition = position;
       writeByte(Pickles.POSITION_WITH_ID);
       writeString(namedPosition.sourceName);
       writeInt(namedPosition.offset);
@@ -333,19 +333,19 @@
     }
   }
 
-  void writeDartString(DartString s) {
-    if (s is LiteralDartString) {
+  void writeDartString(ast.DartString s) {
+    if (s is ast.LiteralDartString) {
       writeByte(Pickles.CONST_STRING_LITERAL);
       writeString(s.string);
-    } else if (s is RawSourceDartString) {
+    } else if (s is ast.RawSourceDartString) {
       writeByte(Pickles.CONST_STRING_RAW);
       writeString(s.source);
       writeInt(s.length);
-    } else if (s is EscapedSourceDartString) {
+    } else if (s is ast.EscapedSourceDartString) {
       writeByte(Pickles.CONST_STRING_ESCAPED);
       writeString(s.source);
       writeInt(s.length);
-    } else if (s is ConsDartString) {
+    } else if (s is ast.ConsDartString) {
       writeByte(Pickles.CONST_STRING_CONS);
       writeDartString(s.left);
       writeDartString(s.right);
@@ -382,14 +382,14 @@
     }
   }
 
-  void writeNodeList(List<IrNode> nodes) {
+  void writeNodeList(List<ir.Node> nodes) {
     writeInt(nodes.length);
     for (int i = 0; i < nodes.length; i++) {
       nodes[i].accept(this);
     }
   }
 
-  void visitIrFunction(IrFunction node) {
+  void visitFunction(ir.Function node) {
     recordForBackReference(node);
     writeByte(Pickles.NODE_FUNCTION);
     writePosition(node.position);
@@ -398,20 +398,20 @@
     writeNodeList(node.statements);
   }
 
-  void visitIrReturn(IrReturn node) {
+  void visitReturn(ir.Return node) {
     writeByte(Pickles.NODE_RETURN);
     writePosition(node.position);
     writeBackReference(node.value);
   }
 
-  void visitIrConstant(IrConstant node) {
+  void visitConstant(ir.Constant node) {
     recordForBackReference(node);
     writeByte(Pickles.NODE_CONST);
     writePosition(node.position);
     node.value.accept(constantPickler);
   }
 
-  void visitIrInvokeStatic(IrInvokeStatic node) {
+  void visitInvokeStatic(ir.InvokeStatic node) {
     recordForBackReference(node);
     writeByte(Pickles.NODE_INVOKE_STATIC);
     writePosition(node.position);
@@ -422,7 +422,7 @@
     writeBackReferenceList(node.arguments);
   }
 
-  void visitIrNode(IrNode node) {
+  void visitNode(ir.Node node) {
     throw "Unexpected $node in pickler.";
   }
 }
@@ -462,7 +462,7 @@
   void visitList(ListConstant constant) => abort(constant);
   void visitMap(MapConstant constant) => abort(constant);
   void visitInterceptor(InterceptorConstant constant) => abort(constant);
-  void visitDummyReceiver(DummyReceiverConstant constant) => abort(constant);
+  void visitDummy(DummyConstant constant) => abort(constant);
   void visitFunction(FunctionConstant constant) => abort(constant);
   void visitType(TypeConstant constant) => abort(constant);
   void visitConstructed(ConstructedConstant constant) => abort(constant);
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart
index 428785e..e55aa54 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart
@@ -29,7 +29,7 @@
 
   ConstantSystem get constantSystem => compiler.backend.constantSystem;
 
-  IrFunction unpickle(List<int> data) {
+  ir.Function unpickle(List<int> data) {
     this.data = data;
     offset = 0;
     int numEntries = readInt();
@@ -100,10 +100,10 @@
   }
 
   /**
-   * Reads a [IrNode]. Expression nodes are added to the [unpickled] map to
+   * Reads a [ir.Node]. Expression nodes are added to the [unpickled] map to
    * enable unpickling back references.
    */
-  IrNode readNode() {
+  ir.Node readNode() {
     int tag = readByte();
     if (Pickles.isExpressionTag(tag)) {
       return readExpressionNode(tag);
@@ -115,9 +115,9 @@
     }
   }
 
-  IrExpression readExpressionNode(int tag) {
+  ir.Expression readExpressionNode(int tag) {
     int entryIndex = index++;
-    IrExpression result;
+    ir.Expression result;
     if (tag == Pickles.NODE_CONST) {
       result = readConstantNode();
     } else if (tag == Pickles.NODE_FUNCTION) {
@@ -137,50 +137,50 @@
     return unpickled[entryIndex];
   }
 
-  List<IrExpression> readExpressionBackReferenceList() {
+  List<ir.Expression> readExpressionBackReferenceList() {
     int length = readInt();
-    List<IrExpression> result = new List<IrExpression>(length);
+    List<ir.Expression> result = new List<ir.Expression>(length);
     for (int i = 0; i < length; i++) {
       result[i] = readBackReference();
     }
     return result;
   }
 
-  List<IrNode> readNodeList() {
+  List<ir.Node> readNodeList() {
     int length = readInt();
-    List<IrNode> nodes = new List<IrNode>(length);
+    List<ir.Node> nodes = new List<ir.Node>(length);
     for (int i = 0; i < length; i++) {
       nodes[i] = readNode();
     }
     return nodes;
   }
 
-  IrFunction readFunctionNode() {
+  ir.Function readFunctionNode() {
     var position = readPosition();
     int endOffset = readInt();
     int namePosition = readInt();
-    List<IrNode> statements = readNodeList();
-    return new IrFunction(position, endOffset, namePosition, statements);
+    List<ir.Node> statements = readNodeList();
+    return new ir.Function(position, endOffset, namePosition, statements);
   }
 
-  IrConstant readConstantNode() {
+  ir.Constant readConstantNode() {
     var position = readPosition();
     Constant constant = readConstant();
-    return new IrConstant(position, constant);
+    return new ir.Constant(position, constant);
   }
 
-  IrReturn readReturnNode() {
+  ir.Return readReturnNode() {
     var position = readPosition();
-    IrExpression value = readBackReference();
-    return new IrReturn(position, value);
+    ir.Expression value = readBackReference();
+    return new ir.Return(position, value);
   }
 
-  IrInvokeStatic readInvokeStaticNode() {
+  ir.InvokeStatic readInvokeStaticNode() {
     var position = readPosition();
     FunctionElement functionElement = readElement();
     Selector selector = readSelector();
-    List<IrExpression> arguments = readExpressionBackReferenceList();
-    return new IrInvokeStatic(position, functionElement, selector, arguments);
+    List<ir.Expression> arguments = readExpressionBackReferenceList();
+    return new ir.InvokeStatic(position, functionElement, selector, arguments);
   }
 
   /* int | PositionWithIdentifierName */ readPosition() {
@@ -189,7 +189,7 @@
     } else {
       String sourceName = readString();
       int offset = readInt();
-      return new PositionWithIdentifierName(offset, sourceName);
+      return new ir.PositionWithIdentifierName(offset, sourceName);
     }
   }
 
@@ -219,16 +219,16 @@
     }
   }
 
-  DartString readDartString(int tag) {
+  ast.DartString readDartString(int tag) {
     switch(tag) {
       case Pickles.CONST_STRING_LITERAL:
-        return new LiteralDartString(readString());
+        return new ast.LiteralDartString(readString());
       case Pickles.CONST_STRING_RAW:
-        return new RawSourceDartString(readString(), readInt());
+        return new ast.RawSourceDartString(readString(), readInt());
       case Pickles.CONST_STRING_ESCAPED:
-        return new EscapedSourceDartString(readString(), readInt());
+        return new ast.EscapedSourceDartString(readString(), readInt());
       case Pickles.CONST_STRING_CONS:
-        return new ConsDartString(
+        return new ast.ConsDartString(
             readDartString(readByte()), readDartString(readByte()));
       default:
         compiler.internalError("Unexpected dart string tag: $tag");
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 3d58931..8e8366b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -1910,7 +1910,7 @@
 
   void visitInterceptor(InterceptorConstant constant) => copy(constant);
 
-  void visitDummyReceiver(DummyReceiverConstant constant) => copy(constant);
+  void visitDummy(DummyConstant constant) => copy(constant);
 
   void visitList(ListConstant constant) {
     copy(constant.entries);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index c8edc9b..f19fc1b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -145,7 +145,7 @@
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitDummyReceiver(DummyReceiverConstant constant) {
+  jsAst.Expression visitDummy(DummyConstant constant) {
     return new jsAst.LiteralNumber('0');
   }
 }
@@ -318,7 +318,7 @@
         'prototype');
   }
 
-  jsAst.Expression visitDummyReceiver(DummyReceiverConstant constant) {
+  jsAst.Expression visitDummy(DummyConstant constant) {
     return _reference(constant);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 8ac77b0..1b79342 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -1189,7 +1189,7 @@
     add('methods');
   }
 
-  visitDummyReceiver(DummyReceiverConstant constant) {
+  visitDummy(DummyConstant constant) {
     add('dummy_receiver');
   }
 }
@@ -1269,7 +1269,7 @@
     return _hashString(5, typeName);
   }
 
-  visitDummyReceiver(DummyReceiverConstant constant) {
+  visitDummy(DummyConstant constant) {
     compiler.internalError(
         'DummyReceiverConstant should never be named and never be subconstant');
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index e09cc2f..df46098 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -275,10 +275,9 @@
     for (DartType instantiatedType in universe.instantiatedTypes) {
       if (instantiatedType.kind == TypeKind.INTERFACE) {
         InterfaceType interface = instantiatedType;
-        InterfaceTypeMember member =
-            interface.lookupMember(Compiler.CALL_OPERATOR_NAME);
-        if (member != null) {
-          instantiatedTypes.add(member.computeType(compiler));
+        FunctionType callType = interface.callType;
+        if (callType != null) {
+          instantiatedTypes.add(callType);
         }
       }
     }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart b/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
index 5dc0126..746f7f8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
@@ -104,7 +104,9 @@
     if (constructors.isEmpty && constructors.tail.isEmpty) {
       compiler.reportInternalError(
           typeVariableClass,
-          "Class '$typeVariableClass' should only have one constructor");
+          MessageKind.GENERIC,
+          {'text': "Class '$typeVariableClass' should only "
+                   "have one constructor"});
     }
     typeVariableConstructor = typeVariableClass.constructors.head;
     backend.enqueueInResolution(typeVariableConstructor,
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
index 9a6ca0b..b28becf 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -204,7 +204,8 @@
             int code = getterCode + (setterCode << 2);
             if (code == 0) {
               compiler.reportInternalError(
-                  field, 'Internal error: code is 0 ($element/$field)');
+                  field, MessageKind.GENERIC,
+                  {'text': 'Field code is 0 ($element/$field)'});
             } else {
               fieldCode = FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE];
             }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index 88359b1..8006c61 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -926,9 +926,9 @@
   }
 
   bool isConstantInlinedOrAlreadyEmitted(Constant constant) {
-    if (constant.isFunction()) return true;       // Already emitted.
-    if (constant.isPrimitive()) return true;      // Inlined.
-    if (constant.isDummyReceiver()) return true;  // Inlined.
+    if (constant.isFunction()) return true;    // Already emitted.
+    if (constant.isPrimitive()) return true;   // Inlined.
+    if (constant.isDummy()) return true;       // Inlined.
     // The name is null when the constant is already a JS constant.
     // TODO(floitsch): every constant should be registered, so that we can
     // share the ones that take up too much space (like some strings).
@@ -964,13 +964,15 @@
 ''');
   }
 
-  String buildIsolateSetup(CodeBuffer buffer,
-                           Element appMain,
-                           Element isolateMain) {
+  /// Returns the code equivalent to:
+  ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
+  String buildIsolateSetupClosure(CodeBuffer buffer,
+                                  Element appMain,
+                                  Element isolateMain) {
     String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}";
     // Since we pass the closurized version of the main method to
     // the isolate method, we must make sure that it exists.
-    return "${namer.isolateAccess(isolateMain)}($mainAccess)";
+    return "(function(a){${namer.isolateAccess(isolateMain)}($mainAccess,a)})";
   }
 
   /**
@@ -1023,13 +1025,13 @@
   emitMain(CodeBuffer buffer) {
     if (compiler.isMockCompilation) return;
     Element main = compiler.mainFunction;
-    String mainCall = null;
+    String mainCallClosure = null;
     if (compiler.hasIsolateSupport()) {
       Element isolateMain =
         compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE);
-      mainCall = buildIsolateSetup(buffer, main, isolateMain);
+      mainCallClosure = buildIsolateSetupClosure(buffer, main, isolateMain);
     } else {
-      mainCall = '${namer.isolateAccess(main)}()';
+      mainCallClosure = '${namer.isolateAccess(main)}';
     }
 
     if (backend.needToInitializeIsolateAffinityTag) {
@@ -1076,9 +1078,9 @@
   init.currentScript = currentScript;
 
   if (typeof dartMainRunner === "function") {
-    dartMainRunner(function() { ${mainCall}; });
+    dartMainRunner(${mainCallClosure}, []);
   } else {
-    ${mainCall};
+    ${mainCallClosure}([]);
   }
 })$N''');
     addComment('END invoke [main].', buffer);
@@ -1275,7 +1277,7 @@
 
       // Using a named function here produces easier to read stack traces in
       // Chrome/V8.
-      mainBuffer.add('function dart() {}');
+      mainBuffer.add('function dart(){${_}this.x$_=${_}0$_}');
       for (String globalObject in Namer.reservedGlobalObjectNames) {
         // The global objects start as so-called "slow objects". For V8, this
         // means that it won't try to make map transitions as we add properties
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
index 98ef937..dc4e201 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -425,18 +425,8 @@
         if (member.isInstanceMember()) {
           Set invokedSelectors =
               compiler.codegenWorld.invokedNames[member.name];
-          //if (invokedSelectors != null && invokedSelectors.contains(selector)) {
             expressions.add(js.string(namer.invocationName(selector)));
-          //} else {
-          //  // Don't add a stub for calling this as a regular instance method,
-          //  // we only need the "call" stub for implicit closures of this
-          //  // method.
-          //  expressions.add("null");
-          //}
         } else {
-          // Static methods don't need "named" stubs as the default arguments
-          // are inlined at call sites. But static methods might need "call"
-          // stubs for implicit closures.
           expressions.add("null");
           // TOOD(ahe): Since we know when reading static data versus instance
           // data, we can eliminate this element.
@@ -484,16 +474,14 @@
         ..addAll(task.metadataEmitter.reifyDefaultArguments(member));
 
     if (canBeReflected || canBeApplied) {
-      parameters.orderedForEachParameter((Element parameter) {
+      parameters.forEachParameter((Element parameter) {
         expressions.add(task.metadataEmitter.reifyName(parameter.name));
         List<MetadataAnnotation> annotations = parameter.metadata.toList();
         Iterable<int> metadataIndices = annotations.map((MetadataAnnotation a) {
           compiler.constantHandler.addCompileTimeConstantForEmission(a.value);
           return task.metadataEmitter.reifyMetadata(a);
         });
-        // TODO(karlklose): store metadata on elements in correct source order.
-        metadataIndices = metadataIndices.toList().reversed.toList();
-        expressions.add(metadataIndices.isNotEmpty ? metadataIndices
+        expressions.add(metadataIndices.isNotEmpty ? metadataIndices.toList()
                                                    : js('[]'));
       });
     }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
index 8ca7b9b..a370cd2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
@@ -57,12 +57,14 @@
 
 const String HOOKS_API_USAGE = """
 // The code supports the following hooks:
-// dartPrint(message)   - if this function is defined it is called
-//                        instead of the Dart [print] method.
-// dartMainRunner(main) - if this function is defined, the Dart [main]
-//                        method will not be invoked directly.
-//                        Instead, a closure that will invoke [main] is
-//                        passed to [dartMainRunner].
+// dartPrint(message):
+//    if this function is defined it is called instead of the Dart [print]
+//    method.
+//
+// dartMainRunner(main, args):
+//    if this function is defined, the Dart [main] method will not be invoked
+//    directly. Instead, a closure that will invoke [main], and its arguments
+//    [args] is passed to [dartMainRunner].
 """;
 
 // Compact field specifications.  The format of the field specification is
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/metadata_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/metadata_emitter.dart
index 85570b2..b6eb5c8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/metadata_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/metadata_emitter.dart
@@ -29,8 +29,8 @@
           MetadataAnnotation annotation = link.head;
           Constant value = annotation.value;
           if (value == null) {
-            compiler.reportInternalError(
-                annotation, 'Internal error: value is null');
+            compiler.reportInternalError(annotation,
+                MessageKind.GENERIC, {'text': 'Annotation value is null'});
           } else {
             metadata.add(task.constantReference(value));
           }
@@ -46,7 +46,7 @@
     FunctionSignature signature = function.computeSignature(compiler);
     if (signature.optionalParameterCount == 0) return const [];
     List<int> defaultValues = <int>[];
-    for (Element element in signature.orderedOptionalParameters) {
+    for (Element element in signature.optionalParameters) {
       Constant value =
           compiler.constantHandler.initialVariableValues[element];
       String stringRepresentation = (value == null)
@@ -61,8 +61,8 @@
   int reifyMetadata(MetadataAnnotation annotation) {
     Constant value = annotation.value;
     if (value == null) {
-      compiler.reportInternalError(
-          annotation, 'Internal error: value is null');
+      compiler.reportInternalError(annotation,
+          MessageKind.GENERIC, {'text': 'Annotation value is null'});
       return -1;
     }
     return addGlobalMetadata(
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 478f36f..53e79da 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -343,16 +343,16 @@
       LibraryElement existing =
           libraryNames.putIfAbsent(name, () => library);
       if (!identical(existing, library)) {
-        Uri uri = library.entryCompilationUnit.script.uri;
-        compiler.reportMessage(
-            compiler.spanFromSpannable(tag.name, uri),
-            MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
-            api.Diagnostic.WARNING);
-        Uri existingUri = existing.entryCompilationUnit.script.uri;
-        compiler.reportMessage(
-            compiler.spanFromSpannable(existing.libraryTag.name, existingUri),
-            MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
-            api.Diagnostic.WARNING);
+        compiler.withCurrentElement(library, () {
+          compiler.reportWarning(tag.name,
+              MessageKind.DUPLICATED_LIBRARY_NAME,
+              {'libraryName': name});
+        });
+        compiler.withCurrentElement(existing, () {
+          compiler.reportWarning(existing.libraryTag.name,
+              MessageKind.DUPLICATED_LIBRARY_NAME,
+              {'libraryName': name});
+        });
       }
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart b/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
index c1231a8..fe10b0f 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
@@ -1,66 +1,66 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file

-// for details. All rights reserved. Use of this source code is governed by a

-// BSD-style license that can be found in the LICENSE file.

-

-library dart2js.source_mirrors.analyze;

-

-import 'dart:async';

-

-import 'source_mirrors.dart';

-import 'dart2js_mirrors.dart' show Dart2JsMirrorSystem;

-import '../../compiler.dart' as api;

-import '../apiimpl.dart' as apiimpl;

-import '../dart2jslib.dart' show Compiler;

-

-//------------------------------------------------------------------------------

-// Analysis entry point.

-//------------------------------------------------------------------------------

-

-/**

- * Analyzes set of libraries and provides a mirror system which can be used for

- * static inspection of the source code.

- */

-// TODO(johnniwinther): Move this to [compiler/compiler.dart].

-Future<MirrorSystem> analyze(List<Uri> libraries,

-                             Uri libraryRoot,

-                             Uri packageRoot,

-                             api.CompilerInputProvider inputProvider,

-                             api.DiagnosticHandler diagnosticHandler,

-                             [List<String> options = const <String>[]]) {

-  if (!libraryRoot.path.endsWith("/")) {

-    throw new ArgumentError("libraryRoot must end with a /");

-  }

-  if (packageRoot != null && !packageRoot.path.endsWith("/")) {

-    throw new ArgumentError("packageRoot must end with a /");

-  }

-  options = new List<String>.from(options);

-  options.add('--analyze-only');

-  options.add('--analyze-signatures-only');

-  options.add('--analyze-all');

-  options.add('--categories=Client,Server');

-

-  bool compilationFailed = false;

-  void internalDiagnosticHandler(Uri uri, int begin, int end,

-                                 String message, api.Diagnostic kind) {

-    if (kind == api.Diagnostic.ERROR ||

-        kind == api.Diagnostic.CRASH) {

-      compilationFailed = true;

-    }

-    diagnosticHandler(uri, begin, end, message, kind);

-  }

-

-  Compiler compiler = new apiimpl.Compiler(inputProvider,

-                                           null,

-                                           internalDiagnosticHandler,

-                                           libraryRoot, packageRoot,

-                                           options,

-                                           const {});

-  compiler.librariesToAnalyzeWhenRun = libraries;

-  return compiler.run(null).then((bool success) {

-    if (success && !compilationFailed) {

-      return new Dart2JsMirrorSystem(compiler);

-    } else {

-      throw new StateError('Failed to create mirror system.');

-    }

-  });

-}

+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.source_mirrors.analyze;
+
+import 'dart:async';
+
+import 'source_mirrors.dart';
+import 'dart2js_mirrors.dart' show Dart2JsMirrorSystem;
+import '../../compiler.dart' as api;
+import '../apiimpl.dart' as apiimpl;
+import '../dart2jslib.dart' show Compiler;
+
+//------------------------------------------------------------------------------
+// Analysis entry point.
+//------------------------------------------------------------------------------
+
+/**
+ * Analyzes set of libraries and provides a mirror system which can be used for
+ * static inspection of the source code.
+ */
+// TODO(johnniwinther): Move this to [compiler/compiler.dart].
+Future<MirrorSystem> analyze(List<Uri> libraries,
+                             Uri libraryRoot,
+                             Uri packageRoot,
+                             api.CompilerInputProvider inputProvider,
+                             api.DiagnosticHandler diagnosticHandler,
+                             [List<String> options = const <String>[]]) {
+  if (!libraryRoot.path.endsWith("/")) {
+    throw new ArgumentError("libraryRoot must end with a /");
+  }
+  if (packageRoot != null && !packageRoot.path.endsWith("/")) {
+    throw new ArgumentError("packageRoot must end with a /");
+  }
+  options = new List<String>.from(options);
+  options.add('--analyze-only');
+  options.add('--analyze-signatures-only');
+  options.add('--analyze-all');
+  options.add('--categories=Client,Server');
+
+  bool compilationFailed = false;
+  void internalDiagnosticHandler(Uri uri, int begin, int end,
+                                 String message, api.Diagnostic kind) {
+    if (kind == api.Diagnostic.ERROR ||
+        kind == api.Diagnostic.CRASH) {
+      compilationFailed = true;
+    }
+    diagnosticHandler(uri, begin, end, message, kind);
+  }
+
+  Compiler compiler = new apiimpl.Compiler(inputProvider,
+                                           null,
+                                           internalDiagnosticHandler,
+                                           libraryRoot, packageRoot,
+                                           options,
+                                           const {});
+  compiler.librariesToAnalyzeWhenRun = libraries;
+  return compiler.run(null).then((bool success) {
+    if (success && !compilationFailed) {
+      return new Dart2JsMirrorSystem(compiler);
+    } else {
+      throw new StateError('Failed to create mirror system.');
+    }
+  });
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart
index 06197ee..c3c2b39 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart
@@ -1,286 +1,286 @@
-// 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 dart2js.mirrors;

-

-abstract class ObjectMirrorMixin implements ObjectMirror {

-  InstanceMirror getField(Symbol fieldName) {

-    throw new UnsupportedError('ObjectMirror.getField unsupported.');

-  }

-

-  InstanceMirror setField(Symbol fieldName, Object value) {

-    throw new UnsupportedError('ObjectMirror.setField unsupported.');

-  }

-

-  InstanceMirror invoke(Symbol memberName,

-                        List positionalArguments,

-                        [Map<Symbol, dynamic> namedArguments]) {

-    throw new UnsupportedError('ObjectMirror.invoke unsupported.');

-  }

-}

-

-abstract class InstanceMirrorMixin implements InstanceMirror {

-

-  bool get hasReflectee => false;

-

-  get reflectee {

-    throw new UnsupportedError('InstanceMirror.reflectee unsupported.');

-  }

-

-  Function operator [](Symbol name) {

-    throw new UnsupportedError('InstanceMirror.operator [] unsupported.');

-  }

-

-  delegate(Invocation invocation) {

-    throw new UnsupportedError('InstanceMirror.delegate unsupported');

-  }

-}

-

-InstanceMirror _convertConstantToInstanceMirror(

-    Dart2JsMirrorSystem mirrorSystem, Constant constant) {

-  if (constant is BoolConstant) {

-    return new Dart2JsBoolConstantMirror(mirrorSystem, constant);

-  } else if (constant is NumConstant) {

-    return new Dart2JsNumConstantMirror(mirrorSystem, constant);

-  } else if (constant is StringConstant) {

-    return new Dart2JsStringConstantMirror(mirrorSystem, constant);

-  } else if (constant is ListConstant) {

-    return new Dart2JsListConstantMirror(mirrorSystem, constant);

-  } else if (constant is MapConstant) {

-    return new Dart2JsMapConstantMirror(mirrorSystem, constant);

-  } else if (constant is TypeConstant) {

-    return new Dart2JsTypeConstantMirror(mirrorSystem, constant);

-  } else if (constant is FunctionConstant) {

-    return new Dart2JsConstantMirror(mirrorSystem, constant);

-  } else if (constant is NullConstant) {

-    return new Dart2JsNullConstantMirror(mirrorSystem, constant);

-  } else if (constant is ConstructedConstant) {

-    return new Dart2JsConstructedConstantMirror(mirrorSystem, constant);

-  }

-  mirrorSystem.compiler.internalError("Unexpected constant $constant");

-  return null;

-}

-

-

-////////////////////////////////////////////////////////////////////////////////

-// Mirrors on constant values used for metadata.

-////////////////////////////////////////////////////////////////////////////////

-

-class Dart2JsConstantMirror extends Object

-    with ObjectMirrorMixin, InstanceMirrorMixin

-    implements InstanceMirror {

-  final Dart2JsMirrorSystem mirrorSystem;

-  final Constant _constant;

-

-  Dart2JsConstantMirror(this.mirrorSystem, this._constant);

-

-  // TODO(johnniwinther): Improve the quality of this method.

-  String toString() => '$_constant';

-

-  ClassMirror get type {

-    return mirrorSystem._getTypeDeclarationMirror(

-        _constant.computeType(mirrorSystem.compiler).element);

-  }

-

-  int get hashCode => 13 * _constant.hashCode;

-

-  bool operator ==(var other) {

-    if (other is! Dart2JsConstantMirror) return false;

-    return _constant == other._constant;

-  }

-}

-

-class Dart2JsNullConstantMirror extends Dart2JsConstantMirror {

-  Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                            NullConstant constant)

-      : super(mirrorSystem, constant);

-

-  NullConstant get _constant => super._constant;

-

-  bool get hasReflectee => true;

-

-  get reflectee => null;

-}

-

-class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror {

-  Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                            BoolConstant constant)

-      : super(mirrorSystem, constant);

-

-  Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrorSystem,

-                                     bool value)

-      : super(mirrorSystem, value ? new TrueConstant() : new FalseConstant());

-

-  BoolConstant get _constant => super._constant;

-

-  bool get hasReflectee => true;

-

-  get reflectee => _constant is TrueConstant;

-}

-

-class Dart2JsStringConstantMirror extends Dart2JsConstantMirror {

-  Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                              StringConstant constant)

-      : super(mirrorSystem, constant);

-

-  Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrorSystem,

-                                         String text)

-      : super(mirrorSystem, new StringConstant(new DartString.literal(text)));

-

-  StringConstant get _constant => super._constant;

-

-  bool get hasReflectee => true;

-

-  get reflectee => _constant.value.slowToString();

-}

-

-class Dart2JsNumConstantMirror extends Dart2JsConstantMirror {

-  Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                           NumConstant constant)

-      : super(mirrorSystem, constant);

-

-  NumConstant get _constant => super._constant;

-

-  bool get hasReflectee => true;

-

-  get reflectee => _constant.value;

-}

-

-class Dart2JsListConstantMirror extends Dart2JsConstantMirror

-    implements ListInstanceMirror {

-  Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                            ListConstant constant)

-      : super(mirrorSystem, constant);

-

-  ListConstant get _constant => super._constant;

-

-  int get length => _constant.length;

-

-  InstanceMirror getElement(int index) {

-    if (index < 0) throw new RangeError('Negative index');

-    if (index >= _constant.length) throw new RangeError('Index out of bounds');

-    return _convertConstantToInstanceMirror(mirrorSystem,

-                                            _constant.entries[index]);

-  }

-}

-

-class Dart2JsMapConstantMirror extends Dart2JsConstantMirror

-    implements MapInstanceMirror {

-  List<String> _listCache;

-

-  Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                           MapConstant constant)

-      : super(mirrorSystem, constant);

-

-  MapConstant get _constant => super._constant;

-

-  List<String> get _list {

-    if (_listCache == null) {

-      _listCache = new List<String>(_constant.keys.entries.length);

-      int index = 0;

-      for (StringConstant keyConstant in _constant.keys.entries) {

-        _listCache[index] = keyConstant.value.slowToString();

-        index++;

-      }

-      _listCache = new UnmodifiableListView<String>(_listCache);

-    }

-    return _listCache;

-  }

-

-  int get length => _constant.length;

-

-  Iterable<String> get keys {

-    return _list;

-  }

-

-  InstanceMirror getValue(String key) {

-    int index = _list.indexOf(key);

-    if (index == -1) return null;

-    return _convertConstantToInstanceMirror(mirrorSystem,

-                                            _constant.values[index]);

-  }

-}

-

-class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror

-    implements TypeInstanceMirror {

-

-  Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                            TypeConstant constant)

-      : super(mirrorSystem, constant);

-

-  TypeConstant get _constant => super._constant;

-

-  TypeMirror get representedType =>

-      mirrorSystem._convertTypeToTypeMirror(_constant.representedType);

-}

-

-class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror {

-  Map<String,Constant> _fieldMapCache;

-

-  Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrorSystem,

-                                   ConstructedConstant constant)

-      : super(mirrorSystem, constant);

-

-  ConstructedConstant get _constant => super._constant;

-

-  Map<String,Constant> get _fieldMap {

-    if (_fieldMapCache == null) {

-      _fieldMapCache = new Map<String,Constant>();

-      if (identical(_constant.type.element.kind, ElementKind.CLASS)) {

-        var index = 0;

-        ClassElement element = _constant.type.element;

-        element.forEachInstanceField((_, Element field) {

-          String fieldName = field.name;

-          _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]);

-          index++;

-        }, includeSuperAndInjectedMembers: true);

-      }

-    }

-    return _fieldMapCache;

-  }

-

-  InstanceMirror getField(Symbol fieldName) {

-    Constant fieldConstant = _fieldMap[MirrorSystem.getName(fieldName)];

-    if (fieldConstant != null) {

-      return _convertConstantToInstanceMirror(mirrorSystem, fieldConstant);

-    }

-    return super.getField(fieldName);

-  }

-}

-

-class Dart2JsCommentInstanceMirror extends Object

-  with ObjectMirrorMixin, InstanceMirrorMixin

-  implements CommentInstanceMirror {

-  final Dart2JsMirrorSystem mirrorSystem;

-  final String text;

-  String _trimmedText;

-

-  Dart2JsCommentInstanceMirror(this.mirrorSystem, this.text);

-

-  ClassMirror get type {

-    return mirrorSystem._getTypeDeclarationMirror(

-        mirrorSystem.compiler.documentClass);

-  }

-

-  bool get isDocComment => text.startsWith('/**') || text.startsWith('///');

-

-  String get trimmedText {

-    if (_trimmedText == null) {

-      _trimmedText = stripComment(text);

-    }

-    return _trimmedText;

-  }

-

-  InstanceMirror getField(Symbol fieldName) {

-    if (fieldName == #isDocComment) {

-      return new Dart2JsBoolConstantMirror.fromBool(mirrorSystem, isDocComment);

-    } else if (fieldName == #text) {

-      return new Dart2JsStringConstantMirror.fromString(mirrorSystem, text);

-    } else if (fieldName == #trimmedText) {

-      return new Dart2JsStringConstantMirror.fromString(mirrorSystem,

-                                                        trimmedText);

-    }

-    return super.getField(fieldName);

-  }

-}

+// 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 dart2js.mirrors;
+
+abstract class ObjectMirrorMixin implements ObjectMirror {
+  InstanceMirror getField(Symbol fieldName) {
+    throw new UnsupportedError('ObjectMirror.getField unsupported.');
+  }
+
+  InstanceMirror setField(Symbol fieldName, Object value) {
+    throw new UnsupportedError('ObjectMirror.setField unsupported.');
+  }
+
+  InstanceMirror invoke(Symbol memberName,
+                        List positionalArguments,
+                        [Map<Symbol, dynamic> namedArguments]) {
+    throw new UnsupportedError('ObjectMirror.invoke unsupported.');
+  }
+}
+
+abstract class InstanceMirrorMixin implements InstanceMirror {
+
+  bool get hasReflectee => false;
+
+  get reflectee {
+    throw new UnsupportedError('InstanceMirror.reflectee unsupported.');
+  }
+
+  Function operator [](Symbol name) {
+    throw new UnsupportedError('InstanceMirror.operator [] unsupported.');
+  }
+
+  delegate(Invocation invocation) {
+    throw new UnsupportedError('InstanceMirror.delegate unsupported');
+  }
+}
+
+InstanceMirror _convertConstantToInstanceMirror(
+    Dart2JsMirrorSystem mirrorSystem, Constant constant) {
+  if (constant is BoolConstant) {
+    return new Dart2JsBoolConstantMirror(mirrorSystem, constant);
+  } else if (constant is NumConstant) {
+    return new Dart2JsNumConstantMirror(mirrorSystem, constant);
+  } else if (constant is StringConstant) {
+    return new Dart2JsStringConstantMirror(mirrorSystem, constant);
+  } else if (constant is ListConstant) {
+    return new Dart2JsListConstantMirror(mirrorSystem, constant);
+  } else if (constant is MapConstant) {
+    return new Dart2JsMapConstantMirror(mirrorSystem, constant);
+  } else if (constant is TypeConstant) {
+    return new Dart2JsTypeConstantMirror(mirrorSystem, constant);
+  } else if (constant is FunctionConstant) {
+    return new Dart2JsConstantMirror(mirrorSystem, constant);
+  } else if (constant is NullConstant) {
+    return new Dart2JsNullConstantMirror(mirrorSystem, constant);
+  } else if (constant is ConstructedConstant) {
+    return new Dart2JsConstructedConstantMirror(mirrorSystem, constant);
+  }
+  mirrorSystem.compiler.internalError("Unexpected constant $constant");
+  return null;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Mirrors on constant values used for metadata.
+////////////////////////////////////////////////////////////////////////////////
+
+class Dart2JsConstantMirror extends Object
+    with ObjectMirrorMixin, InstanceMirrorMixin
+    implements InstanceMirror {
+  final Dart2JsMirrorSystem mirrorSystem;
+  final Constant _constant;
+
+  Dart2JsConstantMirror(this.mirrorSystem, this._constant);
+
+  // TODO(johnniwinther): Improve the quality of this method.
+  String toString() => '$_constant';
+
+  ClassMirror get type {
+    return mirrorSystem._getTypeDeclarationMirror(
+        _constant.computeType(mirrorSystem.compiler).element);
+  }
+
+  int get hashCode => 13 * _constant.hashCode;
+
+  bool operator ==(var other) {
+    if (other is! Dart2JsConstantMirror) return false;
+    return _constant == other._constant;
+  }
+}
+
+class Dart2JsNullConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                            NullConstant constant)
+      : super(mirrorSystem, constant);
+
+  NullConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => null;
+}
+
+class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                            BoolConstant constant)
+      : super(mirrorSystem, constant);
+
+  Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrorSystem,
+                                     bool value)
+      : super(mirrorSystem, value ? new TrueConstant() : new FalseConstant());
+
+  BoolConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant is TrueConstant;
+}
+
+class Dart2JsStringConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                              StringConstant constant)
+      : super(mirrorSystem, constant);
+
+  Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrorSystem,
+                                         String text)
+      : super(mirrorSystem, new StringConstant(new DartString.literal(text)));
+
+  StringConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant.value.slowToString();
+}
+
+class Dart2JsNumConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                           NumConstant constant)
+      : super(mirrorSystem, constant);
+
+  NumConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant.value;
+}
+
+class Dart2JsListConstantMirror extends Dart2JsConstantMirror
+    implements ListInstanceMirror {
+  Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                            ListConstant constant)
+      : super(mirrorSystem, constant);
+
+  ListConstant get _constant => super._constant;
+
+  int get length => _constant.length;
+
+  InstanceMirror getElement(int index) {
+    if (index < 0) throw new RangeError('Negative index');
+    if (index >= _constant.length) throw new RangeError('Index out of bounds');
+    return _convertConstantToInstanceMirror(mirrorSystem,
+                                            _constant.entries[index]);
+  }
+}
+
+class Dart2JsMapConstantMirror extends Dart2JsConstantMirror
+    implements MapInstanceMirror {
+  List<String> _listCache;
+
+  Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                           MapConstant constant)
+      : super(mirrorSystem, constant);
+
+  MapConstant get _constant => super._constant;
+
+  List<String> get _list {
+    if (_listCache == null) {
+      _listCache = new List<String>(_constant.keys.entries.length);
+      int index = 0;
+      for (StringConstant keyConstant in _constant.keys.entries) {
+        _listCache[index] = keyConstant.value.slowToString();
+        index++;
+      }
+      _listCache = new UnmodifiableListView<String>(_listCache);
+    }
+    return _listCache;
+  }
+
+  int get length => _constant.length;
+
+  Iterable<String> get keys {
+    return _list;
+  }
+
+  InstanceMirror getValue(String key) {
+    int index = _list.indexOf(key);
+    if (index == -1) return null;
+    return _convertConstantToInstanceMirror(mirrorSystem,
+                                            _constant.values[index]);
+  }
+}
+
+class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror
+    implements TypeInstanceMirror {
+
+  Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                            TypeConstant constant)
+      : super(mirrorSystem, constant);
+
+  TypeConstant get _constant => super._constant;
+
+  TypeMirror get representedType =>
+      mirrorSystem._convertTypeToTypeMirror(_constant.representedType);
+}
+
+class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror {
+  Map<String,Constant> _fieldMapCache;
+
+  Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrorSystem,
+                                   ConstructedConstant constant)
+      : super(mirrorSystem, constant);
+
+  ConstructedConstant get _constant => super._constant;
+
+  Map<String,Constant> get _fieldMap {
+    if (_fieldMapCache == null) {
+      _fieldMapCache = new Map<String,Constant>();
+      if (identical(_constant.type.element.kind, ElementKind.CLASS)) {
+        var index = 0;
+        ClassElement element = _constant.type.element;
+        element.forEachInstanceField((_, Element field) {
+          String fieldName = field.name;
+          _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]);
+          index++;
+        }, includeSuperAndInjectedMembers: true);
+      }
+    }
+    return _fieldMapCache;
+  }
+
+  InstanceMirror getField(Symbol fieldName) {
+    Constant fieldConstant = _fieldMap[MirrorSystem.getName(fieldName)];
+    if (fieldConstant != null) {
+      return _convertConstantToInstanceMirror(mirrorSystem, fieldConstant);
+    }
+    return super.getField(fieldName);
+  }
+}
+
+class Dart2JsCommentInstanceMirror extends Object
+  with ObjectMirrorMixin, InstanceMirrorMixin
+  implements CommentInstanceMirror {
+  final Dart2JsMirrorSystem mirrorSystem;
+  final String text;
+  String _trimmedText;
+
+  Dart2JsCommentInstanceMirror(this.mirrorSystem, this.text);
+
+  ClassMirror get type {
+    return mirrorSystem._getTypeDeclarationMirror(
+        mirrorSystem.compiler.documentClass);
+  }
+
+  bool get isDocComment => text.startsWith('/**') || text.startsWith('///');
+
+  String get trimmedText {
+    if (_trimmedText == null) {
+      _trimmedText = stripComment(text);
+    }
+    return _trimmedText;
+  }
+
+  InstanceMirror getField(Symbol fieldName) {
+    if (fieldName == #isDocComment) {
+      return new Dart2JsBoolConstantMirror.fromBool(mirrorSystem, isDocComment);
+    } else if (fieldName == #text) {
+      return new Dart2JsStringConstantMirror.fromString(mirrorSystem, text);
+    } else if (fieldName == #trimmedText) {
+      return new Dart2JsStringConstantMirror.fromString(mirrorSystem,
+                                                        trimmedText);
+    }
+    return super.getField(fieldName);
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_library_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_library_mirror.dart
index 9a5e58d..ee87e74 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_library_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_library_mirror.dart
@@ -1,234 +1,234 @@
-// 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 dart2js.mirrors;

-

-

-class Dart2JsLibraryMirror

-    extends Dart2JsElementMirror

-    with ObjectMirrorMixin, ContainerMixin

-    implements LibrarySourceMirror {

-  List<LibraryDependencyMirror> _libraryDependencies;

-

-  Dart2JsLibraryMirror(Dart2JsMirrorSystem system, LibraryElement library)

-      : super(system, library);

-

-  Function operator [](Symbol name) {

-    throw new UnsupportedError('LibraryMirror.operator [] unsupported.');

-  }

-

-  LibraryElement get _element => super._element;

-

-  Uri get uri => _element.canonicalUri;

-

-  DeclarationMirror get owner => null;

-

-  bool get isPrivate => false;

-

-  LibraryMirror library() => this;

-

-  /**

-   * Returns the library name (for libraries with a library tag) or the script

-   * file name (for scripts without a library tag). The latter case is used to

-   * provide a 'library name' for scripts, to use for instance in dartdoc.

-   */

-  String get _simpleNameString {

-    if (_element.libraryTag != null) {

-      return _element.libraryTag.name.toString();

-    } else {

-      // Use the file name as script name.

-      String path = _element.canonicalUri.path;

-      return path.substring(path.lastIndexOf('/') + 1);

-    }

-  }

-

-  Symbol get qualifiedName => simpleName;

-

-  void _forEachElement(f(Element element)) => _element.forEachLocalMember(f);

-

-  Iterable<Dart2JsDeclarationMirror> _getDeclarationMirrors(Element element) {

-    if (element.isClass() || element.isTypedef()) {

-      return [mirrorSystem._getTypeDeclarationMirror(element)];

-    } else {

-      return super._getDeclarationMirrors(element);

-    }

-  }

-

-  Map<Symbol, MethodMirror> get topLevelMembers => null;

-

-  /**

-   * Computes the first token of this library using the first library tag as

-   * indicator.

-   */

-  Token getBeginToken() {

-    if (_element.libraryTag != null) {

-      return _element.libraryTag.getBeginToken();

-    } else if (!_element.tags.isEmpty) {

-      return _element.tags.reverse().head.getBeginToken();

-    }

-    return null;

-  }

-

-  /**

-   * Computes the first token of this library using the last library tag as

-   * indicator.

-   */

-  Token getEndToken() {

-    if (!_element.tags.isEmpty) {

-      return _element.tags.head.getEndToken();

-    }

-    return null;

-  }

-

-  void _ensureLibraryDependenciesAnalyzed() {

-    if (_libraryDependencies == null) {

-      _libraryDependencies = <LibraryDependencyMirror>[];

-      for (LibraryTag node in _element.tags.reverse()) {

-        LibraryDependency libraryDependency = node.asLibraryDependency();

-        if (libraryDependency != null) {

-          LibraryElement targetLibraryElement =

-              _element.getLibraryFromTag(libraryDependency);

-          assert(targetLibraryElement != null);

-          LibraryMirror targetLibrary =

-              mirrorSystem._getLibrary(targetLibraryElement);

-          _libraryDependencies.add(new Dart2JsLibraryDependencyMirror(

-              libraryDependency, this, targetLibrary));

-        }

-      }

-    }

-  }

-

-  List<LibraryDependencyMirror> get libraryDependencies {

-    _ensureLibraryDependenciesAnalyzed();

-    return _libraryDependencies;

-  }

-}

-

-class Dart2JsLibraryDependencyMirror implements LibraryDependencyMirror {

-  final LibraryDependency _node;

-  final Dart2JsLibraryMirror _sourceLibrary;

-  final Dart2JsLibraryMirror _targetLibrary;

-  List<CombinatorMirror> _combinators;

-

-  Dart2JsLibraryDependencyMirror(this._node,

-                                 this._sourceLibrary,

-                                 this._targetLibrary);

-

-  SourceLocation get location {

-    return new Dart2JsSourceLocation(

-      _sourceLibrary._element.entryCompilationUnit.script,

-      _sourceLibrary.mirrorSystem.compiler.spanFromNode(_node));

-  }

-

-  List<CombinatorMirror> get combinators {

-    if (_combinators == null) {

-      _combinators = <CombinatorMirror>[];

-      if (_node.combinators != null) {

-        for (Combinator combinator in _node.combinators.nodes) {

-          List<String> identifiers = <String>[];

-          for (Identifier identifier in combinator.identifiers.nodes) {

-            identifiers.add(identifier.source);

-          }

-          _combinators.add(new Dart2JsCombinatorMirror(

-              identifiers, isShow: combinator.isShow));

-        }

-      }

-    }

-    return _combinators;

-  }

-

-  LibraryMirror get sourceLibrary => _sourceLibrary;

-

-  LibraryMirror get targetLibrary => _targetLibrary;

-

-  String get prefix {

-    Import import = _node.asImport();

-    if (import != null && import.prefix != null) {

-      return import.prefix.source;

-    }

-    return null;

-  }

-

-  bool get isImport => _node.asImport() != null;

-

-  bool get isExport => _node.asExport() != null;

-}

-

-class Dart2JsCombinatorMirror implements CombinatorMirror {

-  final List<String> identifiers;

-  final bool isShow;

-

-  Dart2JsCombinatorMirror(this.identifiers, {bool isShow: true})

-      : this.isShow = isShow;

-

-  bool get isHide => !isShow;

-}

-

-class Dart2JsSourceLocation implements SourceLocation {

-  final Script _script;

-  final SourceSpan _span;

-  int _line;

-  int _column;

-

-  Dart2JsSourceLocation(this._script, this._span);

-

-  int _computeLine() {

-    var sourceFile = _script.file;

-    if (sourceFile != null) {

-      return sourceFile.getLine(offset) + 1;

-    }

-    var index = 0;

-    var lineNumber = 0;

-    while (index <= offset && index < sourceText.length) {

-      index = sourceText.indexOf('\n', index) + 1;

-      if (index <= 0) break;

-      lineNumber++;

-    }

-    return lineNumber;

-  }

-

-  int get line {

-    if (_line == null) {

-      _line = _computeLine();

-    }

-    return _line;

-  }

-

-  int _computeColumn() {

-    if (length == 0) return 0;

-

-    var sourceFile = _script.file;

-    if (sourceFile != null) {

-      return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;

-    }

-    int index = offset - 1;

-    var columnNumber = 0;

-    while (0 <= index && index < sourceText.length) {

-      columnNumber++;

-      var codeUnit = sourceText.codeUnitAt(index);

-      if (codeUnit == $CR || codeUnit == $LF) {

-        break;

-      }

-      index--;

-    }

-    return columnNumber;

-  }

-

-  int get column {

-    if (_column == null) {

-      _column = _computeColumn();

-    }

-    return _column;

-  }

-

-  int get offset => _span.begin;

-

-  int get length => _span.end - _span.begin;

-

-  String get text => _script.text.substring(_span.begin, _span.end);

-

-  Uri get sourceUri => _script.uri;

-

-  String get sourceText => _script.text;

-}

+// 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 dart2js.mirrors;
+
+
+class Dart2JsLibraryMirror
+    extends Dart2JsElementMirror
+    with ObjectMirrorMixin, ContainerMixin
+    implements LibrarySourceMirror {
+  List<LibraryDependencyMirror> _libraryDependencies;
+
+  Dart2JsLibraryMirror(Dart2JsMirrorSystem system, LibraryElement library)
+      : super(system, library);
+
+  Function operator [](Symbol name) {
+    throw new UnsupportedError('LibraryMirror.operator [] unsupported.');
+  }
+
+  LibraryElement get _element => super._element;
+
+  Uri get uri => _element.canonicalUri;
+
+  DeclarationMirror get owner => null;
+
+  bool get isPrivate => false;
+
+  LibraryMirror library() => this;
+
+  /**
+   * Returns the library name (for libraries with a library tag) or the script
+   * file name (for scripts without a library tag). The latter case is used to
+   * provide a 'library name' for scripts, to use for instance in dartdoc.
+   */
+  String get _simpleNameString {
+    if (_element.libraryTag != null) {
+      return _element.libraryTag.name.toString();
+    } else {
+      // Use the file name as script name.
+      String path = _element.canonicalUri.path;
+      return path.substring(path.lastIndexOf('/') + 1);
+    }
+  }
+
+  Symbol get qualifiedName => simpleName;
+
+  void _forEachElement(f(Element element)) => _element.forEachLocalMember(f);
+
+  Iterable<Dart2JsDeclarationMirror> _getDeclarationMirrors(Element element) {
+    if (element.isClass() || element.isTypedef()) {
+      return [mirrorSystem._getTypeDeclarationMirror(element)];
+    } else {
+      return super._getDeclarationMirrors(element);
+    }
+  }
+
+  Map<Symbol, MethodMirror> get topLevelMembers => null;
+
+  /**
+   * Computes the first token of this library using the first library tag as
+   * indicator.
+   */
+  Token getBeginToken() {
+    if (_element.libraryTag != null) {
+      return _element.libraryTag.getBeginToken();
+    } else if (!_element.tags.isEmpty) {
+      return _element.tags.reverse().head.getBeginToken();
+    }
+    return null;
+  }
+
+  /**
+   * Computes the first token of this library using the last library tag as
+   * indicator.
+   */
+  Token getEndToken() {
+    if (!_element.tags.isEmpty) {
+      return _element.tags.head.getEndToken();
+    }
+    return null;
+  }
+
+  void _ensureLibraryDependenciesAnalyzed() {
+    if (_libraryDependencies == null) {
+      _libraryDependencies = <LibraryDependencyMirror>[];
+      for (LibraryTag node in _element.tags.reverse()) {
+        LibraryDependency libraryDependency = node.asLibraryDependency();
+        if (libraryDependency != null) {
+          LibraryElement targetLibraryElement =
+              _element.getLibraryFromTag(libraryDependency);
+          assert(targetLibraryElement != null);
+          LibraryMirror targetLibrary =
+              mirrorSystem._getLibrary(targetLibraryElement);
+          _libraryDependencies.add(new Dart2JsLibraryDependencyMirror(
+              libraryDependency, this, targetLibrary));
+        }
+      }
+    }
+  }
+
+  List<LibraryDependencyMirror> get libraryDependencies {
+    _ensureLibraryDependenciesAnalyzed();
+    return _libraryDependencies;
+  }
+}
+
+class Dart2JsLibraryDependencyMirror implements LibraryDependencyMirror {
+  final LibraryDependency _node;
+  final Dart2JsLibraryMirror _sourceLibrary;
+  final Dart2JsLibraryMirror _targetLibrary;
+  List<CombinatorMirror> _combinators;
+
+  Dart2JsLibraryDependencyMirror(this._node,
+                                 this._sourceLibrary,
+                                 this._targetLibrary);
+
+  SourceLocation get location {
+    return new Dart2JsSourceLocation(
+      _sourceLibrary._element.entryCompilationUnit.script,
+      _sourceLibrary.mirrorSystem.compiler.spanFromNode(_node));
+  }
+
+  List<CombinatorMirror> get combinators {
+    if (_combinators == null) {
+      _combinators = <CombinatorMirror>[];
+      if (_node.combinators != null) {
+        for (Combinator combinator in _node.combinators.nodes) {
+          List<String> identifiers = <String>[];
+          for (Identifier identifier in combinator.identifiers.nodes) {
+            identifiers.add(identifier.source);
+          }
+          _combinators.add(new Dart2JsCombinatorMirror(
+              identifiers, isShow: combinator.isShow));
+        }
+      }
+    }
+    return _combinators;
+  }
+
+  LibraryMirror get sourceLibrary => _sourceLibrary;
+
+  LibraryMirror get targetLibrary => _targetLibrary;
+
+  String get prefix {
+    Import import = _node.asImport();
+    if (import != null && import.prefix != null) {
+      return import.prefix.source;
+    }
+    return null;
+  }
+
+  bool get isImport => _node.asImport() != null;
+
+  bool get isExport => _node.asExport() != null;
+}
+
+class Dart2JsCombinatorMirror implements CombinatorMirror {
+  final List<String> identifiers;
+  final bool isShow;
+
+  Dart2JsCombinatorMirror(this.identifiers, {bool isShow: true})
+      : this.isShow = isShow;
+
+  bool get isHide => !isShow;
+}
+
+class Dart2JsSourceLocation implements SourceLocation {
+  final Script _script;
+  final SourceSpan _span;
+  int _line;
+  int _column;
+
+  Dart2JsSourceLocation(this._script, this._span);
+
+  int _computeLine() {
+    var sourceFile = _script.file;
+    if (sourceFile != null) {
+      return sourceFile.getLine(offset) + 1;
+    }
+    var index = 0;
+    var lineNumber = 0;
+    while (index <= offset && index < sourceText.length) {
+      index = sourceText.indexOf('\n', index) + 1;
+      if (index <= 0) break;
+      lineNumber++;
+    }
+    return lineNumber;
+  }
+
+  int get line {
+    if (_line == null) {
+      _line = _computeLine();
+    }
+    return _line;
+  }
+
+  int _computeColumn() {
+    if (length == 0) return 0;
+
+    var sourceFile = _script.file;
+    if (sourceFile != null) {
+      return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;
+    }
+    int index = offset - 1;
+    var columnNumber = 0;
+    while (0 <= index && index < sourceText.length) {
+      columnNumber++;
+      var codeUnit = sourceText.codeUnitAt(index);
+      if (codeUnit == $CR || codeUnit == $LF) {
+        break;
+      }
+      index--;
+    }
+    return columnNumber;
+  }
+
+  int get column {
+    if (_column == null) {
+      _column = _computeColumn();
+    }
+    return _column;
+  }
+
+  int get offset => _span.begin;
+
+  int get length => _span.end - _span.begin;
+
+  String get text => _script.text.substring(_span.begin, _span.end);
+
+  Uri get sourceUri => _script.uri;
+
+  String get sourceText => _script.text;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_member_mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_member_mirrors.dart
index 0a22d4d..ec0b945 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_member_mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_member_mirrors.dart
@@ -1,288 +1,276 @@
-// 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 dart2js.mirrors;

-

-//------------------------------------------------------------------------------

-// Member mirrors implementation.

-//------------------------------------------------------------------------------

-

-abstract class Dart2JsMemberMirror extends Dart2JsElementMirror {

-

-  Dart2JsMemberMirror(Dart2JsMirrorSystem system, Element element)

-      : super(system, element);

-

-  bool get isStatic => false;

-}

-

-

-class Dart2JsMethodKind {

-  static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular");

-  static const Dart2JsMethodKind GENERATIVE =

-      const Dart2JsMethodKind("generative");

-  static const Dart2JsMethodKind REDIRECTING =

-      const Dart2JsMethodKind("redirecting");

-  static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const");

-  static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory");

-  static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter");

-  static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter");

-  static const Dart2JsMethodKind OPERATOR = const Dart2JsMethodKind("operator");

-

-  final String text;

-

-  const Dart2JsMethodKind(this.text);

-

-  String toString() => text;

-}

-

-

-String _getOperatorFromOperatorName(String name) {

-  Map<String, String> mapping = const {

-    'eq': '==',

-    'not': '~',

-    'index': '[]',

-    'indexSet': '[]=',

-    'mul': '*',

-    'div': '/',

-    'mod': '%',

-    'tdiv': '~/',

-    'add': '+',

-    'sub': '-',

-    'shl': '<<',

-    'shr': '>>',

-    'ge': '>=',

-    'gt': '>',

-    'le': '<=',

-    'lt': '<',

-    'and': '&',

-    'xor': '^',

-    'or': '|',

-  };

-  String newName = mapping[name];

-  if (newName == null) {

-    throw new Exception('Unhandled operator name: $name');

-  }

-  return newName;

-}

-

-class Dart2JsMethodMirror extends Dart2JsMemberMirror

-    implements MethodMirror {

-  final Dart2JsDeclarationMirror owner;

-  final String _simpleNameString;

-  final Dart2JsMethodKind _kind;

-

-  Dart2JsMethodMirror._internal(Dart2JsDeclarationMirror owner,

-      FunctionElement function,

-      String this._simpleNameString,

-      Dart2JsMethodKind this._kind)

-      : this.owner = owner,

-        super(owner.mirrorSystem, function);

-

-  factory Dart2JsMethodMirror(Dart2JsDeclarationMirror owner,

-                              FunctionElement function) {

-    String realName = function.name;

-    // TODO(ahe): This method should not be calling

-    // Elements.operatorNameToIdentifier.

-    String simpleName =

-        Elements.operatorNameToIdentifier(function.name);

-    Dart2JsMethodKind kind;

-    if (function.kind == ElementKind.GETTER) {

-      kind = Dart2JsMethodKind.GETTER;

-    } else if (function.kind == ElementKind.SETTER) {

-      kind = Dart2JsMethodKind.SETTER;

-      simpleName = '$simpleName=';

-    } else if (function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {

-      // TODO(johnniwinther): Support detection of redirecting constructors.

-      if (function.modifiers.isConst()) {

-        kind = Dart2JsMethodKind.CONST;

-      } else {

-        kind = Dart2JsMethodKind.GENERATIVE;

-      }

-    } else if (function.modifiers.isFactory()) {

-      // TODO(johnniwinther): Support detection of redirecting constructors.

-      kind = Dart2JsMethodKind.FACTORY;

-    } else if (realName == 'unary-') {

-      // TODO(johnniwinther): Use a constant for 'unary-'.

-      kind = Dart2JsMethodKind.OPERATOR;

-      // Simple name is 'unary-'.

-      simpleName = 'unary-';

-    } else if (simpleName.startsWith('operator\$')) {

-      String str = simpleName.substring(9);

-      simpleName = 'operator';

-      kind = Dart2JsMethodKind.OPERATOR;

-      simpleName = _getOperatorFromOperatorName(str);

-    } else {

-      kind = Dart2JsMethodKind.REGULAR;

-    }

-    return new Dart2JsMethodMirror._internal(owner, function,

-        simpleName, kind);

-  }

-

-  FunctionElement get _function => _element;

-

-  bool get isTopLevel => owner is LibraryMirror;

-

-  // TODO(johnniwinther): This seems stale and broken.

-  Symbol get constructorName => isConstructor ? simpleName : const Symbol('');

-

-  bool get isConstructor

-      => isGenerativeConstructor || isConstConstructor ||

-         isFactoryConstructor || isRedirectingConstructor;

-

-  bool get isSynthetic => false;

-

-  bool get isStatic => _function.modifiers.isStatic();

-

-  List<ParameterMirror> get parameters {

-    return _parametersFromFunctionSignature(this,

-        _function.computeSignature(mirrorSystem.compiler));

-  }

-

-  TypeMirror get returnType => owner._getTypeMirror(

-      _function.computeSignature(mirrorSystem.compiler).returnType);

-

-  bool get isAbstract => _function.isAbstract;

-

-  bool get isRegularMethod => !(isGetter || isSetter || isConstructor);

-

-  bool get isConstConstructor => _kind == Dart2JsMethodKind.CONST;

-

-  bool get isGenerativeConstructor => _kind == Dart2JsMethodKind.GENERATIVE;

-

-  bool get isRedirectingConstructor => _kind == Dart2JsMethodKind.REDIRECTING;

-

-  bool get isFactoryConstructor => _kind == Dart2JsMethodKind.FACTORY;

-

-  bool get isGetter => _kind == Dart2JsMethodKind.GETTER;

-

-  bool get isSetter => _kind == Dart2JsMethodKind.SETTER;

-

-  bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR;

-

-  DeclarationMirror lookupInScope(String name) {

-    for (Dart2JsParameterMirror parameter in parameters) {

-      if (parameter._element.name == name) {

-        return parameter;

-      }

-    }

-    return super.lookupInScope(name);

-  }

-

-  // TODO(johnniwinther): Should this really be in the interface of

-  // [MethodMirror]?

-  String get source => location.sourceText;

-

-  String toString() => 'Mirror on method ${_element.name}';

-}

-

-class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror {

-  final Dart2JsDeclarationMirror owner;

-  VariableElement _variable;

-

-  Dart2JsFieldMirror(Dart2JsDeclarationMirror owner,

-                     VariableElement variable)

-      : this.owner = owner,

-        this._variable = variable,

-        super(owner.mirrorSystem, variable);

-

-  Element get _beginElement => _variable.variables;

-

-  bool get isTopLevel => owner is LibraryMirror;

-

-  bool get isStatic => _variable.modifiers.isStatic();

-

-  bool get isFinal => _variable.modifiers.isFinal();

-

-  bool get isConst => _variable.modifiers.isConst();

-

-  TypeMirror get type =>

-      owner._getTypeMirror(_variable.computeType(mirrorSystem.compiler));

-}

-

-class Dart2JsParameterMirror extends Dart2JsMemberMirror

-    implements ParameterMirror {

-  final Dart2JsDeclarationMirror owner;

-  final bool isOptional;

-  final bool isNamed;

-

-  factory Dart2JsParameterMirror(Dart2JsDeclarationMirror owner,

-                                 VariableElement element,

-                                 {bool isOptional: false,

-                                  bool isNamed: false}) {

-    if (element is FieldParameterElement) {

-      return new Dart2JsFieldParameterMirror(

-          owner, element, isOptional, isNamed);

-    }

-    return new Dart2JsParameterMirror._normal(

-        owner, element, isOptional, isNamed);

-  }

-

-  Dart2JsParameterMirror._normal(Dart2JsDeclarationMirror owner,

-                                 VariableElement element,

-                                 this.isOptional,

-                                 this.isNamed)

-    : this.owner = owner,

-      super(owner.mirrorSystem, element);

-

-  Element get _beginElement => _variableElement.variables;

-

-  VariableElement get _variableElement => _element;

-

-  TypeMirror get type => owner._getTypeMirror(

-      _variableElement.computeType(mirrorSystem.compiler),

-      _variableElement.variables.functionSignature);

-

-

-  bool get isFinal => false;

-

-  bool get isConst => false;

-

-  InstanceMirror get defaultValue {

-    if (hasDefaultValue) {

-      Constant constant = mirrorSystem.compiler.constantHandler

-          .getConstantForVariable(_variableElement);

-      assert(invariant(_variableElement, constant != null,

-          message: "Missing constant for parameter "

-                   "$_variableElement with default value."));

-      return _convertConstantToInstanceMirror(mirrorSystem, constant);

-    }

-    return null;

-  }

-

-  bool get hasDefaultValue {

-    return _variableElement.cachedNode.asSendSet() != null;

-  }

-

-  bool get isInitializingFormal => false;

-

-  VariableMirror get initializedField => null;

-}

-

-class Dart2JsFieldParameterMirror extends Dart2JsParameterMirror {

-

-  Dart2JsFieldParameterMirror(Dart2JsDeclarationMirror method,

-                              FieldParameterElement element,

-                              bool isOptional,

-                              bool isNamed)

-      : super._normal(method, element, isOptional, isNamed);

-

-  FieldParameterElement get _fieldParameterElement => _element;

-

-  TypeMirror get type {

-    VariableListElement variables = _fieldParameterElement.variables;

-    VariableDefinitions node = variables.parseNode(mirrorSystem.compiler);

-    if (node.type != null) {

-      return super.type;

-    }

-    // Use the field type for initializing formals with no type annotation.

-    return owner._getTypeMirror(

-      _fieldParameterElement.fieldElement.computeType(mirrorSystem.compiler),

-      _fieldParameterElement.fieldElement.variables.functionSignature);

-  }

-

-  bool get isInitializingFormal => true;

-

-  VariableMirror get initializedField => new Dart2JsFieldMirror(

-      owner.owner, _fieldParameterElement.fieldElement);

-}

+// 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 dart2js.mirrors;
+
+//------------------------------------------------------------------------------
+// Member mirrors implementation.
+//------------------------------------------------------------------------------
+
+abstract class Dart2JsMemberMirror extends Dart2JsElementMirror {
+
+  Dart2JsMemberMirror(Dart2JsMirrorSystem system, Element element)
+      : super(system, element);
+
+  bool get isStatic => false;
+}
+
+
+class Dart2JsMethodKind {
+  static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular");
+  static const Dart2JsMethodKind GENERATIVE =
+      const Dart2JsMethodKind("generative");
+  static const Dart2JsMethodKind REDIRECTING =
+      const Dart2JsMethodKind("redirecting");
+  static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const");
+  static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory");
+  static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter");
+  static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter");
+  static const Dart2JsMethodKind OPERATOR = const Dart2JsMethodKind("operator");
+
+  final String text;
+
+  const Dart2JsMethodKind(this.text);
+
+  String toString() => text;
+}
+
+
+String _getOperatorFromOperatorName(String name) {
+  Map<String, String> mapping = const {
+    'eq': '==',
+    'not': '~',
+    'index': '[]',
+    'indexSet': '[]=',
+    'mul': '*',
+    'div': '/',
+    'mod': '%',
+    'tdiv': '~/',
+    'add': '+',
+    'sub': '-',
+    'shl': '<<',
+    'shr': '>>',
+    'ge': '>=',
+    'gt': '>',
+    'le': '<=',
+    'lt': '<',
+    'and': '&',
+    'xor': '^',
+    'or': '|',
+  };
+  String newName = mapping[name];
+  if (newName == null) {
+    throw new Exception('Unhandled operator name: $name');
+  }
+  return newName;
+}
+
+class Dart2JsMethodMirror extends Dart2JsMemberMirror
+    implements MethodMirror {
+  final Dart2JsDeclarationMirror owner;
+  final String _simpleNameString;
+  final Dart2JsMethodKind _kind;
+
+  Dart2JsMethodMirror._internal(Dart2JsDeclarationMirror owner,
+      FunctionElement function,
+      String this._simpleNameString,
+      Dart2JsMethodKind this._kind)
+      : this.owner = owner,
+        super(owner.mirrorSystem, function);
+
+  factory Dart2JsMethodMirror(Dart2JsDeclarationMirror owner,
+                              FunctionElement function) {
+    String realName = function.name;
+    // TODO(ahe): This method should not be calling
+    // Elements.operatorNameToIdentifier.
+    String simpleName =
+        Elements.operatorNameToIdentifier(function.name);
+    Dart2JsMethodKind kind;
+    if (function.kind == ElementKind.GETTER) {
+      kind = Dart2JsMethodKind.GETTER;
+    } else if (function.kind == ElementKind.SETTER) {
+      kind = Dart2JsMethodKind.SETTER;
+      simpleName = '$simpleName=';
+    } else if (function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+      // TODO(johnniwinther): Support detection of redirecting constructors.
+      if (function.modifiers.isConst()) {
+        kind = Dart2JsMethodKind.CONST;
+      } else {
+        kind = Dart2JsMethodKind.GENERATIVE;
+      }
+    } else if (function.modifiers.isFactory()) {
+      // TODO(johnniwinther): Support detection of redirecting constructors.
+      kind = Dart2JsMethodKind.FACTORY;
+    } else if (realName == 'unary-') {
+      // TODO(johnniwinther): Use a constant for 'unary-'.
+      kind = Dart2JsMethodKind.OPERATOR;
+      // Simple name is 'unary-'.
+      simpleName = 'unary-';
+    } else if (simpleName.startsWith('operator\$')) {
+      String str = simpleName.substring(9);
+      simpleName = 'operator';
+      kind = Dart2JsMethodKind.OPERATOR;
+      simpleName = _getOperatorFromOperatorName(str);
+    } else {
+      kind = Dart2JsMethodKind.REGULAR;
+    }
+    return new Dart2JsMethodMirror._internal(owner, function,
+        simpleName, kind);
+  }
+
+  FunctionElement get _function => _element;
+
+  bool get isTopLevel => owner is LibraryMirror;
+
+  // TODO(johnniwinther): This seems stale and broken.
+  Symbol get constructorName => isConstructor ? simpleName : const Symbol('');
+
+  bool get isConstructor
+      => isGenerativeConstructor || isConstConstructor ||
+         isFactoryConstructor || isRedirectingConstructor;
+
+  bool get isSynthetic => false;
+
+  bool get isStatic => _function.modifiers.isStatic();
+
+  List<ParameterMirror> get parameters {
+    return _parametersFromFunctionSignature(this,
+        _function.computeSignature(mirrorSystem.compiler));
+  }
+
+  TypeMirror get returnType => owner._getTypeMirror(
+      _function.computeSignature(mirrorSystem.compiler).returnType);
+
+  bool get isAbstract => _function.isAbstract;
+
+  bool get isRegularMethod => !(isGetter || isSetter || isConstructor);
+
+  bool get isConstConstructor => _kind == Dart2JsMethodKind.CONST;
+
+  bool get isGenerativeConstructor => _kind == Dart2JsMethodKind.GENERATIVE;
+
+  bool get isRedirectingConstructor => _kind == Dart2JsMethodKind.REDIRECTING;
+
+  bool get isFactoryConstructor => _kind == Dart2JsMethodKind.FACTORY;
+
+  bool get isGetter => _kind == Dart2JsMethodKind.GETTER;
+
+  bool get isSetter => _kind == Dart2JsMethodKind.SETTER;
+
+  bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR;
+
+  DeclarationMirror lookupInScope(String name) {
+    for (Dart2JsParameterMirror parameter in parameters) {
+      if (parameter._element.name == name) {
+        return parameter;
+      }
+    }
+    return super.lookupInScope(name);
+  }
+
+  // TODO(johnniwinther): Should this really be in the interface of
+  // [MethodMirror]?
+  String get source => location.sourceText;
+
+  String toString() => 'Mirror on method ${_element.name}';
+}
+
+class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror {
+  final Dart2JsDeclarationMirror owner;
+  VariableElement _variable;
+
+  Dart2JsFieldMirror(Dart2JsDeclarationMirror owner,
+                     VariableElement variable)
+      : this.owner = owner,
+        this._variable = variable,
+        super(owner.mirrorSystem, variable);
+
+  Element get _beginElement => _variable.variables;
+
+  bool get isTopLevel => owner is LibraryMirror;
+
+  bool get isStatic => _variable.modifiers.isStatic();
+
+  bool get isFinal => _variable.modifiers.isFinal();
+
+  bool get isConst => _variable.modifiers.isConst();
+
+  TypeMirror get type =>
+      owner._getTypeMirror(_variable.computeType(mirrorSystem.compiler));
+}
+
+class Dart2JsParameterMirror extends Dart2JsMemberMirror
+    implements ParameterMirror {
+  final Dart2JsDeclarationMirror owner;
+  final bool isOptional;
+  final bool isNamed;
+
+  factory Dart2JsParameterMirror(Dart2JsDeclarationMirror owner,
+                                 VariableElement element,
+                                 {bool isOptional: false,
+                                  bool isNamed: false}) {
+    if (element is FieldParameterElement) {
+      return new Dart2JsFieldParameterMirror(
+          owner, element, isOptional, isNamed);
+    }
+    return new Dart2JsParameterMirror._normal(
+        owner, element, isOptional, isNamed);
+  }
+
+  Dart2JsParameterMirror._normal(Dart2JsDeclarationMirror owner,
+                                 VariableElement element,
+                                 this.isOptional,
+                                 this.isNamed)
+    : this.owner = owner,
+      super(owner.mirrorSystem, element);
+
+  Element get _beginElement => _variableElement.variables;
+
+  VariableElement get _variableElement => _element;
+
+  TypeMirror get type => owner._getTypeMirror(
+      _variableElement.computeType(mirrorSystem.compiler),
+      _variableElement.variables.functionSignature);
+
+
+  bool get isFinal => false;
+
+  bool get isConst => false;
+
+  InstanceMirror get defaultValue {
+    if (hasDefaultValue) {
+      Constant constant = mirrorSystem.compiler.constantHandler
+          .getConstantForVariable(_variableElement);
+      assert(invariant(_variableElement, constant != null,
+          message: "Missing constant for parameter "
+                   "$_variableElement with default value."));
+      return _convertConstantToInstanceMirror(mirrorSystem, constant);
+    }
+    return null;
+  }
+
+  bool get hasDefaultValue {
+    return _variableElement.cachedNode.asSendSet() != null;
+  }
+
+  bool get isInitializingFormal => false;
+
+  VariableMirror get initializedField => null;
+}
+
+class Dart2JsFieldParameterMirror extends Dart2JsParameterMirror {
+
+  Dart2JsFieldParameterMirror(Dart2JsDeclarationMirror method,
+                              FieldParameterElement element,
+                              bool isOptional,
+                              bool isNamed)
+      : super._normal(method, element, isOptional, isNamed);
+
+  FieldParameterElement get _fieldParameterElement => _element;
+
+  bool get isInitializingFormal => true;
+
+  VariableMirror get initializedField => new Dart2JsFieldMirror(
+      owner.owner, _fieldParameterElement.fieldElement);
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
index 3f5bfdd..3dffd96 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
@@ -1,480 +1,483 @@
-// 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 dart2js.mirrors;

-

-//------------------------------------------------------------------------------

-// Types

-//------------------------------------------------------------------------------

-

-abstract class ClassMirrorMixin implements ClassSourceMirror {

-  bool get hasReflectedType => false;

-  Type get reflectedType {

-    throw new UnsupportedError("ClassMirror.reflectedType is not supported.");

-  }

-  InstanceMirror newInstance(Symbol constructorName,

-                             List positionalArguments,

-                             [Map<Symbol, dynamic> namedArguments]) {

-    throw new UnsupportedError("ClassMirror.newInstance is not supported.");

-  }

-}

-

-abstract class Dart2JsTypeMirror

-    extends Dart2JsElementMirror

-    implements TypeSourceMirror {

-  final DartType _type;

-

-  Dart2JsTypeMirror(Dart2JsMirrorSystem system, DartType type)

-    : super(system, type.element),

-      this._type = type;

-

-  String get _simpleNameString => _type.name;

-

-  Dart2JsDeclarationMirror get owner => library;

-

-  Dart2JsLibraryMirror get library {

-    return mirrorSystem._getLibrary(_type.element.getLibrary());

-  }

-

-  bool get isOriginalDeclaration => true;

-

-  TypeMirror get originalDeclaration => this;

-

-  List<TypeMirror> get typeArguments => const <TypeMirror>[];

-

-  List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];

-

-  TypeMirror createInstantiation(List<TypeMirror> typeArguments) {

-    if (typeArguments.isEmpty) return this;

-    throw new ArgumentError('Cannot create generic instantiation of $_type.');

-  }

-

-  bool get isVoid => false;

-

-  bool get isDynamic => false;

-

-  bool isSubtypeOf(TypeMirror other) {

-    return mirrorSystem.compiler.types.isSubtype(this._type, other._type);

-  }

-

-  bool isAssignableTo(TypeMirror other) {

-    return mirrorSystem.compiler.types.isAssignable(this._type, other._type);

-  }

-

-  String toString() => _type.toString();

-}

-

-abstract class DeclarationMixin implements TypeMirror {

-

-  bool get isOriginalDeclaration => true;

-

-  TypeMirror get originalDeclaration => this;

-

-  List<TypeMirror> get typeArguments => const <TypeMirror>[];

-}

-

-abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeMirror {

-  List<TypeMirror> _typeArguments;

-  List<TypeVariableMirror> _typeVariables;

-

-  Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type)

-      : super(system, type);

-

-  TypeDeclarationElement get _element => super._element;

-

-  GenericType get _type => super._type;

-

-  bool get isOriginalDeclaration => false;

-

-  TypeMirror get originalDeclaration =>

-      mirrorSystem._getTypeDeclarationMirror(_element);

-

-  List<TypeMirror> get typeArguments {

-    if (_typeArguments == null) {

-      _typeArguments = <TypeMirror>[];

-      if (!_type.isRaw) {

-        Link<DartType> type = _type.typeArguments;

-        while (type != null && type.head != null) {

-          _typeArguments.add(_getTypeMirror(type.head));

-          type = type.tail;

-        }

-      }

-    }

-    return _typeArguments;

-  }

-

-  List<TypeVariableMirror> get typeVariables {

-    if (_typeVariables == null) {

-      _typeVariables = <TypeVariableMirror>[];

-      for (TypeVariableType typeVariable in _element.typeVariables) {

-        _typeVariables.add(

-            new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable));

-      }

-    }

-    return _typeVariables;

-  }

-

-  Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {

-    if (element.isTypeVariable()) {

-      assert(invariant(_element, _element == element.enclosingElement,

-          message: 'Foreigned type variable element $element.'));

-      for (Dart2JsTypeVariableMirror mirror in typeVariables) {

-        if (mirror._element == element) return [mirror];

-      }

-    }

-    return super._getDeclarationMirrors(element);

-  }

-

-  TypeMirror _getTypeMirror(DartType type, [FunctionSignature signature]) {

-    return super._getTypeMirror(

-        type.subst(_type.typeArguments, _type.element.typeVariables),

-        signature);

-  }

-

-  TypeSourceMirror createInstantiation(

-      List<TypeSourceMirror> newTypeArguments) {

-    if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw());

-    if (newTypeArguments.length != typeVariables.length) {

-      throw new ArgumentError('Cannot create generic instantiation of $_type '

-                              'with ${newTypeArguments.length} arguments, '

-                              'expect ${typeVariables.length} arguments.');

-    }

-    LinkBuilder<DartType> builder = new LinkBuilder<DartType>();

-    for (TypeSourceMirror newTypeArgument in newTypeArguments) {

-      if (newTypeArgument.isVoid) {

-        throw new ArgumentError('Cannot use void as type argument.');

-      }

-      if (newTypeArgument is Dart2JsTypeMirror) {

-        builder.addLast(newTypeArgument._type);

-      } else {

-        throw new UnsupportedError(

-            'Cannot create instantiation using a type '

-            'mirror from a different mirrorSystem implementation.');

-      }

-    }

-    return owner._getTypeMirror(_type.createInstantiation(builder.toLink()));

-  }

-}

-

-class Dart2JsInterfaceTypeMirror

-    extends Dart2JsGenericTypeMirror

-    with ObjectMirrorMixin, InstanceMirrorMixin, ClassMirrorMixin,

-         ContainerMixin

-    implements ClassMirror {

-  Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system,

-                             InterfaceType interfaceType)

-      : super(system, interfaceType);

-

-  ClassElement get _element => super._element;

-

-  InterfaceType get _type => super._type;

-

-  bool get isNameSynthetic  {

-    if (_element.isMixinApplication) {

-      MixinApplicationElement mixinApplication = _element;

-      return mixinApplication.isUnnamedMixinApplication;

-    }

-    return false;

-  }

-

-  void _forEachElement(f(Element element)) {

-    _element.forEachMember((_, element) => f(element));

-  }

-

-  ClassMirror get superclass {

-    if (_element.supertype != null) {

-      return _getTypeMirror(_element.supertype);

-    }

-    return null;

-  }

-

-  ClassMirror get mixin {

-    if (_element.isMixinApplication) {

-      MixinApplicationElement mixinApplication = _element;

-      return _getTypeMirror(mixinApplication.mixinType);

-    }

-    return this;

-  }

-

-  List<ClassMirror> get superinterfaces {

-    var list = <ClassMirror>[];

-    Link<DartType> link = _element.interfaces;

-    while (!link.isEmpty) {

-      var type = _getTypeMirror(link.head);

-      list.add(type);

-      link = link.tail;

-    }

-    return list;

-  }

-

-  Map<Symbol, MethodMirror> get instanceMembers => null;

-  Map<Symbol, MethodMirror> get staticMembers => null;

-

-  bool get isAbstract => _element.modifiers.isAbstract();

-

-  bool operator ==(other) {

-    if (identical(this, other)) {

-      return true;

-    }

-    if (other is! ClassMirror) {

-      return false;

-    }

-    return _type == other._type;

-  }

-

-  String toString() => 'Mirror on interface type $_type';

-}

-

-class Dart2JsClassDeclarationMirror

-    extends Dart2JsInterfaceTypeMirror

-    with DeclarationMixin {

-

-  Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system,

-                                InterfaceType type)

-      : super(system, type);

-

-  bool isSubclassOf(ClassMirror other) {

-    if (other is! ClassMirror) throw new ArgumentError(other);

-    ClassMirror otherDeclaration = other.originalDeclaration;

-    ClassMirror c = this;

-    while (c != null) {

-      c = c.originalDeclaration;

-      if (c == otherDeclaration) return true;

-      c = c.superclass;

-    }

-    return false;

-  }

-

-  String toString() => 'Mirror on class ${_type.name}';

-}

-

-class Dart2JsTypedefMirror

-    extends Dart2JsGenericTypeMirror

-    implements TypedefMirror {

-  final Dart2JsLibraryMirror _library;

-  List<TypeVariableMirror> _typeVariables;

-  var _definition;

-

-  Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef)

-      : this._library = system._getLibrary(_typedef.element.getLibrary()),

-        super(system, _typedef);

-

-  Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library,

-                                   TypedefType _typedef)

-      : this._library = library,

-        super(library.mirrorSystem, _typedef);

-

-  TypedefType get _typedef => _type;

-

-  LibraryMirror get library => _library;

-

-  bool get isTypedef => true;

-

-  FunctionTypeMirror get referent {

-    if (_definition == null) {

-      _definition = _getTypeMirror(

-          _typedef.element.alias,

-          _typedef.element.functionSignature);

-    }

-    return _definition;

-  }

-

-  bool get isClass => false;

-

-  bool get isAbstract => false;

-

-  String toString() => 'Mirror on typedef $_type';

-}

-

-class Dart2JsTypedefDeclarationMirror

-    extends Dart2JsTypedefMirror

-    with DeclarationMixin {

-  Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system,

-                                  TypedefType type)

-      : super(system, type);

-

-  String toString() => 'Mirror on typedef ${_type.name}';

-}

-

-class Dart2JsTypeVariableMirror extends Dart2JsTypeMirror

-    implements TypeVariableMirror {

-  Dart2JsDeclarationMirror _owner;

-

-  Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system,

-                            TypeVariableType typeVariableType)

-    : super(system, typeVariableType);

-

-  TypeVariableType get _type => super._type;

-

-  Dart2JsDeclarationMirror get owner {

-    if (_owner == null) {

-      _owner = mirrorSystem._getTypeDeclarationMirror(

-          _type.element.enclosingElement);

-    }

-    return _owner;

-  }

-

-  TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound);

-

-  bool operator ==(var other) {

-    if (identical(this, other)) {

-      return true;

-    }

-    if (other is! TypeVariableMirror) {

-      return false;

-    }

-    if (owner != other.owner) {

-      return false;

-    }

-    return qualifiedName == other.qualifiedName;

-  }

-

-  String toString() => 'Mirror on type variable $_type';

-}

-

-class Dart2JsFunctionTypeMirror extends Dart2JsTypeMirror

-    with ObjectMirrorMixin, InstanceMirrorMixin,

-         ClassMirrorMixin, DeclarationMixin

-    implements FunctionTypeMirror {

-  final FunctionSignature _functionSignature;

-  List<ParameterMirror> _parameters;

-

-  Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system,

-                            FunctionType functionType, this._functionSignature)

-      : super(system, functionType) {

-    assert (_functionSignature != null);

-  }

-

-  FunctionType get _type => super._type;

-

-  // TODO(johnniwinther): Is this the qualified name of a function type?

-  Symbol get qualifiedName => originalDeclaration.qualifiedName;

-

-  // TODO(johnniwinther): Substitute type arguments for type variables.

-  Map<Symbol, DeclarationMirror> get declarations {

-    var method = callMethod;

-    if (method != null) {

-      var map = new Map<Symbol, DeclarationMirror>.from(

-          originalDeclaration.declarations);

-      var name = method.qualifiedName;

-      assert(!map.containsKey(name));

-      map[name] = method;

-      return new ImmutableMapWrapper<Symbol, DeclarationMirror>(map);

-    }

-    return originalDeclaration.declarations;

-  }

-

-  bool get isFunction => true;

-

-  MethodMirror get callMethod => _convertElementMethodToMethodMirror(

-      mirrorSystem._getLibrary(_type.element.getLibrary()),

-      _type.element);

-

-  ClassMirror get originalDeclaration =>

-      mirrorSystem._getTypeDeclarationMirror(

-          mirrorSystem.compiler.functionClass);

-

-  // TODO(johnniwinther): Substitute type arguments for type variables.

-  ClassMirror get superclass => originalDeclaration.superclass;

-

-  // TODO(johnniwinther): Substitute type arguments for type variables.

-  List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;

-

-  Map<Symbol, MethodMirror> get instanceMembers => null;

-  Map<Symbol, MethodMirror> get staticMembers => null;

-

-  ClassMirror get mixin => this;

-

-  bool get isPrivate => false;

-

-  bool get isAbstract => false;

-

-  List<TypeVariableMirror> get typeVariables =>

-      originalDeclaration.typeVariables;

-

-  TypeMirror get returnType => owner._getTypeMirror(_type.returnType);

-

-  List<ParameterMirror> get parameters {

-    if (_parameters == null) {

-      _parameters = _parametersFromFunctionSignature(owner,

-                                                     _functionSignature);

-    }

-    return _parameters;

-  }

-

-  String toString() => 'Mirror on function type $_type';

-}

-

-class Dart2JsVoidMirror extends Dart2JsTypeMirror {

-

-  Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType)

-      : super(system, voidType);

-

-  VoidType get _voidType => _type;

-

-  Symbol get qualifiedName => simpleName;

-

-  /**

-   * The void type has no location.

-   */

-  SourceLocation get location => null;

-

-  /**

-   * The void type has no library.

-   */

-  LibraryMirror get library => null;

-

-  List<InstanceMirror> get metadata => const <InstanceMirror>[];

-

-  bool get isVoid => true;

-

-  bool operator ==(other) {

-    if (identical(this, other)) {

-      return true;

-    }

-    if (other is! TypeMirror) {

-      return false;

-    }

-    return other.isVoid;

-  }

-

-  int get hashCode => 13 * _element.hashCode;

-

-  String toString() => 'Mirror on void';

-}

-

-class Dart2JsDynamicMirror extends Dart2JsTypeMirror {

-  Dart2JsDynamicMirror(Dart2JsMirrorSystem system, InterfaceType voidType)

-      : super(system, voidType);

-

-  InterfaceType get _dynamicType => _type;

-

-  Symbol get qualifiedName => simpleName;

-

-  /**

-   * The dynamic type has no location.

-   */

-  SourceLocation get location => null;

-

-  /**

-   * The dynamic type has no library.

-   */

-  LibraryMirror get library => null;

-

-  bool get isDynamic => true;

-

-  bool operator ==(other) {

-    if (identical(this, other)) {

-      return true;

-    }

-    if (other is! TypeMirror) {

-      return false;

-    }

-    return other.isDynamic;

-  }

-

-  int get hashCode => 13 * _element.hashCode;

-

-  String toString() => 'Mirror on dynamic';

-}

+// 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 dart2js.mirrors;
+
+abstract class ClassMirrorMixin implements ClassSourceMirror {
+  bool get hasReflectedType => false;
+  Type get reflectedType {
+    throw new UnsupportedError("ClassMirror.reflectedType is not supported.");
+  }
+  InstanceMirror newInstance(Symbol constructorName,
+                             List positionalArguments,
+                             [Map<Symbol, dynamic> namedArguments]) {
+    throw new UnsupportedError("ClassMirror.newInstance is not supported.");
+  }
+}
+
+abstract class Dart2JsTypeMirror
+    extends Dart2JsElementMirror
+    implements TypeSourceMirror {
+  final DartType _type;
+
+  Dart2JsTypeMirror(Dart2JsMirrorSystem system, DartType type)
+    : super(system, type.element),
+      this._type = type;
+
+  String get _simpleNameString => _type.name;
+
+  Dart2JsDeclarationMirror get owner => library;
+
+  Dart2JsLibraryMirror get library {
+    return mirrorSystem._getLibrary(_type.element.getLibrary());
+  }
+
+  bool get isOriginalDeclaration => true;
+
+  TypeMirror get originalDeclaration => this;
+
+  List<TypeMirror> get typeArguments => const <TypeMirror>[];
+
+  List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
+
+  TypeMirror createInstantiation(List<TypeMirror> typeArguments) {
+    if (typeArguments.isEmpty) return this;
+    throw new ArgumentError('Cannot create generic instantiation of $_type.');
+  }
+
+  bool get isVoid => false;
+
+  bool get isDynamic => false;
+
+  bool isSubtypeOf(TypeMirror other) {
+    if (other is Dart2JsTypeMirror) {
+      return mirrorSystem.compiler.types.isSubtype(this._type, other._type);
+    } else {
+      throw new ArgumentError(other);
+    }
+  }
+
+  bool isAssignableTo(TypeMirror other) {
+    if (other is Dart2JsTypeMirror) {
+      return mirrorSystem.compiler.types.isAssignable(this._type, other._type);
+    } else {
+      throw new ArgumentError(other);
+    }
+  }
+
+  String toString() => _type.toString();
+}
+
+abstract class DeclarationMixin implements TypeMirror {
+
+  bool get isOriginalDeclaration => true;
+
+  TypeMirror get originalDeclaration => this;
+
+  List<TypeMirror> get typeArguments => const <TypeMirror>[];
+}
+
+abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeMirror {
+  List<TypeMirror> _typeArguments;
+  List<TypeVariableMirror> _typeVariables;
+
+  Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type)
+      : super(system, type);
+
+  TypeDeclarationElement get _element => super._element;
+
+  GenericType get _type => super._type;
+
+  bool get isOriginalDeclaration => false;
+
+  TypeMirror get originalDeclaration =>
+      mirrorSystem._getTypeDeclarationMirror(_element);
+
+  List<TypeMirror> get typeArguments {
+    if (_typeArguments == null) {
+      _typeArguments = <TypeMirror>[];
+      if (!_type.isRaw) {
+        Link<DartType> type = _type.typeArguments;
+        while (type != null && type.head != null) {
+          _typeArguments.add(_getTypeMirror(type.head));
+          type = type.tail;
+        }
+      }
+    }
+    return _typeArguments;
+  }
+
+  List<TypeVariableMirror> get typeVariables {
+    if (_typeVariables == null) {
+      _typeVariables = <TypeVariableMirror>[];
+      for (TypeVariableType typeVariable in _element.typeVariables) {
+        _typeVariables.add(
+            new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable));
+      }
+    }
+    return _typeVariables;
+  }
+
+  Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {
+    if (element.isTypeVariable()) {
+      assert(invariant(_element, _element == element.enclosingElement,
+          message: 'Foreigned type variable element $element.'));
+      for (Dart2JsTypeVariableMirror mirror in typeVariables) {
+        if (mirror._element == element) return [mirror];
+      }
+    }
+    return super._getDeclarationMirrors(element);
+  }
+
+  TypeMirror _getTypeMirror(DartType type, [FunctionSignature signature]) {
+    return super._getTypeMirror(
+        type.subst(_type.typeArguments, _type.element.typeVariables),
+        signature);
+  }
+
+  TypeSourceMirror createInstantiation(
+      List<TypeSourceMirror> newTypeArguments) {
+    if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw());
+    if (newTypeArguments.length != typeVariables.length) {
+      throw new ArgumentError('Cannot create generic instantiation of $_type '
+                              'with ${newTypeArguments.length} arguments, '
+                              'expect ${typeVariables.length} arguments.');
+    }
+    LinkBuilder<DartType> builder = new LinkBuilder<DartType>();
+    for (TypeSourceMirror newTypeArgument in newTypeArguments) {
+      if (newTypeArgument.isVoid) {
+        throw new ArgumentError('Cannot use void as type argument.');
+      }
+      if (newTypeArgument is Dart2JsTypeMirror) {
+        builder.addLast(newTypeArgument._type);
+      } else {
+        throw new UnsupportedError(
+            'Cannot create instantiation using a type '
+            'mirror from a different mirrorSystem implementation.');
+      }
+    }
+    return owner._getTypeMirror(_type.createInstantiation(builder.toLink()));
+  }
+}
+
+class Dart2JsInterfaceTypeMirror
+    extends Dart2JsGenericTypeMirror
+    with ObjectMirrorMixin, InstanceMirrorMixin, ClassMirrorMixin,
+         ContainerMixin
+    implements ClassMirror {
+  Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system,
+                             InterfaceType interfaceType)
+      : super(system, interfaceType);
+
+  ClassElement get _element => super._element;
+
+  InterfaceType get _type => super._type;
+
+  bool get isNameSynthetic  {
+    if (_element.isMixinApplication) {
+      MixinApplicationElement mixinApplication = _element;
+      return mixinApplication.isUnnamedMixinApplication;
+    }
+    return false;
+  }
+
+  void _forEachElement(f(Element element)) {
+    _element.forEachMember((_, element) => f(element));
+  }
+
+  ClassMirror get superclass {
+    if (_element.supertype != null) {
+      return _getTypeMirror(_element.supertype);
+    }
+    return null;
+  }
+
+  ClassMirror get mixin {
+    if (_element.isMixinApplication) {
+      MixinApplicationElement mixinApplication = _element;
+      return _getTypeMirror(mixinApplication.mixinType);
+    }
+    return this;
+  }
+
+  List<ClassMirror> get superinterfaces {
+    var list = <ClassMirror>[];
+    Link<DartType> link = _element.interfaces;
+    while (!link.isEmpty) {
+      var type = _getTypeMirror(link.head);
+      list.add(type);
+      link = link.tail;
+    }
+    return list;
+  }
+
+  Map<Symbol, MethodMirror> get instanceMembers => null;
+  Map<Symbol, MethodMirror> get staticMembers => null;
+
+  bool get isAbstract => _element.modifiers.isAbstract();
+
+  bool operator ==(other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! ClassMirror) {
+      return false;
+    }
+    return _type == other._type;
+  }
+
+  String toString() => 'Mirror on interface type $_type';
+}
+
+class Dart2JsClassDeclarationMirror
+    extends Dart2JsInterfaceTypeMirror
+    with DeclarationMixin {
+
+  Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system,
+                                InterfaceType type)
+      : super(system, type);
+
+  bool isSubclassOf(ClassMirror other) {
+    if (other is Dart2JsFunctionTypeMirror) {
+      return false;
+    } else if (other is Dart2JsClassDeclarationMirror) {
+      Dart2JsClassDeclarationMirror otherDeclaration =
+          other.originalDeclaration;
+      return _element.isSubclassOf(otherDeclaration._element);
+    }
+    throw new ArgumentError(other);
+  }
+
+  String toString() => 'Mirror on class ${_type.name}';
+}
+
+class Dart2JsTypedefMirror
+    extends Dart2JsGenericTypeMirror
+    implements TypedefMirror {
+  final Dart2JsLibraryMirror _library;
+  List<TypeVariableMirror> _typeVariables;
+  var _definition;
+
+  Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef)
+      : this._library = system._getLibrary(_typedef.element.getLibrary()),
+        super(system, _typedef);
+
+  Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library,
+                                   TypedefType _typedef)
+      : this._library = library,
+        super(library.mirrorSystem, _typedef);
+
+  TypedefType get _typedef => _type;
+
+  LibraryMirror get library => _library;
+
+  bool get isTypedef => true;
+
+  FunctionTypeMirror get referent {
+    if (_definition == null) {
+      _definition = _getTypeMirror(
+          _typedef.element.alias,
+          _typedef.element.functionSignature);
+    }
+    return _definition;
+  }
+
+  bool get isClass => false;
+
+  bool get isAbstract => false;
+
+  String toString() => 'Mirror on typedef $_type';
+}
+
+class Dart2JsTypedefDeclarationMirror
+    extends Dart2JsTypedefMirror
+    with DeclarationMixin {
+  Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system,
+                                  TypedefType type)
+      : super(system, type);
+
+  String toString() => 'Mirror on typedef ${_type.name}';
+}
+
+class Dart2JsTypeVariableMirror extends Dart2JsTypeMirror
+    implements TypeVariableMirror {
+  Dart2JsDeclarationMirror _owner;
+
+  Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system,
+                            TypeVariableType typeVariableType)
+    : super(system, typeVariableType);
+
+  TypeVariableType get _type => super._type;
+
+  Dart2JsDeclarationMirror get owner {
+    if (_owner == null) {
+      _owner = mirrorSystem._getTypeDeclarationMirror(
+          _type.element.enclosingElement);
+    }
+    return _owner;
+  }
+
+  TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound);
+
+  bool operator ==(var other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! TypeVariableMirror) {
+      return false;
+    }
+    if (owner != other.owner) {
+      return false;
+    }
+    return qualifiedName == other.qualifiedName;
+  }
+
+  String toString() => 'Mirror on type variable $_type';
+}
+
+class Dart2JsFunctionTypeMirror extends Dart2JsTypeMirror
+    with ObjectMirrorMixin, InstanceMirrorMixin,
+         ClassMirrorMixin, DeclarationMixin
+    implements FunctionTypeMirror {
+  final FunctionSignature _functionSignature;
+  List<ParameterMirror> _parameters;
+
+  Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system,
+                            FunctionType functionType, this._functionSignature)
+      : super(system, functionType) {
+    assert (_functionSignature != null);
+  }
+
+  FunctionType get _type => super._type;
+
+  // TODO(johnniwinther): Is this the qualified name of a function type?
+  Symbol get qualifiedName => originalDeclaration.qualifiedName;
+
+  // TODO(johnniwinther): Substitute type arguments for type variables.
+  Map<Symbol, DeclarationMirror> get declarations {
+    var method = callMethod;
+    if (method != null) {
+      var map = new Map<Symbol, DeclarationMirror>.from(
+          originalDeclaration.declarations);
+      var name = method.qualifiedName;
+      assert(!map.containsKey(name));
+      map[name] = method;
+      return new ImmutableMapWrapper<Symbol, DeclarationMirror>(map);
+    }
+    return originalDeclaration.declarations;
+  }
+
+  bool get isFunction => true;
+
+  MethodMirror get callMethod => _convertElementMethodToMethodMirror(
+      mirrorSystem._getLibrary(_type.element.getLibrary()),
+      _type.element);
+
+  ClassMirror get originalDeclaration =>
+      mirrorSystem._getTypeDeclarationMirror(
+          mirrorSystem.compiler.functionClass);
+
+  // TODO(johnniwinther): Substitute type arguments for type variables.
+  ClassMirror get superclass => originalDeclaration.superclass;
+
+  // TODO(johnniwinther): Substitute type arguments for type variables.
+  List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;
+
+  Map<Symbol, MethodMirror> get instanceMembers => null;
+  Map<Symbol, MethodMirror> get staticMembers => null;
+
+  ClassMirror get mixin => this;
+
+  bool get isPrivate => false;
+
+  bool get isAbstract => false;
+
+  List<TypeVariableMirror> get typeVariables =>
+      originalDeclaration.typeVariables;
+
+  TypeMirror get returnType => owner._getTypeMirror(_type.returnType);
+
+  List<ParameterMirror> get parameters {
+    if (_parameters == null) {
+      _parameters = _parametersFromFunctionSignature(owner,
+                                                     _functionSignature);
+    }
+    return _parameters;
+  }
+
+  String toString() => 'Mirror on function type $_type';
+}
+
+class Dart2JsVoidMirror extends Dart2JsTypeMirror {
+
+  Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType)
+      : super(system, voidType);
+
+  VoidType get _voidType => _type;
+
+  Symbol get qualifiedName => simpleName;
+
+  /**
+   * The void type has no location.
+   */
+  SourceLocation get location => null;
+
+  /**
+   * The void type has no library.
+   */
+  LibraryMirror get library => null;
+
+  List<InstanceMirror> get metadata => const <InstanceMirror>[];
+
+  bool get isVoid => true;
+
+  bool operator ==(other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! TypeMirror) {
+      return false;
+    }
+    return other.isVoid;
+  }
+
+  int get hashCode => 13 * _element.hashCode;
+
+  String toString() => 'Mirror on void';
+}
+
+class Dart2JsDynamicMirror extends Dart2JsTypeMirror {
+  Dart2JsDynamicMirror(Dart2JsMirrorSystem system, InterfaceType voidType)
+      : super(system, voidType);
+
+  InterfaceType get _dynamicType => _type;
+
+  Symbol get qualifiedName => simpleName;
+
+  /**
+   * The dynamic type has no location.
+   */
+  SourceLocation get location => null;
+
+  /**
+   * The dynamic type has no library.
+   */
+  LibraryMirror get library => null;
+
+  bool get isDynamic => true;
+
+  bool operator ==(other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! TypeMirror) {
+      return false;
+    }
+    return other.isDynamic;
+  }
+
+  int get hashCode => 13 * _element.hashCode;
+
+  String toString() => 'Mirror on dynamic';
+}
diff --git a/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart b/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart
index d7b62de..c21996e 100644
--- a/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart
+++ b/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart
@@ -139,7 +139,7 @@
       DartType existingType = link.head;
       if (existingType == type) return;
       if (existingType.element == type.element) {
-        compiler.reportError(cls,
+        compiler.reportInternalError(cls,
             MessageKind.MULTI_INHERITANCE,
             {'thisType': cls.computeType(compiler),
              'firstType': existingType,
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/class_members.dart b/sdk/lib/_internal/compiler/implementation/resolution/class_members.dart
index c8c9c00..4aa640d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/class_members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/class_members.dart
@@ -35,7 +35,10 @@
   Map<dynamic/* Member | Element */, Set<MessageKind>> reportedMessages =
       new Map<dynamic, Set<MessageKind>>();
 
-  MembersCreator(Compiler this.compiler, ClassElement this.cls);
+  MembersCreator(Compiler this.compiler, ClassElement this.cls) {
+    assert(invariant(cls, cls.isDeclaration,
+        message: "Members may only be computed on declarations."));
+  }
 
   void reportMessage(var marker, MessageKind kind, report()) {
     Set<MessageKind> messages =
@@ -128,7 +131,7 @@
       LibraryElement library = cls.getLibrary();
       InterfaceType thisType = cls.thisType;
 
-      cls.forEachLocalMember((Element element) {
+      void createMember(Element element) {
         if (element.isConstructor()) return;
 
         Name name = new Name(element.name, library);
@@ -168,7 +171,16 @@
           declaredMembers[name] = new DeclaredMember(
               name, element, thisType, type, type);
         }
-      });
+      };
+
+      cls.forEachLocalMember(createMember);
+      if (cls.isPatched) {
+        cls.implementation.forEachLocalMember((Element element) {
+          if (element.isDeclaration) {
+            createMember(element);
+          }
+        });
+      }
     }
 
     declaredMembers.values.forEach((Member member) {
@@ -221,9 +233,9 @@
               () => new Set<Member>()).add(inherited);
         }
         if (someAreGetters && !allAreGetters) {
-          compiler.reportWarningCode(cls,
-                                     MessageKind.INHERIT_GETTER_AND_METHOD,
-                                     {'class': thisType, 'name': name.text });
+          compiler.reportWarning(cls,
+                                 MessageKind.INHERIT_GETTER_AND_METHOD,
+                                 {'class': thisType, 'name': name.text });
           for (Member inherited in inheritedMembers) {
             MessageKind kind;
             if (inherited.isMethod) {
@@ -357,7 +369,7 @@
         }
         reportMessage(
             interfaceMember.element, MessageKind.ABSTRACT_METHOD, () {
-          compiler.reportWarningCode(
+          compiler.reportWarning(
               interfaceMember.element, kind,
               {'class': cls.name, 'name': name.text});
         });
@@ -369,7 +381,7 @@
           Member inherited = interfaceMember.declarations.first;
           reportMessage(
               interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () {
-            compiler.reportWarningCode(cls,
+            compiler.reportWarning(cls,
                 interfaceMember.declarations.length == 1
                     ? singleKind : multipleKind,
                 {'class': cls.name,
@@ -418,7 +430,7 @@
           if (superMember != null && superMember.isStatic) {
             reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME,
                 () {
-              compiler.reportWarningCode(
+              compiler.reportWarning(
                   declared.element,
                   MessageKind.INSTANCE_STATIC_SAME_NAME,
                   {'memberName': declared.name,
@@ -479,7 +491,7 @@
                                MessageKind warningKind,
                                MessageKind infoKind) {
               reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () {
-                compiler.reportWarningCode(declared.element, warningKind,
+                compiler.reportWarning(declared.element, warningKind,
                     {'declaredType': declared.type,
                      'name': declared.name.text,
                      'class': cls.thisType,
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index f97438c..69e3b45 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -305,19 +305,19 @@
                                      Node node,
                                      FunctionElement constructor,
                                      FunctionElement redirection) {
+    assert(invariant(node, constructor.isImplementation,
+        message: 'Redirecting constructors must be resolved on implementation '
+                 'elements.'));
     Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
     seen.add(constructor);
     while (redirection != null) {
+      // Ensure that we follow redirections through implementation elements.
+      redirection = redirection.implementation;
       if (seen.contains(redirection)) {
         resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
         return;
       }
       seen.add(redirection);
-
-      if (redirection.isPatched) {
-        checkMatchingPatchSignatures(constructor, redirection.patch);
-        redirection = redirection.patch;
-      }
       redirection = resolver.visitor.resolveConstructorRedirection(redirection);
     }
   }
@@ -326,8 +326,8 @@
                                     Link<Element> originParameters,
                                     Link<Element> patchParameters) {
     while (!originParameters.isEmpty) {
-      VariableElementX originParameter = originParameters.head;
-      VariableElementX patchParameter = patchParameters.head;
+      ParameterElementX originParameter = originParameters.head;
+      ParameterElementX patchParameter = patchParameters.head;
       // TODO(johnniwinther): Remove the case for reassignment of
       // [patch]/[origin] when resolution is ensure to be done only once.
       assert(invariant(originParameter, originParameter.origin == null));
@@ -357,11 +357,9 @@
             {'methodName': origin.name,
              'originParameter': originParameterText,
              'patchParameter': patchParameterText});
-        compiler.reportMessage(
-            compiler.spanFromSpannable(patchParameter),
-            MessageKind.PATCH_POINT_TO_PARAMETER.error(
-                {'parameterName': patchParameter.name}),
-            Diagnostic.INFO);
+        compiler.reportInfo(patchParameter,
+            MessageKind.PATCH_POINT_TO_PARAMETER,
+            {'parameterName': patchParameter.name});
       }
       DartType originParameterType = originParameter.computeType(compiler);
       DartType patchParameterType = patchParameter.computeType(compiler);
@@ -373,11 +371,9 @@
              'parameterName': originParameter.name,
              'originParameterType': originParameterType,
              'patchParameterType': patchParameterType});
-        compiler.reportMessage(
-            compiler.spanFromSpannable(patchParameter),
-            MessageKind.PATCH_POINT_TO_PARAMETER.error(
-                {'parameterName': patchParameter.name}),
-            Diagnostic.INFO);
+        compiler.reportInfo(patchParameter,
+            MessageKind.PATCH_POINT_TO_PARAMETER,
+            {'parameterName': patchParameter.name});
       }
 
       originParameters = originParameters.tail;
@@ -1145,16 +1141,13 @@
           compiler.parser.measure(() => element.parseNode(compiler));
       return measure(() => SignatureResolver.analyze(
           compiler, node.parameters, node.returnType, element,
+          // TODO(johnniwinther): Use the [TreeElements] used for resolution of
+          // the method body.
+          new TreeElementMapping(element),
           defaultValuesError: defaultValuesError));
     });
   }
 
-  FunctionSignature resolveFunctionExpression(Element element,
-                                              FunctionExpression node) {
-    return measure(() => SignatureResolver.analyze(
-      compiler, node.parameters, node.returnType, element));
-  }
-
   TreeElements resolveTypedef(TypedefElementX element) {
     if (element.isResolved) return element.mapping;
     return _resolveTypeDeclaration(element, () {
@@ -1234,6 +1227,18 @@
     // TODO(ahe): Make non-fatal.
     compiler.reportFatalError(node, kind, arguments);
   }
+
+  resolveMetadata(MetadataContainer variables, VariableDefinitions node) {
+    LinkBuilder<MetadataAnnotation> metadata =
+        new LinkBuilder<MetadataAnnotation>();
+    for (Metadata annotation in node.metadata.nodes) {
+      ParameterMetadataAnnotation metadataAnnotation =
+          new ParameterMetadataAnnotation(annotation);
+      metadataAnnotation.annotatedElement = variables;
+      metadata.addLast(metadataAnnotation.ensureResolved(compiler));
+    }
+    variables.metadata = metadata.toLink();
+  }
 }
 
 class ConstantMapper extends Visitor {
@@ -1310,7 +1315,7 @@
     if (isFieldInitializer(init)) {
       target = constructor.getEnclosingClass().lookupLocalMember(name);
       if (target == null) {
-        error(selector, MessageKind.CANNOT_RESOLVE.error, {'name': name});
+        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
       } else if (target.kind != ElementKind.FIELD) {
         error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
       } else if (!target.isInstanceMember()) {
@@ -1543,10 +1548,8 @@
     compiler.reportFatalError(node, kind, arguments);
   }
 
-  void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
-    ResolutionWarning message =
-        new ResolutionWarning(kind, arguments, compiler.terseDiagnostics);
-    compiler.reportWarning(node, message);
+  void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) {
+    compiler.reportWarning(node, kind, arguments);
   }
 
   void cancel(Node node, String message) {
@@ -1704,17 +1707,17 @@
 
     Element element = resolveTypeName(visitor.scope, prefixName, typeName);
 
-    DartType reportFailureAndCreateType(DualKind messageKind,
+    DartType reportFailureAndCreateType(MessageKind messageKind,
                                         Map messageArguments,
                                         {DartType userProvidedBadType}) {
       if (malformedIsError) {
-        visitor.error(node, messageKind.error, messageArguments);
+        visitor.error(node, messageKind, messageArguments);
       } else {
         compiler.backend.registerThrowRuntimeError(visitor.mapping);
-        visitor.warning(node, messageKind.warning, messageArguments);
+        visitor.warning(node, messageKind, messageArguments);
       }
       Element erroneousElement = new ErroneousElementX(
-          messageKind.error, messageArguments, typeName.source,
+          messageKind, messageArguments, typeName.source,
           visitor.enclosingElement);
       LinkBuilder<DartType> arguments = new LinkBuilder<DartType>();
       resolveTypeArguments(visitor, node, null, arguments);
@@ -1834,7 +1837,7 @@
                                    DartType bound) {
       compiler.backend.registerTypeVariableBoundCheck(elements);
       if (!compiler.types.isSubtype(typeArgument, bound)) {
-        compiler.reportWarningCode(node,
+        compiler.reportWarning(node,
             MessageKind.INVALID_TYPE_VARIABLE_BOUND,
             {'typeVariable': typeVariable,
              'bound': bound,
@@ -1866,7 +1869,7 @@
          typeArguments = typeArguments.tail) {
       if (typeVariables != null && typeVariables.isEmpty) {
         visitor.warning(
-            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
         typeArgumentCountMismatch = true;
       }
       DartType argType = resolveTypeAnnotation(visitor, typeArguments.head);
@@ -1877,7 +1880,7 @@
     }
     if (typeVariables != null && !typeVariables.isEmpty) {
       visitor.warning(node.typeArguments,
-                      MessageKind.MISSING_TYPE_ARGUMENT.warning);
+                      MessageKind.MISSING_TYPE_ARGUMENT);
       typeArgumentCountMismatch = true;
     }
     return typeArgumentCountMismatch;
@@ -1929,13 +1932,10 @@
   void reportDuplicateDefinition(/*Node|String*/ name,
                                  Spannable definition,
                                  Spannable existing) {
-    compiler.reportError(
-        definition,
+    compiler.reportError(definition,
         MessageKind.DUPLICATE_DEFINITION, {'name': name});
-    compiler.reportMessage(
-        compiler.spanFromSpannable(existing),
-        MessageKind.EXISTING_DEFINITION.error({'name': name}),
-        Diagnostic.INFO);
+    compiler.reportInfo(existing,
+        MessageKind.EXISTING_DEFINITION, {'name': name});
   }
 }
 
@@ -2044,9 +2044,9 @@
       } else if (result.isAmbiguous()) {
         AmbiguousElement ambiguous = result;
         compiler.reportError(
-            node, ambiguous.messageKind.error, ambiguous.messageArguments);
+            node, ambiguous.messageKind, ambiguous.messageArguments);
         ambiguous.diagnose(enclosingElement, compiler);
-        return new ErroneousElementX(ambiguous.messageKind.error,
+        return new ErroneousElementX(ambiguous.messageKind,
                                      ambiguous.messageArguments,
                                      name, enclosingElement);
       }
@@ -2095,12 +2095,10 @@
 
   ErroneousElement warnAndCreateErroneousElement(Node node,
                                                  String name,
-                                                 DualKind kind,
+                                                 MessageKind kind,
                                                  [Map arguments = const {}]) {
-    ResolutionWarning warning = new ResolutionWarning(
-        kind.warning, arguments, compiler.terseDiagnostics);
-    compiler.reportWarning(node, warning);
-    return new ErroneousElementX(kind.error, arguments, name, enclosingElement);
+    compiler.reportWarning(node, kind, arguments);
+    return new ErroneousElementX(kind, arguments, name, enclosingElement);
   }
 
   Element visitIdentifier(Identifier node) {
@@ -2428,7 +2426,7 @@
         // TODO(karlklose): this should be reported by the caller of
         // [resolveSend] to select better warning messages for getters and
         // setters.
-        DualKind kind = (target == null)
+        MessageKind kind = (target == null)
             ? MessageKind.MEMBER_NOT_FOUND
             : MessageKind.MEMBER_NOT_STATIC;
         return warnAndCreateErroneousElement(node, name, kind,
@@ -2695,7 +2693,7 @@
     compiler.backend.registerThrowNoSuchMethod(mapping);
     // TODO(karlklose): we can be more precise about the reason of the
     // mismatch.
-    warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS.warning,
+    warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS,
             {'methodName': target.name});
   }
 
@@ -2855,8 +2853,9 @@
     world.registerStaticUse(compiler.symbolConstructor.declaration);
     world.registerConstSymbol(node.slowNameString, mapping);
     if (!validateSymbol(node, node.slowNameString, reportError: false)) {
-      compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
-                           {'value': node.slowNameString});
+      compiler.reportInternalError(node,
+          MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
+          {'value': node.slowNameString});
     }
     analyzeConstant(node);
   }
@@ -2936,7 +2935,7 @@
     FunctionType constructorType = constructor.computeType(compiler);
     bool isSubtype = compiler.types.isSubtype(targetType, constructorType);
     if (!isSubtype) {
-      warning(node, MessageKind.NOT_ASSIGNABLE.warning,
+      warning(node, MessageKind.NOT_ASSIGNABLE,
               {'fromType': targetType, 'toType': constructorType});
     }
 
@@ -2972,7 +2971,7 @@
     VariableDefinitionsVisitor visitor =
         new VariableDefinitionsVisitor(compiler, node, this,
                                        ElementKind.VARIABLE);
-    VariableListElement variables = visitor.variables;
+    VariableListElementX variables = visitor.variables;
     // Ensure that we set the type of the [VariableListElement] since it depends
     // on the current scope. If the current scope is a [MethodScope] or
     // [BlockScope] it will not be available for the
@@ -3013,15 +3012,7 @@
       }
     }
     if (node.metadata != null) {
-      // TODO(johnniwinther): Unify handling of metadata on locals/formals.
-      for (Link<Node> link = node.metadata.nodes;
-           !link.isEmpty;
-           link = link.tail) {
-        ParameterMetadataAnnotation metadata =
-            new ParameterMetadataAnnotation(link.head);
-        variables.addMetadata(metadata);
-        metadata.ensureResolved(compiler);
-      }
+      compiler.resolver.resolveMetadata(variables, node);
     }
     visitor.visit(node.definitions);
   }
@@ -3109,28 +3100,28 @@
 
   void analyzeConstant(Node node, {bool isConst: true}) {
     addDeferredAction(enclosingElement, () {
-       Constant constant = compiler.constantHandler.compileNodeWithDefinitions(
-           node, mapping, isConst: isConst);
+      Constant constant = compiler.constantHandler.compileNodeWithDefinitions(
+          node, mapping, isConst: isConst);
 
-       // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
-       // a class that will be instantiated outside the program by attaching a
-       // native class dispatch record referencing the interceptor.
-       if (argumentsToJsInterceptorConstant != null &&
-           argumentsToJsInterceptorConstant.contains(node)) {
-         if (constant.isType()) {
-           TypeConstant typeConstant = constant;
-           if (typeConstant.representedType is InterfaceType) {
-             world.registerInstantiatedType(typeConstant.representedType,
-                 mapping);
-           } else {
-             compiler.reportError(node,
-                 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
-           }
-         } else {
-           compiler.reportError(node,
-               MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
-         }
-       }
+      // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
+      // a class that will be instantiated outside the program by attaching a
+      // native class dispatch record referencing the interceptor.
+      if (argumentsToJsInterceptorConstant != null &&
+          argumentsToJsInterceptorConstant.contains(node)) {
+        if (constant.isType()) {
+          TypeConstant typeConstant = constant;
+          if (typeConstant.representedType is InterfaceType) {
+            world.registerInstantiatedType(typeConstant.representedType,
+                mapping);
+          } else {
+            compiler.reportError(node,
+                MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
+          }
+        } else {
+          compiler.reportError(node,
+              MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
+        }
+      }
     });
   }
 
@@ -3191,11 +3182,11 @@
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
         // The syntax [: <>[] :] is not allowed.
-        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
+        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
       } else {
         typeArgument = resolveTypeAnnotation(nodes.head);
         for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-          warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+          warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
           resolveTypeAnnotation(nodes.head);
         }
       }
@@ -3406,16 +3397,16 @@
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
         // The syntax [: <>{} :] is not allowed.
-        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
+        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
       } else {
         keyTypeArgument = resolveTypeAnnotation(nodes.head);
         nodes = nodes.tail;
         if (nodes.isEmpty) {
-          warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning);
+          warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
         } else {
           valueTypeArgument = resolveTypeAnnotation(nodes.head);
           for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-            warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+            warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
             resolveTypeAnnotation(nodes.head);
           }
         }
@@ -3475,7 +3466,7 @@
           // It's an error if the same label occurs twice in the same switch.
           compiler.reportError(
               label,
-              MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName});
+              MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
           compiler.reportInfo(
               existingElement.label,
               MessageKind.EXISTING_LABEL, {'labelName': labelName});
@@ -3483,9 +3474,9 @@
           // It's only a warning if it shadows another label.
           existingElement = statementScope.lookupLabel(labelName);
           if (existingElement != null) {
-            compiler.reportWarningCode(
+            compiler.reportWarning(
                 label,
-                MessageKind.DUPLICATE_LABEL.warning, {'labelName': labelName});
+                MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
             compiler.reportInfo(
                 existingElement.label,
                 MessageKind.EXISTING_LABEL, {'labelName': labelName});
@@ -3697,7 +3688,7 @@
     resolveTypeVariableBounds(node.typeParameters);
 
     FunctionSignature signature = SignatureResolver.analyze(
-        compiler, node.formals, node.returnType, element,
+        compiler, node.formals, node.returnType, element, mapping,
         defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
     element.functionSignature = signature;
 
@@ -3881,13 +3872,13 @@
     if (!element.hasConstructor) {
       Element superMember = element.superclass.localLookup('');
       if (superMember == null || !superMember.isGenerativeConstructor()) {
-        DualKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
+        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
         Map arguments = {'constructorName': ''};
         // TODO(ahe): Why is this a compile-time error? Or if it is an error,
         // why do we bother to registerThrowNoSuchMethod below?
-        compiler.reportError(node, kind.error, arguments);
+        compiler.reportError(node, kind, arguments);
         superMember = new ErroneousElementX(
-            kind.error, arguments, '', element);
+            kind, arguments, '', element);
         compiler.backend.registerThrowNoSuchMethod(mapping);
       } else {
         Selector callToMatch = new Selector.call("", element.getLibrary(), 0);
@@ -3927,7 +3918,7 @@
     if (identical(node.classKeyword.stringValue, 'typedef')) {
       // TODO(aprelev@gmail.com): Remove this deprecation diagnostic
       // together with corresponding TODO in parser.dart.
-      compiler.reportWarningCode(node.classKeyword,
+      compiler.reportWarning(node.classKeyword,
           MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX);
     }
 
@@ -4298,7 +4289,7 @@
     Identifier selector = node.selector.asIdentifier();
     var e = prefixElement.lookupLocalMember(selector.source);
     if (e == null || !e.impliesType()) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE.error,
+      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
             {'typeName': node.selector});
       return;
     }
@@ -4376,7 +4367,7 @@
   }
 
   failOrReturnErroneousElement(Element enclosing, Node diagnosticNode,
-                               String targetName, DualKind kind,
+                               String targetName, MessageKind kind,
                                Map arguments) {
     if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
       compiler.backend.registerThrowNoSuchMethod(resolver.mapping);
@@ -4384,15 +4375,11 @@
       compiler.backend.registerThrowRuntimeError(resolver.mapping);
     }
     if (inConstContext) {
-      compiler.reportError(diagnosticNode, kind.error, arguments);
+      compiler.reportError(diagnosticNode, kind, arguments);
     } else {
-      ResolutionWarning warning  =
-          new ResolutionWarning(
-              kind.warning, arguments, compiler.terseDiagnostics);
-      compiler.reportWarning(diagnosticNode, warning);
+      compiler.reportWarning(diagnosticNode, kind, arguments);
     }
-    return new ErroneousElementX(
-        kind.error, arguments, targetName, enclosing);
+    return new ErroneousElementX(kind, arguments, targetName, enclosing);
   }
 
   Selector createConstructorSelector(String constructorName) {
@@ -4499,7 +4486,7 @@
             MessageKind.CANNOT_RESOLVE,
             {'name': name});
       } else if (!element.isClass()) {
-        error(node, MessageKind.NOT_A_TYPE.error, {'node': name});
+        error(node, MessageKind.NOT_A_TYPE, {'node': name});
       }
     } else {
       internalError(node.receiver, 'unexpected element $element');
@@ -4525,7 +4512,7 @@
       error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
             {'typeVariableName': name});
     } else if (!element.isClass() && !element.isPrefix()) {
-      error(node, MessageKind.NOT_A_TYPE.error, {'node': name});
+      error(node, MessageKind.NOT_A_TYPE, {'node': name});
     }
     return element;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 460f6da..57fcedc 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -6,9 +6,8 @@
 
 import 'dart:collection' show Queue;
 
-import '../dart2jslib.dart' hide Diagnostic;
+import '../dart2jslib.dart';
 import '../dart_types.dart';
-import '../../compiler.dart' show Diagnostic;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart'
@@ -22,11 +21,13 @@
          LabelElementX,
          TargetElementX,
          MixinApplicationElementX,
+         ParameterElementX,
          TypeVariableElementX,
          TypedefElementX,
          SynthesizedConstructorElementX,
          MetadataAnnotationX,
-         ParameterMetadataAnnotation;
+         ParameterMetadataAnnotation,
+         MetadataContainer;
 import '../util/util.dart';
 
 import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/signatures.dart b/sdk/lib/_internal/compiler/implementation/resolution/signatures.dart
index 1978aa0..cd21970 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/signatures.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/signatures.dart
@@ -7,8 +7,9 @@
 /**
  * [SignatureResolver] resolves function signatures.
  */
-class SignatureResolver extends CommonResolverVisitor<Element> {
+class SignatureResolver extends MappingVisitor<Element> {
   final Element enclosingElement;
+  final Scope scope;
   final MessageKind defaultValuesError;
   Link<Element> optionalParameters = const Link<Element>();
   int optionalParameterCount = 0;
@@ -17,9 +18,12 @@
   VariableDefinitions currentDefinitions;
 
   SignatureResolver(Compiler compiler,
-                    this.enclosingElement,
+                    Element enclosingElement,
+                    TreeElementMapping treeElements,
                     {this.defaultValuesError})
-      : super(compiler);
+      : this.enclosingElement = enclosingElement,
+        this.scope = enclosingElement.buildScope(),
+        super(compiler, treeElements);
 
   bool get defaultValuesAllowed => defaultValuesError == null;
 
@@ -64,15 +68,7 @@
     currentDefinitions = node;
     Element element = definition.accept(this);
     if (currentDefinitions.metadata != null) {
-      // TODO(johnniwinther): Unify handling of metadata on locals/formals.
-      for (Link<Node> link = currentDefinitions.metadata.nodes;
-           !link.isEmpty;
-           link = link.tail) {
-        ParameterMetadataAnnotation metadata =
-            new ParameterMetadataAnnotation(link.head);
-        element.addMetadata(metadata);
-        metadata.ensureResolved(compiler);
-      }
+      compiler.resolver.resolveMetadata(element, node);
     }
     currentDefinitions = null;
     return element;
@@ -87,29 +83,45 @@
     }
   }
 
-  Element visitIdentifier(Identifier node) {
-    validateName(node);
-    Element variables = new VariableListElementX.node(currentDefinitions,
-        ElementKind.VARIABLE_LIST, enclosingElement);
-    // Ensure a parameter is not typed 'void'.
-    variables.computeType(compiler);
-    return new VariableElementX(node.source, variables,
-        ElementKind.PARAMETER, node);
+  void computeParameterType(ParameterElementX element) {
+    if (currentDefinitions.type != null) {
+      element.type = compiler.resolver.resolveTypeAnnotation(element,
+          currentDefinitions.type);
+    } else {
+      // Is node.definitions exactly one FunctionExpression?
+      Link<Node> link = currentDefinitions.definitions.nodes;
+      if (!link.isEmpty &&
+          link.head.asFunctionExpression() != null &&
+          link.tail.isEmpty) {
+        FunctionExpression functionExpression = link.head;
+        // We found exactly one FunctionExpression
+        element.functionSignature = SignatureResolver.analyze(
+            compiler, functionExpression.parameters,
+            functionExpression.returnType, element, mapping,
+            defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT);
+        element.type =
+            compiler.computeFunctionType(element, element.functionSignature);
+      } else {
+        element.type = compiler.types.dynamicType;
+      }
+    }
   }
 
-  String getParameterName(Send node) {
+  Element visitIdentifier(Identifier node) {
+    return createParameter(node, node);
+  }
+
+  Identifier getParameterName(Send node) {
     var identifier = node.selector.asIdentifier();
     if (identifier != null) {
       // Normal parameter: [:Type name:].
-      validateName(identifier);
-      return identifier.source;
+      return identifier;
     } else {
       // Function type parameter: [:void name(DartType arg):].
       var functionExpression = node.selector.asFunctionExpression();
       if (functionExpression != null &&
           functionExpression.name.asIdentifier() != null) {
-        validateName(functionExpression.name);
-        return functionExpression.name.asIdentifier().source;
+        return functionExpression.name.asIdentifier();
       } else {
         cancel(node,
             'internal error: unimplemented receiver on parameter send');
@@ -120,8 +132,21 @@
 
   // The only valid [Send] can be in constructors and must be of the form
   // [:this.x:] (where [:x:] represents an instance field).
-  FieldParameterElement visitSend(Send node) {
-    FieldParameterElement element;
+  FieldParameterElementX visitSend(Send node) {
+    return createFieldParameter(node);
+  }
+
+  ParameterElementX createParameter(Node node, Identifier name) {
+    validateName(name);
+    ParameterElementX parameter = new ParameterElementX(
+        name.source,
+        enclosingElement, ElementKind.PARAMETER, currentDefinitions, node);
+    computeParameterType(parameter);
+    return parameter;
+  }
+
+  FieldParameterElementX createFieldParameter(Send node) {
+    FieldParameterElementX element;
     if (node.receiver.asIdentifier() == null ||
         !node.receiver.asIdentifier().isThis()) {
       error(node, MessageKind.INVALID_PARAMETER);
@@ -129,37 +154,30 @@
                           ElementKind.GENERATIVE_CONSTRUCTOR)) {
       error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
     } else {
-      String name = getParameterName(node);
-      Element fieldElement = currentClass.lookupLocalMember(name);
+      Identifier name = getParameterName(node);
+      validateName(name);
+      Element fieldElement = currentClass.lookupLocalMember(name.source);
       if (fieldElement == null ||
           !identical(fieldElement.kind, ElementKind.FIELD)) {
         error(node, MessageKind.NOT_A_FIELD, {'fieldName': name});
       } else if (!fieldElement.isInstanceMember()) {
         error(node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name});
       }
-      Element variables = new VariableListElementX.node(currentDefinitions,
-          ElementKind.VARIABLE_LIST, enclosingElement);
-      element = new FieldParameterElementX(name, fieldElement, variables, node);
+      element = new FieldParameterElementX(name.source,
+          enclosingElement, currentDefinitions, node, fieldElement);
+      computeParameterType(element);
     }
     return element;
   }
 
   /// A [SendSet] node is an optional parameter with a default value.
   Element visitSendSet(SendSet node) {
-    Element element;
+    ParameterElementX element;
     if (node.receiver != null) {
-      element = visitSend(node);
+      element = createFieldParameter(node);
     } else if (node.selector.asIdentifier() != null ||
                node.selector.asFunctionExpression() != null) {
-      Element variables = new VariableListElementX.node(currentDefinitions,
-          ElementKind.VARIABLE_LIST, enclosingElement);
-      Identifier identifier = node.selector.asIdentifier() != null ?
-          node.selector.asIdentifier() :
-          node.selector.asFunctionExpression().name.asIdentifier();
-      validateName(identifier);
-      String source = identifier.source;
-      element = new VariableElementX(source, variables,
-          ElementKind.PARAMETER, node);
+      element = createParameter(node, getParameterName(node));
     }
     Node defaultValue = node.arguments.head;
     if (!defaultValuesAllowed) {
@@ -182,13 +200,7 @@
       compiler.reportError(modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER);
     }
 
-    Element variable = visit(node.name);
-    SignatureResolver.analyze(compiler, node.parameters, node.returnType,
-        variable,
-        defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT);
-    // TODO(ahe): Resolve and record the function type in the correct
-    // [TreeElements].
-    return variable;
+    return createParameter(node, node.name);
   }
 
   LinkBuilder<Element> analyzeNodes(Link<Node> link) {
@@ -209,15 +221,17 @@
   }
 
   /**
-   * Resolves formal parameters and return type to a [FunctionSignature].
+   * Resolves formal parameters and return type of a [FunctionExpression]
+   * to a [FunctionSignature].
    */
   static FunctionSignature analyze(Compiler compiler,
                                    NodeList formalParameters,
                                    Node returnNode,
                                    Element element,
+                                   TreeElementMapping mapping,
                                    {MessageKind defaultValuesError}) {
     SignatureResolver visitor = new SignatureResolver(compiler, element,
-        defaultValuesError: defaultValuesError);
+        mapping, defaultValuesError: defaultValuesError);
     Link<Element> parameters = const Link<Element>();
     int requiredParameterCount = 0;
     if (formalParameters == null) {
@@ -248,7 +262,7 @@
             returnType, new TreeElementMapping(element));
       }
     } else {
-      returnType = compiler.resolveReturnType(element, returnNode);
+      returnType = compiler.resolver.resolveReturnType(element, returnNode);
     }
 
     if (element.isSetter() && (requiredParameterCount != 1 ||
@@ -270,8 +284,7 @@
   // TODO(ahe): This is temporary.
   void resolveExpression(Node node) {
     if (node == null) return;
-    node.accept(new ResolverVisitor(compiler, enclosingElement,
-                                    new TreeElementMapping(enclosingElement)));
+    node.accept(new ResolverVisitor(compiler, enclosingElement, mapping));
   }
 
   // TODO(ahe): This is temporary.
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 6f7aa5c..02715ad 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -622,9 +622,9 @@
   }
 
   void reportError(Spannable spannable,
-                   MessageKind errorCode,
+                   MessageKind messageKind,
                    [Map arguments = const {}]) {
-    String message = errorCode.error(arguments, true).toString();
+    String message = messageKind.message(arguments, true).toString();
     Token token;
     Node node;
     if (spannable is Token) {
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index ab11a77..c97cebe 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -82,12 +82,30 @@
   void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
     if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
     if (enableColors) {
-      print('${colors.green("info:")} $message');
+      print('${colors.green("Info:")} $message');
     } else {
-      print('info: $message');
+      print('Info: $message');
     }
   }
 
+  /// Adds [kind] specific prefix to [message].
+  String prefixMessage(String message, api.Diagnostic kind) {
+    switch (kind) {
+      case api.Diagnostic.ERROR:
+        return 'Error: $message';
+      case api.Diagnostic.WARNING:
+        return 'Warning: $message';
+      case api.Diagnostic.HINT:
+        return 'Hint: $message';
+      case api.Diagnostic.CRASH:
+        return 'Internal Error: $message';
+      case api.Diagnostic.INFO:
+      case api.Diagnostic.VERBOSE_INFO:
+        return 'Info: $message';
+    }
+    throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})';
+  }
+
   void diagnosticHandler(Uri uri, int begin, int end, String message,
                          api.Diagnostic kind) {
     // TODO(ahe): Remove this when source map is handled differently.
@@ -95,6 +113,9 @@
 
     if (isAborting) return;
     isAborting = (kind == api.Diagnostic.CRASH);
+
+    message = prefixMessage(message, kind);
+
     bool fatal = (kind.ordinal & FATAL) != 0;
     bool isInfo = (kind.ordinal & INFO) != 0;
     if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 5f49bd6..17c9706 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -159,7 +159,7 @@
    * If the scope (function or loop) [node] has captured variables then this
    * method creates a box and sets up the redirections.
    */
-  void enterScope(Node node, Element element) {
+  void enterScope(ast.Node node, Element element) {
     // See if any variable in the top-scope of the function is captured. If yes
     // we need to create a box-object.
     ClosureScope scopeData = closureData.capturingScopes[node];
@@ -223,7 +223,7 @@
    *
    * Invariant: [function] must be an implementation element.
    */
-  void startFunction(Element element, Expression node) {
+  void startFunction(Element element, ast.Expression node) {
     assert(invariant(element, element.isImplementation));
     Compiler compiler = builder.compiler;
     closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
@@ -454,16 +454,16 @@
    * initializers.
    *
    * The [LocalsHandler] will make the boxes and updates at the right moment.
-   * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for
-   * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and
-   * [endLoop] must also be called.
+   * The builder just needs to call [enterLoopBody] and [enterLoopUpdates]
+   * (for [ast.For] loops) at the correct places. For phi-handling
+   * [beginLoopHeader] and [endLoop] must also be called.
    *
    * The correct place for the box depends on the given loop. In most cases
    * the box will be created when entering the loop-body: while, do-while, and
    * for-in (assuming the call to [:next:] is inside the body) can always be
    * constructed this way.
    *
-   * Things are slightly more complicated for [For] loops. If no declared
+   * Things are slightly more complicated for [ast.For] loops. If no declared
    * loop variable is boxed then the loop-body approach works here too. If a
    * loop-variable is boxed we need to introduce a new box for the
    * loop-variable before we enter the initializer so that the initializer
@@ -483,7 +483,7 @@
    *     print("--");
    *     for (var i = 0; i < 2; i++) fs[i]();
    *
-   * We solve this by emitting the following code (only for [For] loops):
+   * We solve this by emitting the following code (only for [ast.For] loops):
    *  <Create box>    <== move the first box creation outside the loop.
    *  <initializer>;
    *  loop-entry:
@@ -494,7 +494,7 @@
    *    goto loop-entry;
    *  loop-exit:
    */
-  void startLoop(Node node) {
+  void startLoop(ast.Node node) {
     ClosureScope scopeData = closureData.capturingScopes[node];
     if (scopeData == null) return;
     if (scopeData.hasBoxedLoopVariables()) {
@@ -532,7 +532,7 @@
     });
   }
 
-  void enterLoopBody(Node node) {
+  void enterLoopBody(ast.Node node) {
     ClosureScope scopeData = closureData.capturingScopes[node];
     if (scopeData == null) return;
     // If there are no declared boxed loop variables then we did not create the
@@ -542,7 +542,7 @@
     }
   }
 
-  void enterLoopUpdates(Node node) {
+  void enterLoopUpdates(ast.Node node) {
     // If there are declared boxed loop variables then the updates might have
     // access to the box and we must switch to a new box before executing the
     // updates.
@@ -749,7 +749,7 @@
       continueInstruction = new HContinue.toLabel(label);
       // Switch case continue statements must be handled by the
       // [SwitchCaseJumpHandler].
-      assert(label.target.statement is! SwitchCase);
+      assert(label.target.statement is! ast.SwitchCase);
     }
     LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
     builder.close(continueInstruction);
@@ -806,16 +806,16 @@
 
   SwitchCaseJumpHandler(SsaFromAstMixin builder,
                         TargetElement target,
-                        SwitchStatement node)
+                        ast.SwitchStatement node)
       : super(builder, target) {
     // The switch case indices must match those computed in
     // [SsaFromAstMixin.buildSwitchCaseConstants].
     // Switch indices are 1-based so we can bypass the synthetic loop when no
     // cases match simply by branching on the index (which defaults to null).
     int switchIndex = 1;
-    for (SwitchCase switchCase in node.cases) {
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        Node label = labelOrCase.asLabel();
+    for (ast.SwitchCase switchCase in node.cases) {
+      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+        ast.Node label = labelOrCase.asLabel();
         if (label != null) {
           LabelElement labelElement = builder.elements[label];
           if (labelElement != null && labelElement.isContinueTarget) {
@@ -886,7 +886,7 @@
  * and [SsaFromAstBuilder].
  *
  * The type parameter [N] represents the node type from which the SSA form is
- * built, either [IrNode] or [Node].
+ * built, either [ir.Node] or [ast.Node].
  *
  * The following diagram shows the mixin structure of the AST and IR builders
  * and inliners, which is explained in the text below.
@@ -1287,11 +1287,11 @@
       }
       bool canInline;
       if (hasIr) {
-        IrFunction irFunction = compiler.irBuilder.getIr(function);
+        ir.Function irFunction = compiler.irBuilder.getIr(function);
         canInline = IrInlineWeeder.canBeInlined(
             irFunction, maxInliningNodes, useMaxInliningNodes);
       } else {
-        FunctionExpression functionNode = function.parseNode(compiler);
+        ast.FunctionExpression functionNode = function.parseNode(compiler);
         canInline = InlineWeeder.canBeInlined(
             functionNode, maxInliningNodes, useMaxInliningNodes);
       }
@@ -1455,7 +1455,7 @@
  * [SsaFromAstBuilder] and [SsaFromAstInliner].
  */
 abstract class SsaFromAstMixin
-    implements ResolvedVisitor, SsaBuilderMixin<Node> {
+    implements ResolvedVisitor, SsaBuilderMixin<ast.Node> {
   CodegenWorkItem get work;
   ConstantSystem get constantSystem;
   RuntimeTypes get rti;
@@ -1512,14 +1512,14 @@
 
   bool inTryStatement = false;
 
-  Constant getConstantForNode(Node node) {
+  Constant getConstantForNode(ast.Node node) {
     Constant constant = elements.getConstant(node);
     assert(invariant(node, constant != null,
         message: 'No constant computed for $node'));
     return constant;
   }
 
-  HInstruction addConstant(Node node) {
+  HInstruction addConstant(ast.Node node) {
     return graph.addConstant(getConstantForNode(node), compiler);
   }
 
@@ -1568,7 +1568,7 @@
   HGraph buildMethod(FunctionElement functionElement) {
     assert(invariant(functionElement, functionElement.isImplementation));
     graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
-    FunctionExpression function = functionElement.parseNode(compiler);
+    ast.FunctionExpression function = functionElement.parseNode(compiler);
     assert(function != null);
     assert(!function.modifiers.isExternal());
     assert(elements[function] != null);
@@ -1615,9 +1615,9 @@
   }
 
   HGraph buildLazyInitializer(VariableElement variable) {
-    SendSet node = variable.parseNode(compiler);
+    ast.SendSet node = variable.parseNode(compiler);
     openFunction(variable, node);
-    Link<Node> link = node.arguments;
+    Link<ast.Node> link = node.arguments;
     assert(!link.isEmpty && link.tail.isEmpty);
     visit(link.head);
     HInstruction value = pop();
@@ -1636,7 +1636,7 @@
     assert(constructor.isGenerativeConstructor());
     assert(invariant(constructor, constructor.isImplementation));
     if (constructor.isSynthesized) return null;
-    FunctionExpression node = constructor.parseNode(compiler);
+    ast.FunctionExpression node = constructor.parseNode(compiler);
     // If we know the body doesn't have any code, we don't generate it.
     if (!node.hasBody()) return null;
     if (node.hasEmptyBody()) return null;
@@ -1768,7 +1768,7 @@
     if (function.isGenerativeConstructor()) {
       buildFactory(function);
     } else {
-      FunctionExpression functionNode = function.parseNode(compiler);
+      ast.FunctionExpression functionNode = function.parseNode(compiler);
       functionNode.body.accept(this);
     }
   }
@@ -1786,7 +1786,7 @@
     }
   }
 
-  bool providedArgumentsKnownToBeComplete(Node currentNode) {
+  bool providedArgumentsKnownToBeComplete(ast.Node currentNode) {
     /* When inlining the iterator methods generated for a [:for-in:] loop, the
      * [currentNode] is the [ForIn] tree. The compiler-generated iterator
      * invocations are known to have fully specified argument lists, no default
@@ -1875,7 +1875,7 @@
       TreeElements oldElements = elements;
       elements = compiler.enqueuer.resolution.getCachedElements(callee);
       ClosureClassMap oldClosureData = localsHandler.closureData;
-      Node node = callee.parseNode(compiler);
+      ast.Node node = callee.parseNode(compiler);
       ClosureClassMap newClosureData =
           compiler.closureToClassMapper.computeClosureToClassMapping(
               callee, node, elements);
@@ -1923,22 +1923,22 @@
           constructor);
       return;
     }
-    FunctionExpression functionNode = constructor.parseNode(compiler);
+    ast.FunctionExpression functionNode = constructor.parseNode(compiler);
 
     bool foundSuperOrRedirect = false;
     if (functionNode.initializers != null) {
-      Link<Node> initializers = functionNode.initializers.nodes;
-      for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
-        assert(link.head is Send);
-        if (link.head is !SendSet) {
+      Link<ast.Node> initializers = functionNode.initializers.nodes;
+      for (Link<ast.Node> link = initializers; !link.isEmpty; link = link.tail) {
+        assert(link.head is ast.Send);
+        if (link.head is !ast.SendSet) {
           // A super initializer or constructor redirection.
           foundSuperOrRedirect = true;
-          Send call = link.head;
-          assert(Initializers.isSuperConstructorCall(call) ||
-                 Initializers.isConstructorRedirect(call));
+          ast.Send call = link.head;
+          assert(ast.Initializers.isSuperConstructorCall(call) ||
+                 ast.Initializers.isConstructorRedirect(call));
           FunctionElement target = elements[call].implementation;
           Selector selector = elements.getSelector(call);
-          Link<Node> arguments = call.arguments;
+          Link<ast.Node> arguments = call.arguments;
           List<HInstruction> compiledArguments = new List<HInstruction>();
           inlinedFrom(constructor, () {
             addStaticSendArgumentsToList(selector,
@@ -1953,8 +1953,8 @@
                                 constructor);
         } else {
           // A field initializer.
-          SendSet init = link.head;
-          Link<Node> arguments = init.arguments;
+          ast.SendSet init = link.head;
+          Link<ast.Node> arguments = init.arguments;
           assert(!arguments.isEmpty && arguments.tail.isEmpty);
           inlinedFrom(constructor, () {
             visit(arguments.head);
@@ -1980,7 +1980,7 @@
           compiler.internalError("no default constructor available");
         }
         List<HInstruction> arguments = <HInstruction>[];
-        selector.addArgumentsToList(const Link<Node>(),
+        selector.addArgumentsToList(const Link<ast.Node>(),
                                     arguments,
                                     target.implementation,
                                     null,
@@ -2008,8 +2008,8 @@
         (ClassElement enclosingClass, Element member) {
           compiler.withCurrentElement(member, () {
             TreeElements definitions = compiler.analyzeElement(member);
-            Node node = member.parseNode(compiler);
-            SendSet assignment = node.asSendSet();
+            ast.Node node = member.parseNode(compiler);
+            ast.SendSet assignment = node.asSendSet();
             if (assignment == null) {
               // Unassigned fields of native classes are not initialized to
               // prevent overwriting pre-initialized native properties.
@@ -2017,7 +2017,7 @@
                 fieldValues[member] = graph.addConstantNull(compiler);
               }
             } else {
-              Node right = assignment.arguments.head;
+              ast.Node right = assignment.arguments.head;
               TreeElements savedElements = elements;
               elements = definitions;
               // In case the field initializer uses closures, run the
@@ -2047,7 +2047,7 @@
         functionElement.getEnclosingClass().implementation;
     bool isNativeUpgradeFactory =
         Elements.isNativeOrExtendsNative(classElement);
-    FunctionExpression function = functionElement.parseNode(compiler);
+    ast.FunctionExpression function = functionElement.parseNode(compiler);
     // Note that constructors (like any other static function) do not need
     // to deal with optional arguments. It is the callers job to provide all
     // arguments as if they were positional.
@@ -2218,7 +2218,7 @@
       bodyCallInputs.add(newObject);
       TreeElements elements =
           compiler.enqueuer.resolution.getCachedElements(constructor);
-      Node node = constructor.parseNode(compiler);
+      ast.Node node = constructor.parseNode(compiler);
       ClosureClassMap parameterClosureData =
           compiler.closureToClassMapper.getMappingForNestedFunction(node);
 
@@ -2273,7 +2273,7 @@
    *
    * Invariant: [functionElement] must be the implementation element.
    */
-  void openFunction(Element element, Expression node) {
+  void openFunction(Element element, ast.Expression node) {
     assert(invariant(element, element.isImplementation));
     HBasicBlock block = graph.addNewBlock();
     open(graph.entry);
@@ -2370,12 +2370,12 @@
     return other;
   }
 
-  void assertIsSubtype(Node node, DartType subtype, DartType supertype,
+  void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype,
                        String message) {
     HInstruction subtypeInstruction = analyzeTypeArgument(subtype);
     HInstruction supertypeInstruction = analyzeTypeArgument(supertype);
     HInstruction messageInstruction =
-        graph.addConstantString(new DartString.literal(message), compiler);
+        graph.addConstantString(new ast.DartString.literal(message), compiler);
     Element element = backend.getAssertIsSubtype();
     var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
                                 messageInstruction];
@@ -2397,7 +2397,7 @@
     stack.add(instruction);
   }
 
-  void pushWithPosition(HInstruction instruction, Node node) {
+  void pushWithPosition(HInstruction instruction, ast.Node node) {
     push(attachPosition(instruction, node));
   }
 
@@ -2422,20 +2422,20 @@
     return result;
   }
 
-  HInstruction attachPosition(HInstruction target, Node node) {
+  HInstruction attachPosition(HInstruction target, ast.Node node) {
     if (node != null) {
       target.sourcePosition = sourceFileLocationForBeginToken(node);
     }
     return target;
   }
 
-  SourceFileLocation sourceFileLocationForBeginToken(Node node) =>
+  SourceFileLocation sourceFileLocationForBeginToken(ast.Node node) =>
       sourceFileLocationForToken(node, node.getBeginToken());
 
-  SourceFileLocation sourceFileLocationForEndToken(Node node) =>
+  SourceFileLocation sourceFileLocationForEndToken(ast.Node node) =>
       sourceFileLocationForToken(node, node.getEndToken());
 
-  SourceFileLocation sourceFileLocationForToken(Node node, Token token) {
+  SourceFileLocation sourceFileLocationForToken(ast.Node node, Token token) {
     SourceFile sourceFile = currentSourceFile();
     SourceFileLocation location =
         new TokenSourceFileLocation(sourceFile, token);
@@ -2443,14 +2443,14 @@
     return location;
   }
 
-  void visit(Node node) {
+  void visit(ast.Node node) {
     if (node != null) node.accept(this);
   }
 
-  visitBlock(Block node) {
+  visitBlock(ast.Block node) {
     assert(!isAborted());
     if (!isReachable) return;  // This can only happen when inlining.
-    for (Link<Node> link = node.statements.nodes;
+    for (Link<ast.Node> link = node.statements.nodes;
          !link.isEmpty;
          link = link.tail) {
       visit(link.head);
@@ -2464,11 +2464,11 @@
     if (!stack.isEmpty) compiler.cancel('non-empty instruction stack');
   }
 
-  visitClassNode(ClassNode node) {
+  visitClassNode(ast.ClassNode node) {
     compiler.internalError('visitClassNode should not be called', node: node);
   }
 
-  visitThrowExpression(Expression expression) {
+  visitThrowExpression(ast.Expression expression) {
     bool old = inThrowExpression;
     try {
       inThrowExpression = true;
@@ -2478,9 +2478,9 @@
     }
   }
 
-  visitExpressionStatement(ExpressionStatement node) {
+  visitExpressionStatement(ast.ExpressionStatement node) {
     if (!isReachable) return;
-    Throw throwExpression = node.expression.asThrow();
+    ast.Throw throwExpression = node.expression.asThrow();
     if (throwExpression != null && inliningStack.isEmpty) {
       visitThrowExpression(throwExpression.expression);
       handleInTryStatement();
@@ -2496,7 +2496,7 @@
    * is closed with an [HGoto] and replaced by the newly created block.
    * Also notifies the locals handler that we're entering a loop.
    */
-  JumpHandler beginLoopHeader(Node node) {
+  JumpHandler beginLoopHeader(ast.Node node) {
     assert(!isAborted());
     HBasicBlock previousBlock = close(new HGoto());
 
@@ -2575,7 +2575,7 @@
   // For while loops, initializer and update are null.
   // The condition function must return a boolean result.
   // None of the functions must leave anything on the stack.
-  void handleLoop(Node loop,
+  void handleLoop(ast.Node loop,
                   void initialize(),
                   HInstruction condition(),
                   void update(),
@@ -2766,12 +2766,12 @@
     loopNesting--;
   }
 
-  visitFor(For node) {
+  visitFor(ast.For node) {
     assert(isReachable);
     assert(node.body != null);
     void buildInitializer() {
       if (node.initializer == null) return;
-      Node initializer = node.initializer;
+      ast.Node initializer = node.initializer;
       if (initializer != null) {
         visit(initializer);
         if (initializer.asExpression() != null) {
@@ -2787,7 +2787,7 @@
       return popBoolified();
     }
     void buildUpdate() {
-      for (Expression expression in node.update) {
+      for (ast.Expression expression in node.update) {
         visit(expression);
         assert(!isAborted());
         // The result of the update instruction isn't used, and can just
@@ -2801,7 +2801,7 @@
     handleLoop(node, buildInitializer, buildCondition, buildUpdate, buildBody);
   }
 
-  visitWhile(While node) {
+  visitWhile(ast.While node) {
     assert(isReachable);
     HInstruction buildCondition() {
       visit(node.condition);
@@ -2814,7 +2814,7 @@
                () { visit(node.body); });
   }
 
-  visitDoWhile(DoWhile node) {
+  visitDoWhile(ast.DoWhile node) {
     assert(isReachable);
     LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
     localsHandler.startLoop(node);
@@ -2947,7 +2947,7 @@
     loopNesting--;
   }
 
-  visitFunctionExpression(FunctionExpression node) {
+  visitFunctionExpression(ast.FunctionExpression node) {
     ClosureClassMap nestedClosureData =
         compiler.closureToClassMapper.getMappingForNestedFunction(node);
     assert(nestedClosureData != null);
@@ -2982,13 +2982,13 @@
     }
   }
 
-  visitFunctionDeclaration(FunctionDeclaration node) {
+  visitFunctionDeclaration(ast.FunctionDeclaration node) {
     assert(isReachable);
     visit(node.function);
     localsHandler.updateLocal(elements[node], pop());
   }
 
-  visitIdentifier(Identifier node) {
+  visitIdentifier(ast.Identifier node) {
     if (node.isThis()) {
       stack.add(localsHandler.readThis());
     } else {
@@ -2997,7 +2997,7 @@
     }
   }
 
-  visitIf(If node) {
+  visitIf(ast.If node) {
     assert(isReachable);
     handleIf(node,
              () => visit(node.condition),
@@ -3005,13 +3005,13 @@
              node.elsePart != null ? () => visit(node.elsePart) : null);
   }
 
-  void handleIf(Node diagnosticNode,
+  void handleIf(ast.Node diagnosticNode,
                 void visitCondition(), void visitThen(), void visitElse()) {
     SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode);
     branchBuilder.handleIf(visitCondition, visitThen, visitElse);
   }
 
-  void visitLogicalAndOr(Send node, Operator op) {
+  void visitLogicalAndOr(ast.Send node, ast.Operator op) {
     SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
     branchBuilder.handleLogicalAndOrWithLeftNode(
         node.receiver,
@@ -3019,15 +3019,15 @@
         isAnd: ("&&" == op.source));
   }
 
-  void visitLogicalNot(Send node) {
-    assert(node.argumentsNode is Prefix);
+  void visitLogicalNot(ast.Send node) {
+    assert(node.argumentsNode is ast.Prefix);
     visit(node.receiver);
     HNot not = new HNot(popBoolified(), backend.boolType);
     pushWithPosition(not, node);
   }
 
-  void visitUnary(Send node, Operator op) {
-    assert(node.argumentsNode is Prefix);
+  void visitUnary(ast.Send node, ast.Operator op) {
+    assert(node.argumentsNode is ast.Prefix);
     visit(node.receiver);
     assert(!identical(op.token.kind, PLUS_TOKEN));
     HInstruction operand = pop();
@@ -3047,10 +3047,10 @@
   }
 
   void visitBinary(HInstruction left,
-                   Operator op,
+                   ast.Operator op,
                    HInstruction right,
                    Selector selector,
-                   Send send) {
+                   ast.Send send) {
     switch (op.source) {
       case "===":
         pushWithPosition(
@@ -3069,7 +3069,7 @@
     }
   }
 
-  HInstruction generateInstanceSendReceiver(Send send) {
+  HInstruction generateInstanceSendReceiver(ast.Send send) {
     assert(Elements.isInstanceSend(send, elements));
     if (send.receiver == null) {
       return localsHandler.readThis();
@@ -3090,7 +3090,7 @@
    * Returns a set of interceptor classes that contain the given
    * [selector].
    */
-  void generateInstanceGetterWithCompiledReceiver(Send send,
+  void generateInstanceGetterWithCompiledReceiver(ast.Send send,
                                                   Selector selector,
                                                   HInstruction receiver) {
     assert(Elements.isInstanceSend(send, elements));
@@ -3098,7 +3098,7 @@
     pushInvokeDynamic(send, selector, [receiver]);
   }
 
-  void generateGetter(Send send, Element element) {
+  void generateGetter(ast.Send send, Element element) {
     if (Elements.isStaticOrTopLevelField(element)) {
       Constant value;
       if (element.isField() && !element.isAssignable()) {
@@ -3151,17 +3151,17 @@
       // An erroneous element indicates an unresolved static getter.
       generateThrowNoSuchMethod(send,
                                 getTargetName(element, 'get'),
-                                argumentNodes: const Link<Node>());
+                                argumentNodes: const Link<ast.Node>());
     } else {
       stack.add(localsHandler.readLocal(element));
     }
   }
 
-  void generateInstanceSetterWithCompiledReceiver(Send send,
+  void generateInstanceSetterWithCompiledReceiver(ast.Send send,
                                                   HInstruction receiver,
                                                   HInstruction value,
                                                   {Selector selector,
-                                                   Node location}) {
+                                                   ast.Node location}) {
     assert(send == null || Elements.isInstanceSend(send, elements));
     if (selector == null) {
       assert(send != null);
@@ -3177,10 +3177,10 @@
     stack.add(value);
   }
 
-  void generateNonInstanceSetter(SendSet send,
+  void generateNonInstanceSetter(ast.SendSet send,
                                  Element element,
                                  HInstruction value,
-                                 {Node location}) {
+                                 {ast.Node location}) {
     assert(send == null || !Elements.isInstanceSend(send, elements));
     if (location == null) {
       assert(send != null);
@@ -3261,8 +3261,8 @@
     }
   }
 
-  visitOperatorSend(Send node) {
-    Operator op = node.selector;
+  visitOperatorSend(ast.Send node) {
+    ast.Operator op = node.selector;
     if ("[]" == op.source) {
       visitDynamicSend(node);
     } else if ("&&" == op.source ||
@@ -3270,7 +3270,7 @@
       visitLogicalAndOr(node, op);
     } else if ("!" == op.source) {
       visitLogicalNot(node);
-    } else if (node.argumentsNode is Prefix) {
+    } else if (node.argumentsNode is ast.Prefix) {
       visitUnary(node, op);
     } else if ("is" == op.source) {
       visitIsSend(node);
@@ -3296,7 +3296,7 @@
     }
   }
 
-  void visitIsSend(Send node) {
+  void visitIsSend(ast.Send node) {
     visit(node.receiver);
     HInstruction expression = pop();
     bool isNot = node.isIsNotCheck;
@@ -3310,7 +3310,7 @@
     push(instruction);
   }
 
-  HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
+  HInstruction buildIsNode(ast.Node node, DartType type, HInstruction expression) {
     type = type.unalias(compiler);
     if (type.kind == TypeKind.FUNCTION) {
       List arguments = [buildFunctionType(type), expression];
@@ -3364,13 +3364,13 @@
     return pop();
   }
 
-  void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
+  void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
     Selector selector = elements.getSelector(node);
     if (selector.namedArgumentCount == 0) {
       addGenericSendArgumentsToList(node.arguments, list);
     } else {
       // Visit positional arguments and add them to the list.
-      Link<Node> arguments = node.arguments;
+      Link<ast.Node> arguments = node.arguments;
       int positionalArgumentCount = selector.positionalArgumentCount;
       for (int i = 0;
            i < positionalArgumentCount;
@@ -3405,12 +3405,12 @@
    * Invariant: [element] must be an implementation element.
    */
   bool addStaticSendArgumentsToList(Selector selector,
-                                    Link<Node> arguments,
+                                    Link<ast.Node> arguments,
                                     FunctionElement element,
                                     List<HInstruction> list) {
     assert(invariant(element, element.isImplementation));
 
-    HInstruction compileArgument(Node argument) {
+    HInstruction compileArgument(ast.Node argument) {
       visit(argument);
       return pop();
     }
@@ -3423,14 +3423,14 @@
                                        compiler);
   }
 
-  void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
+  void addGenericSendArgumentsToList(Link<ast.Node> link, List<HInstruction> list) {
     for (; !link.isEmpty; link = link.tail) {
       visit(link.head);
       list.add(pop());
     }
   }
 
-  visitDynamicSend(Send node) {
+  visitDynamicSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
 
     List<HInstruction> inputs = <HInstruction>[];
@@ -3445,7 +3445,7 @@
     }
   }
 
-  visitClosureSend(Send node) {
+  visitClosureSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
     assert(node.receiver == null);
     Element element = elements[node];
@@ -3466,8 +3466,8 @@
         node);
   }
 
-  void handleForeignJs(Send node) {
-    Link<Node> link = node.arguments;
+  void handleForeignJs(ast.Send node) {
+    Link<ast.Node> link = node.arguments;
     // If the invoke is on foreign code, don't visit the first
     // argument, which is the type, and the second argument,
     // which is the foreign code.
@@ -3489,7 +3489,7 @@
     return;
   }
 
-  void handleForeignJsCurrentIsolateContext(Send node) {
+  void handleForeignJsCurrentIsolateContext(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.cancel(
           'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT', node: node);
@@ -3515,9 +3515,9 @@
     }
   }
 
-  void handleForeignJsGetName(Send node) {
-    List<Node> arguments = node.arguments.toList();
-    Node argument;
+  void handleForeignJsGetName(ast.Send node) {
+    List<ast.Node> arguments = node.arguments.toList();
+    ast.Node argument;
     switch (arguments.length) {
     case 0:
       compiler.reportError(
@@ -3535,7 +3535,7 @@
       }
       return;
     }
-    LiteralString string = argument.asLiteralString();
+    ast.LiteralString string = argument.asLiteralString();
     if (string == null) {
       compiler.reportError(
           argument, MessageKind.GENERIC,
@@ -3547,11 +3547,11 @@
                 argument, string.dartString.slowToString())));
   }
 
-  void handleJsInterceptorConstant(Send node) {
+  void handleJsInterceptorConstant(ast.Send node) {
     // Single argument must be a TypeConstant which is converted into a
     // InterceptorConstant.
     if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
-      Node argument = node.arguments.head;
+      ast.Node argument = node.arguments.head;
       visit(argument);
       HInstruction argumentInstruction = pop();
       if (argumentInstruction is HConstant) {
@@ -3570,8 +3570,8 @@
     stack.add(graph.addConstantNull(compiler));
   }
 
-  void handleForeignJsCallInIsolate(Send node) {
-    Link<Node> link = node.arguments;
+  void handleForeignJsCallInIsolate(ast.Send node) {
+    Link<ast.Node> link = node.arguments;
     if (!compiler.hasIsolateSupport()) {
       // If the isolate library is not used, we just invoke the
       // closure.
@@ -3593,12 +3593,12 @@
     }
   }
 
-  FunctionSignature handleForeignRawFunctionRef(Send node, String name) {
+  FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
     if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
       compiler.cancel('"$name" requires exactly one argument',
                       node: node.argumentsNode);
     }
-    Node closure = node.arguments.head;
+    ast.Node closure = node.arguments.head;
     Element element = elements[closure];
     if (!Elements.isStaticOrTopLevelFunction(element)) {
       compiler.cancel(
@@ -3624,14 +3624,14 @@
     return params;
   }
 
-  void handleForeignDartClosureToJs(Send node, String name) {
+  void handleForeignDartClosureToJs(ast.Send node, String name) {
     // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
     // care to wrap the closure in another closure that saves the current
     // isolate.
     handleForeignRawFunctionRef(node, name);
   }
 
-  void handleForeignSetCurrentIsolate(Send node) {
+  void handleForeignSetCurrentIsolate(ast.Send node) {
     if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
       compiler.cancel('Exactly one argument required',
                       node: node.argumentsNode);
@@ -3646,7 +3646,7 @@
                       effects: sideEffects));
   }
 
-  void handleForeignCreateIsolate(Send node) {
+  void handleForeignCreateIsolate(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.cancel('Too many arguments',
                       node: node.argumentsNode);
@@ -3657,7 +3657,7 @@
                       <HInstruction>[]));
   }
 
-  void handleForeignDartObjectJsConstructorFunction(Send node) {
+  void handleForeignDartObjectJsConstructorFunction(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.cancel('Too many arguments', node: node.argumentsNode);
     }
@@ -3667,7 +3667,7 @@
                       <HInstruction>[]));
   }
 
-  void handleForeignJsCurrentIsolate(Send node) {
+  void handleForeignJsCurrentIsolate(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.cancel('Too many arguments', node: node.argumentsNode);
     }
@@ -3676,7 +3676,7 @@
                       <HInstruction>[]));
   }
 
-  visitForeignSend(Send node) {
+  visitForeignSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
     String name = selector.name;
     if (name == 'JS') {
@@ -3745,7 +3745,7 @@
     }
   }
 
-  generateSuperNoSuchMethodSend(Send node,
+  generateSuperNoSuchMethodSend(ast.Send node,
                                 Selector selector,
                                 List<HInstruction> arguments) {
     String name = selector.name;
@@ -3764,11 +3764,11 @@
     if (selector.isSetter()) publicName += '=';
 
     Constant nameConstant = constantSystem.createString(
-        new DartString.literal(publicName));
+        new ast.DartString.literal(publicName));
 
     String internalName = backend.namer.invocationName(selector);
     Constant internalNameConstant =
-        constantSystem.createString(new DartString.literal(internalName));
+        constantSystem.createString(new ast.DartString.literal(internalName));
 
     Element createInvocationMirror = backend.getCreateInvocationMirror();
     var argumentsInstruction = buildLiteralList(arguments);
@@ -3777,7 +3777,7 @@
     var argumentNames = new List<HInstruction>();
     for (String argumentName in selector.namedArguments) {
       Constant argumentNameConstant =
-          constantSystem.createString(new DartString.literal(argumentName));
+          constantSystem.createString(new ast.DartString.literal(argumentName));
       argumentNames.add(graph.addConstant(argumentNameConstant, compiler));
     }
     var argumentNamesInstruction = buildLiteralList(argumentNames);
@@ -3799,7 +3799,7 @@
     push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs));
   }
 
-  visitSuperSend(Send node) {
+  visitSuperSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
     Element element = elements[node];
     if (Elements.isUnresolved(element)) {
@@ -3867,7 +3867,7 @@
       // segmentation of '$'.
       String substitutionNameString = backend.namer.getNameForRti(cls);
       HInstruction substitutionName = graph.addConstantString(
-          new LiteralDartString(substitutionNameString), compiler);
+          new ast.LiteralDartString(substitutionNameString), compiler);
       pushInvokeStatic(null,
                        backend.getGetRuntimeTypeArgument(),
                        [target, substitutionName, index],
@@ -3965,7 +3965,7 @@
   }
 
   HInstruction handleListConstructor(InterfaceType type,
-                                     Node currentNode,
+                                     ast.Node currentNode,
                                      HInstruction newObject) {
     if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
       return newObject;
@@ -4011,8 +4011,8 @@
     return pop();
   }
 
-  handleNewSend(NewExpression node) {
-    Send send = node.send;
+  handleNewSend(ast.NewExpression node) {
+    ast.Send send = node.send;
     bool isFixedList = false;
     bool isFixedListConstructorCall =
         Elements.isFixedListConstructorCall(elements[send], send, compiler);
@@ -4186,7 +4186,7 @@
 
   /// In checked mode checks the [type] of [node] to be well-bounded. The method
   /// returns [:true:] if an error can be statically determined.
-  bool checkTypeVariableBounds(NewExpression node, InterfaceType type) {
+  bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) {
     if (!compiler.enableTypeAssertions) return false;
 
     Map<DartType, Set<DartType>> seenChecksMap =
@@ -4248,7 +4248,7 @@
     visitStaticSend(node);
   }
 
-  visitStaticSend(Send node) {
+  visitStaticSend(ast.Send node) {
     Selector selector = elements.getSelector(node);
     Element element = elements[node];
     if (element.isForeign(compiler)) {
@@ -4295,12 +4295,12 @@
   }
 
   HConstant addConstantString(String string) {
-    DartString dartString = new DartString.literal(string);
+    ast.DartString dartString = new ast.DartString.literal(string);
     Constant constant = constantSystem.createString(dartString);
     return graph.addConstant(constant, compiler);
   }
 
-  visitTypeReferenceSend(Send node) {
+  visitTypeReferenceSend(ast.Send node) {
     Element element = elements[node];
     if (element.isClass() || element.isTypedef()) {
       // TODO(karlklose): add type representation
@@ -4338,44 +4338,44 @@
     }
   }
 
-  visitGetterSend(Send node) {
+  visitGetterSend(ast.Send node) {
     generateGetter(node, elements[node]);
   }
 
   // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
-  internalError(String reason, {Node node}) {
+  internalError(String reason, {ast.Node node}) {
     compiler.internalError(reason, node: node);
   }
 
-  void generateError(Node node, String message, Element helper) {
+  void generateError(ast.Node node, String message, Element helper) {
     HInstruction errorMessage = addConstantString(message);
     pushInvokeStatic(node, helper, [errorMessage]);
   }
 
-  void generateRuntimeError(Node node, String message) {
+  void generateRuntimeError(ast.Node node, String message) {
     generateError(node, message, backend.getThrowRuntimeError());
   }
 
-  void generateTypeError(Node node, String message) {
+  void generateTypeError(ast.Node node, String message) {
     generateError(node, message, backend.getThrowTypeError());
   }
 
-  void generateAbstractClassInstantiationError(Node node, String message) {
+  void generateAbstractClassInstantiationError(ast.Node node, String message) {
     generateError(node,
                   message,
                   backend.getThrowAbstractClassInstantiationError());
   }
 
-  void generateThrowNoSuchMethod(Node diagnosticNode,
+  void generateThrowNoSuchMethod(ast.Node diagnosticNode,
                                  String methodName,
-                                 {Link<Node> argumentNodes,
+                                 {Link<ast.Node> argumentNodes,
                                   List<HInstruction> argumentValues,
                                   List<String> existingArguments}) {
     Element helper = backend.getThrowNoSuchMethod();
     Constant receiverConstant =
-        constantSystem.createString(new DartString.empty());
+        constantSystem.createString(new ast.DartString.empty());
     HInstruction receiver = graph.addConstant(receiverConstant, compiler);
-    DartString dartString = new DartString.literal(methodName);
+    ast.DartString dartString = new ast.DartString.literal(methodName);
     Constant nameConstant = constantSystem.createString(dartString);
     HInstruction name = graph.addConstant(nameConstant, compiler);
     if (argumentValues == null) {
@@ -4393,7 +4393,7 @@
       List<HInstruction> existingNames = <HInstruction>[];
       for (String name in existingArguments) {
         HInstruction nameConstant =
-            graph.addConstantString(new DartString.literal(name), compiler);
+            graph.addConstantString(new ast.DartString.literal(name), compiler);
         existingNames.add(nameConstant);
       }
       existingNamesList = buildLiteralList(existingNames);
@@ -4411,9 +4411,9 @@
    * method with a wrong number of arguments or mismatching named optional
    * arguments.
    */
-  void generateWrongArgumentCountError(Node diagnosticNode,
+  void generateWrongArgumentCountError(ast.Node diagnosticNode,
                                        FunctionElement function,
-                                       Link<Node> argumentNodes) {
+                                       Link<ast.Node> argumentNodes) {
     List<String> existingArguments = <String>[];
     FunctionSignature signature = function.computeSignature(compiler);
     signature.forEachParameter((Element parameter) {
@@ -4425,7 +4425,7 @@
                               existingArguments: existingArguments);
   }
 
-  visitNewExpression(NewExpression node) {
+  visitNewExpression(ast.NewExpression node) {
     Element element = elements[node.send];
     final bool isSymbolConstructor = element == compiler.symbolConstructor;
     if (!Elements.isErroneousElement(element)) {
@@ -4434,7 +4434,7 @@
     }
     if (Elements.isErroneousElement(element)) {
       ErroneousElement error = element;
-      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR.error) {
+      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
         generateThrowNoSuchMethod(node.send,
                                   getTargetName(error, 'constructor'),
                                   argumentNodes: node.send.arguments);
@@ -4455,10 +4455,10 @@
     }
   }
 
-  void pushInvokeDynamic(Node node,
+  void pushInvokeDynamic(ast.Node node,
                          Selector selector,
                          List<HInstruction> arguments,
-                         {Node location}) {
+                         {ast.Node location}) {
     if (location == null) location = node;
 
     // We prefer to not inline certain operations on indexables,
@@ -4531,7 +4531,7 @@
     }
   }
 
-  void pushInvokeStatic(Node location,
+  void pushInvokeStatic(ast.Node location,
                         Element element,
                         List<HInstruction> arguments,
                         [TypeMask type]) {
@@ -4591,9 +4591,9 @@
     return instruction;
   }
 
-  void handleComplexOperatorSend(SendSet node,
+  void handleComplexOperatorSend(ast.SendSet node,
                                  HInstruction receiver,
-                                 Link<Node> arguments) {
+                                 Link<ast.Node> arguments) {
     HInstruction rhs;
     if (node.isPrefix || node.isPostfix) {
       rhs = graph.addConstantInt(1, compiler);
@@ -4606,15 +4606,15 @@
                 elements.getOperatorSelectorInComplexSendSet(node), node);
   }
 
-  visitSendSet(SendSet node) {
+  visitSendSet(ast.SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
-      Identifier selector = node.selector;
+      ast.Identifier selector = node.selector;
       generateThrowNoSuchMethod(node, selector.source,
                                 argumentNodes: node.arguments);
       return;
     }
-    Operator op = node.assignmentOperator;
+    ast.Operator op = node.assignmentOperator;
     if (node.isSuperCall) {
       HInstruction result;
       List<HInstruction> setterInputs = <HInstruction>[];
@@ -4624,7 +4624,7 @@
       } else {
         Element getter = elements[node.selector];
         List<HInstruction> getterInputs = <HInstruction>[];
-        Link<Node> arguments = node.arguments;
+        Link<ast.Node> arguments = node.arguments;
         if (node.isIndex) {
           // If node is of the from [:super.foo[0] += 2:], the send has
           // two arguments: the index and the left hand side. We get
@@ -4675,7 +4675,7 @@
       } else {
         visit(node.receiver);
         HInstruction receiver = pop();
-        Link<Node> arguments = node.arguments;
+        Link<ast.Node> arguments = node.arguments;
         HInstruction index;
         if (node.isIndex) {
           visit(arguments.head);
@@ -4703,7 +4703,7 @@
         }
       }
     } else if ("=" == op.source) {
-      Link<Node> link = node.arguments;
+      Link<ast.Node> link = node.arguments;
       assert(!link.isEmpty && link.tail.isEmpty);
       if (Elements.isInstanceSend(node, elements)) {
         HInstruction receiver = generateInstanceSendReceiver(node);
@@ -4724,7 +4724,7 @@
       Element getter = elements[node.selector];
 
       if (!Elements.isUnresolved(getter) && getter.impliesType()) {
-        Identifier selector = node.selector;
+        ast.Identifier selector = node.selector;
         generateThrowNoSuchMethod(node, selector.source,
                                   argumentNodes: node.arguments);
         return;
@@ -4753,29 +4753,29 @@
     }
   }
 
-  void visitLiteralInt(LiteralInt node) {
+  void visitLiteralInt(ast.LiteralInt node) {
     stack.add(graph.addConstantInt(node.value, compiler));
   }
 
-  void visitLiteralDouble(LiteralDouble node) {
+  void visitLiteralDouble(ast.LiteralDouble node) {
     stack.add(graph.addConstantDouble(node.value, compiler));
   }
 
-  void visitLiteralBool(LiteralBool node) {
+  void visitLiteralBool(ast.LiteralBool node) {
     stack.add(graph.addConstantBool(node.value, compiler));
   }
 
-  void visitLiteralString(LiteralString node) {
+  void visitLiteralString(ast.LiteralString node) {
     stack.add(graph.addConstantString(node.dartString, compiler));
   }
 
-  void visitLiteralSymbol(LiteralSymbol node) {
+  void visitLiteralSymbol(ast.LiteralSymbol node) {
     stack.add(addConstant(node));
     compiler.enqueuer.codegen.registerConstSymbol(
         node.slowNameString, elements);
   }
 
-  void visitStringJuxtaposition(StringJuxtaposition node) {
+  void visitStringJuxtaposition(ast.StringJuxtaposition node) {
     if (!node.isInterpolation) {
       // This is a simple string with no interpolations.
       stack.add(graph.addConstantString(node.dartString, compiler));
@@ -4786,36 +4786,37 @@
     stack.add(stringBuilder.result);
   }
 
-  void visitLiteralNull(LiteralNull node) {
+  void visitLiteralNull(ast.LiteralNull node) {
     stack.add(graph.addConstantNull(compiler));
   }
 
-  visitNodeList(NodeList node) {
-    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
+  visitNodeList(ast.NodeList node) {
+    for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) {
       if (isAborted()) {
-        compiler.reportWarning(link.head, 'dead code');
+        compiler.reportWarning(link.head,
+            MessageKind.GENERIC, {'text': 'dead code'});
       } else {
         visit(link.head);
       }
     }
   }
 
-  void visitParenthesizedExpression(ParenthesizedExpression node) {
+  void visitParenthesizedExpression(ast.ParenthesizedExpression node) {
     visit(node.expression);
   }
 
-  visitOperator(Operator node) {
+  visitOperator(ast.Operator node) {
     // Operators are intercepted in their surrounding Send nodes.
     compiler.internalError('visitOperator should not be called', node: node);
   }
 
-  visitCascade(Cascade node) {
+  visitCascade(ast.Cascade node) {
     visit(node.expression);
     // Remove the result and reveal the duplicated receiver on the stack.
     pop();
   }
 
-  visitCascadeReceiver(CascadeReceiver node) {
+  visitCascadeReceiver(ast.CascadeReceiver node) {
     visit(node.expression);
     dup();
   }
@@ -4828,7 +4829,7 @@
     open(newBlock);
   }
 
-  visitRethrow(Rethrow node) {
+  visitRethrow(ast.Rethrow node) {
     HInstruction exception = rethrowableException;
     if (exception == null) {
       exception = graph.addConstantNull(compiler);
@@ -4839,7 +4840,7 @@
     closeAndGotoExit(new HThrow(exception, isRethrow: true));
   }
 
-  visitReturn(Return node) {
+  visitReturn(ast.Return node) {
     if (identical(node.getBeginToken().stringValue, 'native')) {
       native.handleSsaNative(this, node.expression);
       return;
@@ -4890,7 +4891,7 @@
     emitReturn(value, node);
   }
 
-  visitThrow(Throw node) {
+  visitThrow(ast.Throw node) {
     visitThrowExpression(node.expression);
     if (isReachable) {
       handleInTryStatement();
@@ -4899,29 +4900,29 @@
     }
   }
 
-  visitTypeAnnotation(TypeAnnotation node) {
+  visitTypeAnnotation(ast.TypeAnnotation node) {
     compiler.internalError('visiting type annotation in SSA builder',
                            node: node);
   }
 
-  visitVariableDefinitions(VariableDefinitions node) {
+  visitVariableDefinitions(ast.VariableDefinitions node) {
     assert(isReachable);
-    for (Link<Node> link = node.definitions.nodes;
+    for (Link<ast.Node> link = node.definitions.nodes;
          !link.isEmpty;
          link = link.tail) {
-      Node definition = link.head;
-      if (definition is Identifier) {
+      ast.Node definition = link.head;
+      if (definition is ast.Identifier) {
         HInstruction initialValue = graph.addConstantNull(compiler);
         localsHandler.updateLocal(elements[definition], initialValue);
       } else {
-        assert(definition is SendSet);
+        assert(definition is ast.SendSet);
         visitSendSet(definition);
         pop();  // Discard value.
       }
     }
   }
 
-  HInstruction setRtiIfNeeded(HInstruction object, Node node) {
+  HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) {
     InterfaceType type = elements.getType(node);
     if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
       return object;
@@ -4935,14 +4936,14 @@
     return callSetRuntimeTypeInfo(type.element, arguments, object);
   }
 
-  visitLiteralList(LiteralList node) {
+  visitLiteralList(ast.LiteralList node) {
     HInstruction instruction;
 
     if (node.isConst()) {
       instruction = addConstant(node);
     } else {
       List<HInstruction> inputs = <HInstruction>[];
-      for (Link<Node> link = node.elements.nodes;
+      for (Link<ast.Node> link = node.elements.nodes;
            !link.isEmpty;
            link = link.tail) {
         visit(link.head);
@@ -4959,34 +4960,34 @@
     stack.add(instruction);
   }
 
-  visitConditional(Conditional node) {
+  visitConditional(ast.Conditional node) {
     SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
     brancher.handleConditional(() => visit(node.condition),
                                () => visit(node.thenExpression),
                                () => visit(node.elseExpression));
   }
 
-  visitStringInterpolation(StringInterpolation node) {
+  visitStringInterpolation(ast.StringInterpolation node) {
     StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
     stringBuilder.visit(node);
     stack.add(stringBuilder.result);
   }
 
-  visitStringInterpolationPart(StringInterpolationPart node) {
+  visitStringInterpolationPart(ast.StringInterpolationPart node) {
     // The parts are iterated in visitStringInterpolation.
     compiler.internalError('visitStringInterpolation should not be called',
                            node: node);
   }
 
-  visitEmptyStatement(EmptyStatement node) {
+  visitEmptyStatement(ast.EmptyStatement node) {
     // Do nothing, empty statement.
   }
 
-  visitModifiers(Modifiers node) {
+  visitModifiers(ast.Modifiers node) {
     compiler.unimplemented('SsaFromAstMixin.visitModifiers', node: node);
   }
 
-  visitBreakStatement(BreakStatement node) {
+  visitBreakStatement(ast.BreakStatement node) {
     assert(!isAborted());
     handleInTryStatement();
     TargetElement target = elements[node];
@@ -5001,7 +5002,7 @@
     }
   }
 
-  visitContinueStatement(ContinueStatement node) {
+  visitContinueStatement(ast.ContinueStatement node) {
     handleInTryStatement();
     TargetElement target = elements[node];
     assert(target != null);
@@ -5025,13 +5026,13 @@
    * to distinguish the synthetized loop created for a switch statement with
    * continue statements from simple switch statements.
    */
-  JumpHandler createJumpHandler(Statement node, {bool isLoopJump}) {
+  JumpHandler createJumpHandler(ast.Statement node, {bool isLoopJump}) {
     TargetElement element = elements[node];
     if (element == null || !identical(element.statement, node)) {
       // No breaks or continues to this node.
       return new NullJumpHandler(compiler);
     }
-    if (isLoopJump && node is SwitchStatement) {
+    if (isLoopJump && node is ast.SwitchStatement) {
       // Create a special jump handler for loops created for switch statements
       // with continue statements.
       return new SwitchCaseJumpHandler(this, element, node);
@@ -5039,7 +5040,7 @@
     return new JumpHandler(this, element);
   }
 
-  visitForIn(ForIn node) {
+  visitForIn(ast.ForIn node) {
     // Generate a structure equivalent to:
     //   Iterator<E> $iter = <iterable>.iterator;
     //   while ($iter.moveNext()) {
@@ -5065,7 +5066,7 @@
       Selector call = elements.getCurrentSelector(node);
       pushInvokeDynamic(node, call, [iterator]);
 
-      Node identifier = node.declaredIdentifier;
+      ast.Node identifier = node.declaredIdentifier;
       Element variable = elements[identifier];
       Selector selector = elements.getSelector(identifier);
 
@@ -5090,14 +5091,14 @@
     handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
   }
 
-  visitLabel(Label node) {
+  visitLabel(ast.Label node) {
     compiler.internalError('SsaFromAstMixin.visitLabel', node: node);
   }
 
-  visitLabeledStatement(LabeledStatement node) {
-    Statement body = node.statement;
-    if (body is Loop
-        || body is SwitchStatement
+  visitLabeledStatement(ast.LabeledStatement node) {
+    ast.Statement body = node.statement;
+    if (body is ast.Loop
+        || body is ast.SwitchStatement
         || Elements.isUnusedLabel(node, elements)) {
       // Loops and switches handle their own labels.
       visit(body);
@@ -5136,13 +5137,13 @@
     handler.close();
   }
 
-  visitLiteralMap(LiteralMap node) {
+  visitLiteralMap(ast.LiteralMap node) {
     if (node.isConst()) {
       stack.add(addConstant(node));
       return;
     }
     List<HInstruction> inputs = <HInstruction>[];
-    for (Link<Node> link = node.entries.nodes;
+    for (Link<ast.Node> link = node.entries.nodes;
          !link.isEmpty;
          link = link.tail) {
       visit(link.head);
@@ -5156,21 +5157,21 @@
     stack.add(setRtiIfNeeded(pop(), node));
   }
 
-  visitLiteralMapEntry(LiteralMapEntry node) {
+  visitLiteralMapEntry(ast.LiteralMapEntry node) {
     visit(node.value);
     visit(node.key);
   }
 
-  visitNamedArgument(NamedArgument node) {
+  visitNamedArgument(ast.NamedArgument node) {
     visit(node.expression);
   }
 
-  Map<CaseMatch, Constant> buildSwitchCaseConstants(SwitchStatement node) {
-    Map<CaseMatch, Constant> constants = new Map<CaseMatch, Constant>();
-    for (SwitchCase switchCase in node.cases) {
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is CaseMatch) {
-          CaseMatch match = labelOrCase;
+  Map<ast.CaseMatch, Constant> buildSwitchCaseConstants(ast.SwitchStatement node) {
+    Map<ast.CaseMatch, Constant> constants = new Map<ast.CaseMatch, Constant>();
+    for (ast.SwitchCase switchCase in node.cases) {
+      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+        if (labelOrCase is ast.CaseMatch) {
+          ast.CaseMatch match = labelOrCase;
           Constant constant = getConstantForNode(match.expression);
           constants[labelOrCase] = constant;
         }
@@ -5179,18 +5180,18 @@
     return constants;
   }
 
-  visitSwitchStatement(SwitchStatement node) {
-    Map<CaseMatch,Constant> constants = buildSwitchCaseConstants(node);
+  visitSwitchStatement(ast.SwitchStatement node) {
+    Map<ast.CaseMatch,Constant> constants = buildSwitchCaseConstants(node);
 
     // The switch case indices must match those computed in
     // [SwitchCaseJumpHandler].
     bool hasContinue = false;
-    Map<SwitchCase, int> caseIndex = new Map<SwitchCase, int>();
+    Map<ast.SwitchCase, int> caseIndex = new Map<ast.SwitchCase, int>();
     int switchIndex = 1;
     bool hasDefault = false;
-    for (SwitchCase switchCase in node.cases) {
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        Node label = labelOrCase.asLabel();
+    for (ast.SwitchCase switchCase in node.cases) {
+      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+        ast.Node label = labelOrCase.asLabel();
         if (label != null) {
           LabelElement labelElement = elements[label];
           if (labelElement != null && labelElement.isContinueTarget) {
@@ -5217,26 +5218,26 @@
    * Builds a simple switch statement which does not handle uses of continue
    * statements to labeled switch cases.
    */
-  void buildSimpleSwitchStatement(SwitchStatement node,
-                                  Map<CaseMatch, Constant> constants) {
+  void buildSimpleSwitchStatement(ast.SwitchStatement node,
+                                  Map<ast.CaseMatch, Constant> constants) {
     JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false);
     HInstruction buildExpression() {
       visit(node.expression);
       return pop();
     }
-    Iterable<Constant> getConstants(SwitchCase switchCase) {
+    Iterable<Constant> getConstants(ast.SwitchCase switchCase) {
       List<Constant> constantList = <Constant>[];
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is CaseMatch) {
+      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+        if (labelOrCase is ast.CaseMatch) {
           constantList.add(constants[labelOrCase]);
         }
       }
       return constantList;
     }
-    bool isDefaultCase(SwitchCase switchCase) {
+    bool isDefaultCase(ast.SwitchCase switchCase) {
       return switchCase.isDefaultCase;
     }
-    void buildSwitchCase(SwitchCase node) {
+    void buildSwitchCase(ast.SwitchCase node) {
       visit(node.statements);
     }
     handleSwitch(node,
@@ -5253,9 +5254,9 @@
    * Builds a switch statement that can handle arbitrary uses of continue
    * statements to labeled switch cases.
    */
-  void buildComplexSwitchStatement(SwitchStatement node,
-                                   Map<CaseMatch, Constant> constants,
-                                   Map<SwitchCase, int> caseIndex,
+  void buildComplexSwitchStatement(ast.SwitchStatement node,
+                                   Map<ast.CaseMatch, Constant> constants,
+                                   Map<ast.SwitchCase, int> caseIndex,
                                    bool hasDefault) {
     // If the switch statement has switch cases targeted by continue
     // statements we create the following encoding:
@@ -5301,21 +5302,21 @@
       visit(node.expression);
       return pop();
     }
-    Iterable<Constant> getConstants(SwitchCase switchCase) {
+    Iterable<Constant> getConstants(ast.SwitchCase switchCase) {
       List<Constant> constantList = <Constant>[];
       if (switchCase != null) {
-        for (Node labelOrCase in switchCase.labelsAndCases) {
-          if (labelOrCase is CaseMatch) {
+        for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+          if (labelOrCase is ast.CaseMatch) {
             constantList.add(constants[labelOrCase]);
           }
         }
       }
       return constantList;
     }
-    bool isDefaultCase(SwitchCase switchCase) {
+    bool isDefaultCase(ast.SwitchCase switchCase) {
       return switchCase == null || switchCase.isDefaultCase;
     }
-    void buildSwitchCase(SwitchCase switchCase) {
+    void buildSwitchCase(ast.SwitchCase switchCase) {
       if (switchCase != null) {
         // Generate 'target = i; break;' for switch case i.
         int index = caseIndex[switchCase];
@@ -5344,10 +5345,10 @@
       HInstruction buildExpression() {
         return localsHandler.readLocal(switchTarget);
       }
-      Iterable<Constant> getConstants(SwitchCase switchCase) {
+      Iterable<Constant> getConstants(ast.SwitchCase switchCase) {
         return <Constant>[constantSystem.createInt(caseIndex[switchCase])];
       }
-      void buildSwitchCase(SwitchCase switchCase) {
+      void buildSwitchCase(ast.SwitchCase switchCase) {
         visit(switchCase.statements);
         if (!isAborted()) {
           // Ensure that we break the loop if the case falls through. (This
@@ -5393,21 +5394,21 @@
    *
    * [jumpHandler] is the [JumpHandler] for the created switch statement.
    * [buildExpression] creates the switch expression.
-   * [switchCases] must be either an [Iterable] of [SwitchCase] nodes or
-   *   a [Link] or a [NodeList] of [SwitchCase] nodes.
+   * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or
+   *   a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes.
    * [getConstants] returns the set of constants for a switch case.
    * [isDefaultCase] returns [:true:] if the provided switch case should be
    *   considered default for the created switch statement.
    * [buildSwitchCase] creates the statements for the switch case.
    */
-  void handleSwitch(Node errorNode,
+  void handleSwitch(ast.Node errorNode,
                     JumpHandler jumpHandler,
                     HInstruction buildExpression(),
                     var switchCases,
-                    Iterable<Constant> getConstants(SwitchCase switchCase),
-                    bool isDefaultCase(SwitchCase switchCase),
-                    void buildSwitchCase(SwitchCase switchCase)) {
-    Map<CaseMatch, Constant> constants = new Map<CaseMatch, Constant>();
+                    Iterable<Constant> getConstants(ast.SwitchCase switchCase),
+                    bool isDefaultCase(ast.SwitchCase switchCase),
+                    void buildSwitchCase(ast.SwitchCase switchCase)) {
+    Map<ast.CaseMatch, Constant> constants = new Map<ast.CaseMatch, Constant>();
 
     HBasicBlock expressionStart = openNewBlock();
     HInstruction expression = buildExpression();
@@ -5422,10 +5423,10 @@
     List<HStatementInformation> statements = <HStatementInformation>[];
     bool hasDefault = false;
     Element getFallThroughErrorElement = backend.getFallThroughError();
-    HasNextIterator<Node> caseIterator =
-        new HasNextIterator<Node>(switchCases.iterator);
+    HasNextIterator<ast.Node> caseIterator =
+        new HasNextIterator<ast.Node>(switchCases.iterator);
     while (caseIterator.hasNext) {
-      SwitchCase switchCase = caseIterator.next();
+      ast.SwitchCase switchCase = caseIterator.next();
       HBasicBlock block = graph.addNewBlock();
       for (Constant constant in getConstants(switchCase)) {
         HConstant hConstant = graph.addConstant(constant, compiler);
@@ -5520,15 +5521,15 @@
     jumpHandler.close();
   }
 
-  visitSwitchCase(SwitchCase node) {
+  visitSwitchCase(ast.SwitchCase node) {
     compiler.internalError('SsaFromAstMixin.visitSwitchCase');
   }
 
-  visitCaseMatch(CaseMatch node) {
+  visitCaseMatch(ast.CaseMatch node) {
     compiler.internalError('SsaFromAstMixin.visitCaseMatch');
   }
 
-  visitTryStatement(TryStatement node) {
+  visitTryStatement(ast.TryStatement node) {
     // Save the current locals. The catch block and the finally block
     // must not reuse the existing locals handler. None of the variables
     // that have been defined in the body-block will be used, but for
@@ -5576,9 +5577,9 @@
       pushInvokeStatic(node, backend.getExceptionUnwrapper(), [exception]);
       HInvokeStatic unwrappedException = pop();
       tryInstruction.exception = exception;
-      Link<Node> link = node.catchBlocks.nodes;
+      Link<ast.Node> link = node.catchBlocks.nodes;
 
-      void pushCondition(CatchBlock catchBlock) {
+      void pushCondition(ast.CatchBlock catchBlock) {
         if (catchBlock.onKeyword != null) {
           DartType type = elements.getType(catchBlock.type);
           if (type == null) {
@@ -5588,7 +5589,7 @@
               buildIsNode(catchBlock.type, type, unwrappedException);
           push(condition);
         } else {
-          VariableDefinitions declaration = catchBlock.formals.nodes.head;
+          ast.VariableDefinitions declaration = catchBlock.formals.nodes.head;
           HInstruction condition = null;
           if (declaration.type == null) {
             condition = graph.addConstantBool(true, compiler);
@@ -5609,13 +5610,13 @@
       }
 
       void visitThen() {
-        CatchBlock catchBlock = link.head;
+        ast.CatchBlock catchBlock = link.head;
         link = link.tail;
         if (catchBlock.exception != null) {
           localsHandler.updateLocal(elements[catchBlock.exception],
                                     unwrappedException);
         }
-        Node trace = catchBlock.trace;
+        ast.Node trace = catchBlock.trace;
         if (trace != null) {
           pushInvokeStatic(trace, backend.getTraceFromException(), [exception]);
           HInstruction traceInstruction = pop();
@@ -5628,14 +5629,14 @@
         if (link.isEmpty) {
           closeAndGotoExit(new HThrow(exception, isRethrow: true));
         } else {
-          CatchBlock newBlock = link.head;
+          ast.CatchBlock newBlock = link.head;
           handleIf(node,
                    () { pushCondition(newBlock); },
                    visitThen, visitElse);
         }
       }
 
-      CatchBlock firstBlock = link.head;
+      ast.CatchBlock firstBlock = link.head;
       handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse);
       if (!isAborted()) endCatchBlock = close(new HGoto());
 
@@ -5720,15 +5721,15 @@
     inTryStatement = oldInTryStatement;
   }
 
-  visitCatchBlock(CatchBlock node) {
+  visitCatchBlock(ast.CatchBlock node) {
     visit(node.block);
   }
 
-  visitTypedef(Typedef node) {
+  visitTypedef(ast.Typedef node) {
     compiler.unimplemented('SsaFromAstMixin.visitTypedef', node: node);
   }
 
-  visitTypeVariable(TypeVariable node) {
+  visitTypeVariable(ast.TypeVariable node) {
     compiler.internalError('SsaFromAstMixin.visitTypeVariable');
   }
 }
@@ -5737,9 +5738,9 @@
  * This class builds SSA nodes for functions represented in AST.
  */
 class SsaFromAstBuilder extends ResolvedVisitor with
-    SsaBuilderMixin<Node>,
+    SsaBuilderMixin<ast.Node>,
     SsaFromAstMixin,
-    SsaBuilderFields<Node> {
+    SsaBuilderFields<ast.Node> {
   final Compiler compiler;
   final JavaScriptBackend backend;
   final ConstantSystem constantSystem;
@@ -5771,7 +5772,7 @@
    * that should be inlined.
    */
   void enterInlinedMethod(FunctionElement function,
-                          Node _,
+                          ast.Node _,
                           List<HInstruction> compiledArguments) {
     SsaFromIrInliner irInliner;
     if (compiler.irBuilder.hasIr(function)) {
@@ -5804,7 +5805,7 @@
     }
   }
 
-  void emitReturn(HInstruction value, Node node) {
+  void emitReturn(HInstruction value, ast.Node node) {
     if (inliningStack.isEmpty) {
       closeAndGotoExit(attachPosition(new HReturn(value), node));
     } else {
@@ -5817,9 +5818,9 @@
  * This class inlines an AST function into an [SsaFromIrBuilder].
  */
 class SsaFromAstInliner extends ResolvedVisitor with
-    SsaBuilderMixin<Node>,
+    SsaBuilderMixin<ast.Node>,
     SsaFromAstMixin,
-    SsaBuilderDelegate<Node, IrNode> {
+    SsaBuilderDelegate<ast.Node, ir.Node> {
   final SsaFromIrBuilder builder;
 
   SsaFromAstInliner.internal(SsaFromIrBuilder builder)
@@ -5838,13 +5839,13 @@
   RuntimeTypes get rti => builder.backend.rti;
   CodegenWorkItem get work => builder.work;
 
-  void emitReturn(HInstruction value, Node node) {
+  void emitReturn(HInstruction value, ast.Node node) {
     IrInliningState state = inliningStack.last;
     builder.emitted[state.invokeNode] = value;
   }
 
   void enterInlinedMethod(FunctionElement function,
-                          Node currentNode,
+                          ast.Node currentNode,
                           List<HInstruction> compiledArguments) {
     // At this point we are inside the [SsaFromAstInliner] (inlining an AST
     // function into an IR builder), and we encounter a function invocation that
@@ -5855,13 +5856,13 @@
     // Since we are currently inlining an AST function, the invocation node is
     // an AST node. A synthetic [IrInlinedInvocationDummy] is added to the
     // [emitted] map to hold the result of the inlined function.
-    IrNode invokeNode = new IrInlinedInvocationDummy();
+    ir.Node invokeNode = new ir.InlinedInvocationDummy();
     builder.enterInlinedMethod(function, invokeNode, compiledArguments);
   }
 
   void leaveInlinedMethod() {
     IrInliningState state = inliningStack.last;
-    assert(state.invokeNode is IrInlinedInvocationDummy);
+    assert(state.invokeNode is ir.InlinedInvocationDummy);
     HInstruction result = builder.emitted.remove(state.invokeNode);
     if (result == null) {
       // When the inlined function is in AST form, it might not have an explicit
@@ -5886,9 +5887,9 @@
  * TODO(lrn): Consider whether to handle compile time constant int/boolean
  * expressions as well.
  */
-class StringBuilderVisitor extends Visitor {
+class StringBuilderVisitor extends ast.Visitor {
   final SsaFromAstMixin builder;
-  final Node diagnosticNode;
+  final ast.Node diagnosticNode;
 
   /**
    * The string value generated so far.
@@ -5897,15 +5898,15 @@
 
   StringBuilderVisitor(this.builder, this.diagnosticNode);
 
-  void visit(Node node) {
+  void visit(ast.Node node) {
     node.accept(this);
   }
 
-  visitNode(Node node) {
+  visitNode(ast.Node node) {
     builder.compiler.internalError('unexpected node', node: node);
   }
 
-  void visitExpression(Node node) {
+  void visitExpression(ast.Node node) {
     node.accept(builder);
     HInstruction expression = builder.pop();
     if (!expression.isConstantString()) {
@@ -5915,20 +5916,20 @@
     result = (result == null) ? expression : concat(result, expression);
   }
 
-  void visitStringInterpolation(StringInterpolation node) {
+  void visitStringInterpolation(ast.StringInterpolation node) {
     node.visitChildren(this);
   }
 
-  void visitStringInterpolationPart(StringInterpolationPart node) {
+  void visitStringInterpolationPart(ast.StringInterpolationPart node) {
     visit(node.expression);
     visit(node.string);
   }
 
-  void visitStringJuxtaposition(StringJuxtaposition node) {
+  void visitStringJuxtaposition(ast.StringJuxtaposition node) {
     node.visitChildren(this);
   }
 
-  void visitNodeList(NodeList node) {
+  void visitNodeList(ast.NodeList node) {
      node.visitChildren(this);
   }
 
@@ -5944,7 +5945,7 @@
  * This class visits the method that is a candidate for inlining and
  * finds whether it is too difficult to inline.
  */
-class InlineWeeder extends Visitor {
+class InlineWeeder extends ast.Visitor {
   // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
   static const INLINING_NODES_OUTSIDE_LOOP = 18;
   static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
@@ -5959,7 +5960,7 @@
 
   InlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes);
 
-  static bool canBeInlined(FunctionExpression functionExpression,
+  static bool canBeInlined(ast.FunctionExpression functionExpression,
                            int maxInliningNodes,
                            bool useMaxInliningNodes) {
     InlineWeeder weeder =
@@ -5979,11 +5980,11 @@
     }
   }
 
-  void visit(Node node) {
+  void visit(ast.Node node) {
     if (node != null) node.accept(this);
   }
 
-  void visitNode(Node node) {
+  void visitNode(ast.Node node) {
     if (!registerNode()) return;
     if (seenReturn) {
       tooDifficult = true;
@@ -5992,34 +5993,34 @@
     }
   }
 
-  void visitFunctionExpression(Node node) {
+  void visitFunctionExpression(ast.Node node) {
     if (!registerNode()) return;
     tooDifficult = true;
   }
 
-  void visitFunctionDeclaration(Node node) {
+  void visitFunctionDeclaration(ast.Node node) {
     if (!registerNode()) return;
     tooDifficult = true;
   }
 
-  void visitSend(Send node) {
+  void visitSend(ast.Send node) {
     if (!registerNode()) return;
     node.visitChildren(this);
   }
 
-  visitLoop(Node node) {
+  visitLoop(ast.Node node) {
     // It's actually not difficult to inline a method with a loop, but
     // our measurements show that it's currently better to not inline a
     // method that contains a loop.
     tooDifficult = true;
   }
 
-  void visitRethrow(Rethrow node) {
+  void visitRethrow(ast.Rethrow node) {
     if (!registerNode()) return;
     tooDifficult = true;
   }
 
-  void visitReturn(Return node) {
+  void visitReturn(ast.Return node) {
     if (!registerNode()) return;
     if (seenReturn
         || identical(node.getBeginToken().stringValue, 'native')
@@ -6031,12 +6032,12 @@
     seenReturn = true;
   }
 
-  void visitTryStatement(Node node) {
+  void visitTryStatement(ast.Node node) {
     if (!registerNode()) return;
     tooDifficult = true;
   }
 
-  void visitThrow(Throw node) {
+  void visitThrow(ast.Throw node) {
     if (!registerNode()) return;
     // For now, we don't want to handle throw after a return even if
     // it is in an "if".
@@ -6075,7 +6076,7 @@
 }
 
 class IrInliningState extends InliningState {
-  final IrNode invokeNode;
+  final ir.Node invokeNode;
   final SsaFromAstInliner astInliner;
 
   IrInliningState(FunctionElement function, this.invokeNode, this.astInliner)
@@ -6094,7 +6095,7 @@
 
 class SsaBranchBuilder {
   final SsaFromAstMixin builder;
-  final Node diagnosticNode;
+  final ast.Node diagnosticNode;
 
   SsaBranchBuilder(this.builder, [this.diagnosticNode]);
 
@@ -6236,7 +6237,7 @@
     builder.stack.add(result);
   }
 
-  void handleLogicalAndOrWithLeftNode(Node left,
+  void handleLogicalAndOrWithLeftNode(ast.Node left,
                                       void visitRight(),
                                       {bool isAnd}) {
     // This method is similar to [handleLogicalAndOr] but optimizes the case
@@ -6253,13 +6254,13 @@
     //   }
     //   result = phi(t3, false);
 
-    Send send = left.asSend();
+    ast.Send send = left.asSend();
     if (send != null &&
         (isAnd ? send.isLogicalAnd : send.isLogicalOr)) {
-      Node newLeft = send.receiver;
-      Link<Node> link = send.argumentsNode.nodes;
+      ast.Node newLeft = send.receiver;
+      Link<ast.Node> link = send.argumentsNode.nodes;
       assert(link.tail.isEmpty);
-      Node middle = link.head;
+      ast.Node middle = link.head;
       handleLogicalAndOrWithLeftNode(
           newLeft,
           () => handleLogicalAndOrWithLeftNode(middle, visitRight,
@@ -6363,7 +6364,7 @@
 
     Link<DartType> namedParameterTypes = type.namedParameterTypes;
     for (String name in type.namedParameters) {
-      DartString dartString = new DartString.literal(name);
+      ast.DartString dartString = new ast.DartString.literal(name);
       inputs.add(
           builder.graph.addConstantString(dartString, builder.compiler));
       namedParameterTypes.head.accept(this, builder);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index ad93039..c0835f7 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -20,13 +20,13 @@
     // was on a wrapping node.
     SourceFile sourceFile = sourceFileOfElement(element);
     if (compiler.irBuilder.hasIr(element)) {
-      IrFunction function = compiler.irBuilder.getIr(element);
+      ir.Function function = compiler.irBuilder.getIr(element);
       node.sourcePosition = new OffsetSourceFileLocation(
           sourceFile, function.offset, function.sourceName);
       node.endSourcePosition = new OffsetSourceFileLocation(
           sourceFile, function.endOffset);
     } else {
-      Node expression = element.implementation.parseNode(backend.compiler);
+      ast.Node expression = element.implementation.parseNode(backend.compiler);
       Token beginToken;
       Token endToken;
       if (expression == null) {
@@ -445,7 +445,7 @@
     if (len == 0) return new js.EmptyStatement();
     if (len == 1) {
       js.Statement result = block.statements[0];
-      if (result is Block) return unwrapStatement(result);
+      if (result is ast.Block) return unwrapStatement(result);
       return result;
     }
     return block;
@@ -1354,7 +1354,7 @@
     } else {
       TargetElement target = node.target;
       if (!tryCallAction(continueAction, target)) {
-        if (target.statement is SwitchStatement) {
+        if (target.statement is ast.SwitchStatement) {
           pushStatement(new js.Continue(
               backend.namer.implicitContinueLabelName(target)), node);
         } else {
@@ -1803,7 +1803,7 @@
 
       HInstruction left = relational.left;
       HInstruction right = relational.right;
-      if (left.isString(compiler) && right.isString(compiler)) {
+      if (left.isStringOrNull(compiler) && right.isStringOrNull(compiler)) {
         return true;
       }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
index f5aa966..85f2ce5 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
@@ -50,15 +50,15 @@
  * [SsaFromIrInliner].
  */
 abstract class SsaFromIrMixin
-    implements IrNodesVisitor, SsaBuilderMixin<IrNode> {
+    implements ir.NodesVisitor, SsaBuilderMixin<ir.Node> {
   /**
    * Maps IR expressions to the generated [HInstruction]. Because the IR is
-   * in an SSA form, the arguments of an [IrNode] have already been visited
+   * in an SSA form, the arguments of an [ir.Node] have already been visited
    * prior to the node. This map is used to obtain the corresponding generated
    * SSA node.
    */
-  final Map<IrExpression, HInstruction> emitted =
-      new Map<IrExpression, HInstruction>();
+  final Map<ir.Expression, HInstruction> emitted =
+      new Map<ir.Expression, HInstruction>();
 
   /**
    * This method sets up the state of the IR visitor for inlining an invocation
@@ -78,20 +78,20 @@
   void visitInlinedFunction(FunctionElement function) {
     assert(compiler.irBuilder.hasIr(function));
     potentiallyCheckInlinedParameterTypes(function);
-    IrFunction functionNode = compiler.irBuilder.getIr(function);
+    ir.Function functionNode = compiler.irBuilder.getIr(function);
     visitAll(functionNode.statements);
   }
 
-  void addExpression(IrExpression irNode, HInstruction ssaNode) {
+  void addExpression(ir.Expression irNode, HInstruction ssaNode) {
     current.add(emitted[irNode] = ssaNode);
   }
 
-  HInstruction attachPosition(HInstruction target, IrNode node) {
+  HInstruction attachPosition(HInstruction target, ir.Node node) {
     target.sourcePosition = sourceFileLocation(node);
     return target;
   }
 
-  SourceFileLocation sourceFileLocation(IrNode node) {
+  SourceFileLocation sourceFileLocation(ir.Node node) {
     SourceFile sourceFile = currentSourceFile();
     SourceFileLocation location =
         new OffsetSourceFileLocation(sourceFile, node.offset, node.sourceName);
@@ -104,16 +104,16 @@
     assert(!compiler.enableTypeAssertions);
   }
 
-  bool providedArgumentsKnownToBeComplete(IrNode currentNode) {
+  bool providedArgumentsKnownToBeComplete(ir.Node currentNode) {
     // See comment in [SsaFromAstBuilder.providedArgumentsKnownToBeComplete].
     return false;
   }
 
-  List<HInstruction> toInstructionList(List<IrNode> nodes) {
+  List<HInstruction> toInstructionList(List<ir.Node> nodes) {
     return nodes.map((e) => emitted[e]).toList(growable: false);
   }
 
-  void addInvokeStatic(IrInvokeStatic node,
+  void addInvokeStatic(ir.InvokeStatic node,
                        FunctionElement function,
                        List<HInstruction> arguments,
                        [TypeMask type]) {
@@ -142,21 +142,21 @@
     addExpression(node, attachPosition(instruction, node));
   }
 
-  void visitIrConstant(IrConstant node) {
+  void visitConstant(ir.Constant node) {
     emitted[node] = graph.addConstant(node.value, compiler);
   }
 
-  void visitIrInvokeStatic(IrInvokeStatic node) {
+  void visitInvokeStatic(ir.InvokeStatic node) {
     FunctionElement function = node.target;
     List<HInstruction> arguments = toInstructionList(node.arguments);
     addInvokeStatic(node, function, arguments);
   }
 
-  void visitIrNode(IrNode node) {
+  void visitNode(ir.Node node) {
     compiler.internalError('Cannot build SSA from IR for $node');
   }
 
-  void visitIrReturn(IrReturn node) {
+  void visitReturn(ir.Return node) {
     HInstruction value = emitted[node.value];
     // TODO(lry): add code for dynamic type check.
     // value = potentiallyCheckType(value, returnType);
@@ -169,10 +169,10 @@
  * [SsaBuilderMixin] to share functionality with the [SsaFromAstBuilder] that
  * creates SSA nodes from trees.
  */
-class SsaFromIrBuilder extends IrNodesVisitor with
-    SsaBuilderMixin<IrNode>,
+class SsaFromIrBuilder extends ir.NodesVisitor with
+    SsaBuilderMixin<ir.Node>,
     SsaFromIrMixin,
-    SsaBuilderFields<IrNode> {
+    SsaBuilderFields<ir.Node> {
   final Compiler compiler;
   final JavaScriptBackend backend;
   final CodegenWorkItem work;
@@ -200,14 +200,14 @@
     close(new HGoto()).addSuccessor(block);
     open(block);
 
-    IrFunction function = compiler.irBuilder.getIr(functionElement);
+    ir.Function function = compiler.irBuilder.getIr(functionElement);
     visitAll(function.statements);
     if (!isAborted()) closeAndGotoExit(new HGoto());
     graph.finalize();
     return graph;
   }
 
-  void emitReturn(HInstruction value, IrReturn node) {
+  void emitReturn(HInstruction value, ir.Return node) {
     if (inliningStack.isEmpty) {
       closeAndGotoExit(attachPosition(new HReturn(value), node));
     } else {
@@ -225,7 +225,7 @@
    * that should be inlined.
    */
   void enterInlinedMethod(FunctionElement function,
-                          IrNode callNode,
+                          ir.Node callNode,
                           List<HInstruction> compiledArguments) {
     bool hasIr = compiler.irBuilder.hasIr(function);
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart
index e88f130..ff7ba5b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart
@@ -5,13 +5,13 @@
 part of ssa;
 
 /**
- * This class implements an [IrNodesVisitor] that inlines a function represented
+ * This class implements an [ir.NodesVisitor] that inlines a function represented
  * as IR into an [SsaFromAstBuilder].
  */
-class SsaFromIrInliner extends IrNodesVisitor with
-    SsaBuilderMixin<IrNode>,
+class SsaFromIrInliner extends ir.NodesVisitor with
+    SsaBuilderMixin<ir.Node>,
     SsaFromIrMixin,
-    SsaBuilderDelegate<IrNode, Node> {
+    SsaBuilderDelegate<ir.Node, ast.Node> {
   final SsaFromAstBuilder builder;
 
   SsaFromIrInliner.internal(this.builder);
@@ -24,14 +24,14 @@
     return irInliner;
   }
 
-  final List<IrExpression> inlinedCalls = <IrExpression>[];
+  final List<ir.Expression> inlinedCalls = <ir.Expression>[];
 
   /**
    * This function is invoked when we are currently inlining an IR function
    * into an AST builder, and we encounter an infocation that is inlined.
    */
   void enterInlinedMethod(FunctionElement function,
-                          IrNode callNode,
+                          ir.Node callNode,
                           List<HInstruction> compiledArguments) {
     assert(callNode != null);
     inlinedCalls.add(callNode);
@@ -49,13 +49,13 @@
     builder.doInline(function);
   }
 
-  void emitReturn(HInstruction value, IrReturn node) {
+  void emitReturn(HInstruction value, ir.Return node) {
     builder.localsHandler.updateLocal(builder.returnElement, value);
   }
 }
 
-class IrInlineWeeder extends IrNodesVisitor {
-  static bool canBeInlined(IrFunction irFunction,
+class IrInlineWeeder extends ir.NodesVisitor {
+  static bool canBeInlined(ir.Function irFunction,
                            int maxInliningNodes,
                            bool useMaxInliningNodes) {
     IrInlineWeeder weeder =
@@ -83,19 +83,19 @@
     }
   }
 
-  void visitIrNode(IrNode node) {
+  void visitNode(ir.Node node) {
     if (!registerNode()) return;
     if (seenReturn) {
       tooDifficult = true;
     }
   }
 
-  void visitIrReturn(IrReturn node) {
-    visitIrNode(node);
+  void visitReturn(ir.Return node) {
+    visitNode(node);
     seenReturn = true;
   }
 
-  void visitIrFunction(IrFunction node) {
+  void visitFunction(ir.Function node) {
     tooDifficult = true;
   }
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 441d653..f2ae1a5 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -288,7 +288,7 @@
             // TODO(15933): Make automatically generated property extraction
             // closures work with the dummy receiver optimization.
             if (!invoke.selector.isGetter()) {
-              Constant constant = new DummyReceiverConstant(
+              Constant constant = new DummyConstant(
                   receiverArgument.instructionType);
               HConstant dummy = graph.addConstant(constant, compiler);
               receiverArgument.usedBy.remove(invoke);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index ea74d96..accb1f7a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -191,7 +191,7 @@
         compiler.backend.constantSystem.createDouble(d), compiler);
   }
 
-  HConstant addConstantString(DartString str,
+  HConstant addConstantString(ast.DartString str,
                               Compiler compiler) {
     return addConstant(
         compiler.backend.constantSystem.createString(str),
@@ -968,6 +968,11 @@
   }
 
   bool isString(Compiler compiler) {
+    return instructionType.containsOnlyString(compiler)
+        && !instructionType.isNullable;
+  }
+
+  bool isStringOrNull(Compiler compiler) {
     return instructionType.containsOnlyString(compiler);
   }
 
@@ -2458,7 +2463,7 @@
 }
 
 class HStringConcat extends HInstruction {
-  final Node node;
+  final ast.Node node;
   HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type)
       : super(<HInstruction>[left, right], type) {
     // TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
@@ -2479,7 +2484,7 @@
  * into a String value.
  */
 class HStringify extends HInstruction {
-  final Node node;
+  final ast.Node node;
   HStringify(HInstruction input, this.node, TypeMask type)
       : super(<HInstruction>[input], type) {
     sideEffects.setAllSideEffects();
@@ -2663,14 +2668,14 @@
     visitor.visitLabeledBlockInfo(this);
 }
 
-class LoopTypeVisitor extends Visitor {
+class LoopTypeVisitor extends ast.Visitor {
   const LoopTypeVisitor();
-  int visitNode(Node node) => HLoopBlockInformation.NOT_A_LOOP;
-  int visitWhile(While node) => HLoopBlockInformation.WHILE_LOOP;
-  int visitFor(For node) => HLoopBlockInformation.FOR_LOOP;
-  int visitDoWhile(DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
-  int visitForIn(ForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
-  int visitSwitchStatement(SwitchStatement node) =>
+  int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
+  int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
+  int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
+  int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
+  int visitForIn(ast.ForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
+  int visitSwitchStatement(ast.SwitchStatement node) =>
       HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
 }
 
@@ -2725,7 +2730,7 @@
     return body.end;
   }
 
-  static int loopType(Node node) {
+  static int loopType(ast.Node node) {
     return node.accept(const LoopTypeVisitor());
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 8116646..bea5bd5 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -263,10 +263,10 @@
             target = backend.jsArrayAdd;
           }
         }
-      } else if (input.isString(compiler)) {
+      } else if (input.isStringOrNull(compiler)) {
         if (selector.applies(backend.jsStringSplit, compiler)) {
           HInstruction argument = node.inputs[2];
-          if (argument.isString(compiler) && !argument.canBeNull()) {
+          if (argument.isString(compiler)) {
             target = backend.jsStringSplit;
           }
         } else if (selector.applies(backend.jsStringOperatorAdd, compiler)) {
@@ -274,7 +274,6 @@
           // make sure the receiver and the argument are not null.
           HInstruction argument = node.inputs[2];
           if (argument.isString(compiler)
-              && !argument.canBeNull()
               && !input.canBeNull()) {
             target = backend.jsStringOperatorAdd;
           }
@@ -702,7 +701,7 @@
   }
 
   HInstruction directFieldGet(HInstruction receiver, Element field) {
-    Modifiers modifiers = field.modifiers;
+    ast.Modifiers modifiers = field.modifiers;
     bool isAssignable = !compiler.world.fieldNeverChanges(field);
 
     TypeMask type;
@@ -784,7 +783,7 @@
 
     HInstruction folded = graph.addConstant(
         constantSystem.createString(
-            new DartString.concat(leftString.value, rightString.value)),
+            new ast.DartString.concat(leftString.value, rightString.value)),
         compiler);
     if (prefix == null) return folded;
     return new HStringConcat(prefix, folded, node.node, backend.stringType);
@@ -792,7 +791,7 @@
 
   HInstruction visitStringify(HStringify node) {
     HInstruction input = node.inputs[0];
-    if (input.isString(compiler) && !input.canBeNull()) return input;
+    if (input.isString(compiler)) return input;
     if (input.isConstant()) {
       HConstant constant = input;
       if (!constant.constant.isPrimitive()) return node;
@@ -894,9 +893,12 @@
 
   HInstruction zapInstructionCache;
   HInstruction get zapInstruction {
-    return (zapInstructionCache == null)
-        ? zapInstructionCache = analyzer.graph.addConstantInt(0, compiler)
-        : zapInstructionCache;
+    if (zapInstructionCache == null) {
+      // A constant with no type does not pollute types at phi nodes.
+      Constant constant = new DummyConstant(const TypeMask.nonNullEmpty());
+      zapInstructionCache = analyzer.graph.addConstant(constant, compiler);
+    }
+    return zapInstructionCache;
   }
 
   /// Returns whether the next throwing instruction that may have side
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index 76a6ade..41034258 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -15,8 +15,8 @@
 import '../elements/elements.dart';
 import '../js_backend/js_backend.dart';
 import '../native_handler.dart' as native;
-import '../tree/tree.dart';
-import '../ir/ir_nodes.dart';
+import '../tree/tree.dart' as ast;
+import '../ir/ir_nodes.dart' as ir;
 import '../types/types.dart';
 import '../universe/universe.dart';
 import '../util/util.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index 0fe6c66..37731ba 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -449,7 +449,7 @@
   }
 
   String visitStringify(HStringify node) {
-    return "Stringify: ${node.inputs[0]}";
+    return "Stringify ${temporaryId(node.inputs[0])}";
   }
 
   String visitSubtract(HSubtract node) => handleInvokeBinary(node, '-');
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 4df5830..c88e521 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -30,7 +30,8 @@
         compiler);
   }
 
-  static TypeMask inferredForNode(Element owner, Node node, Compiler compiler) {
+  static TypeMask inferredForNode(Element owner, ast.Node node,
+                                  Compiler compiler) {
     return fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfNode(owner, node),
         compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 82b32ba..716fb51 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -126,6 +126,13 @@
   }
 
   TypeMask visitNegate(HNegate instruction) {
+    HInstruction operand = instruction.operand;
+    // We have integer subclasses that represent ranges, so widen any int
+    // subclass to full integer.
+    if (operand.isInteger(compiler)) {
+      JavaScriptBackend backend = compiler.backend;
+      return backend.intType;
+    }
     return instruction.operand.instructionType;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/tree_validator.dart b/sdk/lib/_internal/compiler/implementation/tree_validator.dart
index 5204ed6..399ad60 100644
--- a/sdk/lib/_internal/compiler/implementation/tree_validator.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree_validator.dart
@@ -16,7 +16,7 @@
     void report(node, message) {
       final error = new InvalidNodeError(node, message);
       errors.add(error);
-      compiler.reportWarning(node, message);
+      compiler.reportWarning(node, MessageKind.GENERIC, {'text': message});
     };
     final validator = new ValidatorVisitor(report);
     tree.accept(new TraversingVisitor(validator));
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 53c5b75..fd5c3f5 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -13,8 +13,11 @@
     compiler.withCurrentElement(element, () {
       measure(() {
         Node tree = element.parseNode(compiler);
-        Visitor visitor =
+        TypeCheckerVisitor visitor =
             new TypeCheckerVisitor(compiler, elements, compiler.types);
+        if (element.isField()) {
+          visitor.analyzingInitializer = true;
+        }
         tree.accept(visitor);
       });
     });
@@ -62,13 +65,13 @@
 
 /// An access of a instance member.
 class MemberAccess extends ElementAccess {
-  final InterfaceTypeMember member;
+  final MemberSignature member;
 
-  MemberAccess(InterfaceTypeMember this.member);
+  MemberAccess(MemberSignature this.member);
 
-  Element get element => member.element;
+  Element get element => member.declarations.first.element;
 
-  DartType computeType(Compiler compiler) => member.computeType(compiler);
+  DartType computeType(Compiler compiler) => member.type;
 
   String toString() => 'MemberAccess($member)';
 }
@@ -231,6 +234,8 @@
 
   Link<DartType> cascadeTypes = const Link<DartType>();
 
+  bool analyzingInitializer = false;
+
   DartType intType;
   DartType doubleType;
   DartType boolType;
@@ -314,13 +319,14 @@
 
   LibraryElement get currentLibrary => elements.currentElement.getLibrary();
 
-  reportTypeWarning(Node node, MessageKind kind, [Map arguments = const {}]) {
-    compiler.reportWarning(
-        node, new TypeWarning(kind, arguments, compiler.terseDiagnostics));
+  reportTypeWarning(Spannable spannable, MessageKind kind,
+                    [Map arguments = const {}]) {
+    compiler.reportWarning(spannable, kind, arguments);
   }
 
-  reportTypeInfo(Spannable node, MessageKind kind, [Map arguments = const {}]) {
-    compiler.reportInfo(node, kind, arguments);
+  reportTypeInfo(Spannable spannable, MessageKind kind,
+                 [Map arguments = const {}]) {
+    compiler.reportInfo(spannable, kind, arguments);
   }
 
   reportTypePromotionHint(TypePromotion typePromotion) {
@@ -358,7 +364,9 @@
     return node != null ? analyze(node) : defaultValue;
   }
 
-  DartType analyze(Node node) {
+  /// If [inInitializer] is true, assignment should be interpreted as write to
+  /// a field and not to a setter.
+  DartType analyze(Node node, {bool inInitializer: false}) {
     if (node == null) {
       final String error = 'unexpected node: null';
       if (lastSeenNode != null) {
@@ -369,7 +377,10 @@
     } else {
       lastSeenNode = node;
     }
+    bool previouslyInitializer = analyzingInitializer;
+    analyzingInitializer = inInitializer;
     DartType result = node.accept(this);
+    analyzingInitializer = previouslyInitializer;
     if (result == null) {
       compiler.internalError('type is null', node: node);
     }
@@ -466,14 +477,14 @@
    * return value of type [to].  If `isConst == true`, an error is emitted in
    * checked mode, otherwise a warning is issued.
    */
-  bool checkAssignable(Node node, DartType from, DartType to,
+  bool checkAssignable(Spannable spannable, DartType from, DartType to,
                        {bool isConst: false}) {
     if (!types.isAssignable(from, to)) {
       if (compiler.enableTypeAssertions && isConst) {
-        compiler.reportError(node, MessageKind.NOT_ASSIGNABLE.error,
+        compiler.reportError(spannable, MessageKind.NOT_ASSIGNABLE,
                              {'fromType': from, 'toType': to});
       } else {
-        reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE.warning,
+        reportTypeWarning(spannable, MessageKind.NOT_ASSIGNABLE,
                           {'fromType': from, 'toType': to});
       }
       return false;
@@ -561,13 +572,13 @@
       element.functionSignature.forEachParameter((Element parameter) {
         if (parameter.isFieldParameter()) {
           FieldParameterElement fieldParameter = parameter;
-          checkAssignable(parameter.parseNode(compiler),
+          checkAssignable(parameter,
               parameter.computeType(compiler),
               fieldParameter.fieldElement.computeType(compiler));
         }
       });
       if (node.initializers != null) {
-        analyze(node.initializers);
+        analyze(node.initializers, inInitializer: true);
       }
     } else {
       FunctionType functionType = element.computeType(compiler);
@@ -635,11 +646,15 @@
   }
 
   ElementAccess lookupMember(Node node, DartType receiverType, String name,
-                             MemberKind memberKind, Element receiverElement) {
+                             MemberKind memberKind, Element receiverElement,
+                             {bool lookupClassMember: false}) {
     if (receiverType.treatAsDynamic) {
       return const DynamicAccess();
     }
 
+    Name memberName = new Name(name, currentLibrary,
+        isSetter: memberKind == MemberKind.SETTER);
+
     // Compute the unaliased type of the first non type variable bound of
     // [type].
     DartType computeUnaliasedBound(DartType type) {
@@ -666,15 +681,23 @@
       return type;
     }
 
+    // Lookup the class or interface member [name] in [interface].
+    MemberSignature lookupMemberSignature(Name name, InterfaceType interface) {
+      MembersCreator.computeClassMembers(compiler, interface.element);
+      return lookupClassMember || analyzingInitializer
+          ? interface.lookupClassMember(name)
+          : interface.lookupInterfaceMember(name);
+    }
+
     // Compute the access of [name] on [type]. This function takes the special
     // 'call' method into account.
-    ElementAccess getAccess(DartType unaliasedBound, InterfaceType interface) {
-      InterfaceTypeMember member = interface.lookupMember(name,
-          isSetter: identical(memberKind, MemberKind.SETTER));
+    ElementAccess getAccess(Name name,
+                            DartType unaliasedBound, InterfaceType interface) {
+      MemberSignature member = lookupMemberSignature(memberName, interface);
       if (member != null) {
         return new MemberAccess(member);
       }
-      if (name == 'call' && memberKind != MemberKind.SETTER) {
+      if (name == const PublicName('call')) {
         if (unaliasedBound.kind == TypeKind.FUNCTION) {
           // This is an access the implicit 'call' method of a function type.
           return new FunctionCallAccess(receiverElement, unaliasedBound);
@@ -691,9 +714,8 @@
 
     DartType unaliasedBound = computeUnaliasedBound(receiverType);
     InterfaceType interface = computeInterfaceType(unaliasedBound);
-    ElementAccess access = getAccess(unaliasedBound, interface);
+    ElementAccess access = getAccess(memberName, unaliasedBound, interface);
     if (access != null) {
-      checkPrivateAccess(node, access.element, name);
       return access;
     }
     if (receiverElement != null &&
@@ -705,7 +727,7 @@
           if (!typePromotion.isValid) {
             DartType unaliasedBound = computeUnaliasedBound(typePromotion.type);
             InterfaceType interface = computeInterfaceType(unaliasedBound);
-            if (getAccess(unaliasedBound, interface) != null) {
+            if (getAccess(memberName, unaliasedBound, interface) != null) {
               reportTypePromotionHint(typePromotion);
             }
           }
@@ -714,23 +736,52 @@
       }
     }
     if (!interface.element.isProxy) {
-      switch (memberKind) {
-        case MemberKind.METHOD:
-          reportTypeWarning(node, MessageKind.METHOD_NOT_FOUND,
-              {'className': receiverType.name, 'memberName': name});
-          break;
-        case MemberKind.OPERATOR:
-          reportTypeWarning(node, MessageKind.OPERATOR_NOT_FOUND,
-              {'className': receiverType.name, 'memberName': name});
-          break;
-        case MemberKind.GETTER:
-          reportTypeWarning(node, MessageKind.MEMBER_NOT_FOUND.warning,
-              {'className': receiverType.name, 'memberName': name});
-          break;
-        case MemberKind.SETTER:
-          reportTypeWarning(node, MessageKind.PROPERTY_NOT_FOUND,
-              {'className': receiverType.name, 'memberName': name});
-          break;
+      bool foundPrivateMember = false;
+      if (memberName.isPrivate) {
+        void findPrivateMember(MemberSignature member) {
+          if (memberName.isSimilarTo(member.name)) {
+            PrivateName privateName = member.name;
+            reportTypeWarning(
+                 node,
+                 MessageKind.PRIVATE_ACCESS,
+                 {'name': name,
+                  'libraryName': privateName.library.getLibraryOrScriptName()});
+            foundPrivateMember = true;
+          }
+        }
+        if (lookupClassMember) {
+          interface.element.forEachClassMember(findPrivateMember);
+        } else {
+          interface.element.forEachInterfaceMember(findPrivateMember);
+        }
+
+      }
+      if (!foundPrivateMember) {
+        switch (memberKind) {
+          case MemberKind.METHOD:
+            reportTypeWarning(node, MessageKind.METHOD_NOT_FOUND,
+                {'className': receiverType.name, 'memberName': name});
+            break;
+          case MemberKind.OPERATOR:
+            reportTypeWarning(node, MessageKind.OPERATOR_NOT_FOUND,
+                {'className': receiverType.name, 'memberName': name});
+            break;
+          case MemberKind.GETTER:
+            if (lookupMemberSignature(memberName.setter, interface) != null) {
+              // A setter is present so warn explicitly about the missing
+              // getter.
+              reportTypeWarning(node, MessageKind.GETTER_NOT_FOUND,
+                  {'className': receiverType.name, 'memberName': name});
+            } else {
+              reportTypeWarning(node, MessageKind.MEMBER_NOT_FOUND,
+                  {'className': receiverType.name, 'memberName': name});
+            }
+            break;
+          case MemberKind.SETTER:
+            reportTypeWarning(node, MessageKind.SETTER_NOT_FOUND,
+                {'className': receiverType.name, 'memberName': name});
+            break;
+        }
       }
     }
     return const DynamicAccess();
@@ -738,7 +789,8 @@
 
   DartType lookupMemberType(Node node, DartType type, String name,
                             MemberKind memberKind) {
-    return lookupMember(node, type, name, memberKind, null).computeType(compiler);
+    return lookupMember(node, type, name, memberKind, null)
+        .computeType(compiler);
   }
 
   void analyzeArguments(Send send, Element element, DartType type,
@@ -865,7 +917,8 @@
    * [element] provided for [node] by the resolver.
    */
   ElementAccess computeAccess(Send node, String name, Element element,
-                              MemberKind memberKind) {
+                              MemberKind memberKind,
+                              {bool lookupClassMember: false}) {
     if (element != null && element.isErroneous()) {
       // An error has already been reported for this node.
       return const DynamicAccess();
@@ -886,7 +939,9 @@
       }
       TypeKind receiverKind = receiverType.kind;
       return lookupMember(node, receiverType, name, memberKind,
-          elements[node.receiver]);
+          elements[node.receiver],
+          lookupClassMember: lookupClassMember ||
+              element != null && element.modifiers.isStatic());
     } else {
       return computeResolvedAccess(node, name, element, memberKind);
     }
@@ -915,8 +970,9 @@
       }
       return createResolvedAccess(node, name, element);
     } else if (element.isMember()) {
-      // foo() where foo is an instance member.
-      return lookupMember(node, thisType, name, memberKind, null);
+      // foo() where foo is a member.
+      return lookupMember(node, thisType, name, memberKind, null,
+          lookupClassMember: element.modifiers.isStatic());
     } else if (element.isFunction()) {
       // foo() where foo is a method in the same class.
       return createResolvedAccess(node, name, element);
@@ -955,9 +1011,11 @@
    * [element] provided for [node] by the resolver.
    */
   DartType computeAccessType(Send node, String name, Element element,
-                             MemberKind memberKind) {
+                             MemberKind memberKind,
+                             {bool lookupClassMember: false}) {
     DartType type =
-        computeAccess(node, name, element, memberKind).computeType(compiler);
+        computeAccess(node, name, element, memberKind,
+            lookupClassMember: lookupClassMember).computeType(compiler);
     if (type == null) {
       compiler.internalError('type is null on access of $name on $node',
                              node: node);
@@ -1008,6 +1066,7 @@
       if (node.receiver != null) {
         receiverType = analyze(node.receiver);
       } else if (node.selector.isSuper()) {
+        // TODO(johnniwinther): Lookup super-member in class members.
         receiverType = superType;
       } else {
         assert(node.selector.isThis());
@@ -1310,8 +1369,18 @@
         return value;
       } else {
         // target = value
-        DartType target = computeAccessType(node, selector.source,
-                                            element, MemberKind.SETTER);
+        DartType target;
+        if (analyzingInitializer) {
+          // Field declaration `Foo target = value;` or initializer
+          // `this.target = value`. Lookup the getter `target` in the class
+          // members.
+          target = computeAccessType(node, selector.source, element,
+              MemberKind.GETTER, lookupClassMember: true);
+        } else {
+          // Normal assignment `target = value`.
+          target = computeAccessType(
+              node, selector.source, element, MemberKind.SETTER);
+        }
         final Node valueNode = node.arguments.head;
         final DartType value = analyze(valueNode);
         checkAssignable(node.assignmentOperator, value, target);
@@ -1444,7 +1513,8 @@
     DartType type = StatementType.NOT_RETURNING;
     bool reportedDeadCode = false;
     for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      DartType nextType = analyze(link.head);
+      DartType nextType =
+          analyze(link.head, inInitializer: analyzingInitializer);
       if (type == StatementType.RETURNING) {
         if (!reportedDeadCode) {
           reportTypeWarning(link.head, MessageKind.UNREACHABLE_CODE);
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
deleted file mode 100644
index d9412e6..0000000
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ /dev/null
@@ -1,2380 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library concrete_types_inferrer;
-
-import 'dart:collection' show Queue, IterableBase;
-import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../elements/elements.dart';
-import '../native_handler.dart' as native;
-import '../tree/tree.dart';
-import '../universe/universe.dart';
-import '../util/util.dart';
-
-import 'types.dart' show TypeMask, TypesInferrer;
-
-class CancelTypeInferenceException {
-  final Node node;
-  final String reason;
-
-  CancelTypeInferenceException(this.node, this.reason);
-}
-
-/**
- * A singleton concrete type. More precisely, a [BaseType] is one of the
- * following:
- *
- *   - a non-asbtract class like [: int :] or [: Uri :] but not [: List :]
- *   - the null base type
- *   - the unknown base type
- */
-abstract class BaseType {
-  bool isClass();
-  bool isUnknown();
-  bool isNull();
-}
-
-/**
- * A non-asbtract class like [: int :] or [: Uri :] but not [: List :].
- */
-class ClassBaseType implements BaseType {
-  final ClassElement element;
-
-  ClassBaseType(this.element);
-
-  bool operator ==(var other) {
-    if (identical(this, other)) return true;
-    if (other is! ClassBaseType) return false;
-    return element == other.element;
-  }
-  int get hashCode => element.hashCode;
-  String toString() {
-    return element == null ? 'toplevel' : element.name;
-  }
-  bool isClass() => true;
-  bool isUnknown() => false;
-  bool isNull() => false;
-}
-
-/**
- * The unknown base type.
- */
-class UnknownBaseType implements BaseType {
-  const UnknownBaseType();
-  bool operator ==(BaseType other) => other is UnknownBaseType;
-  int get hashCode => 0;
-  bool isClass() => false;
-  bool isUnknown() => true;
-  bool isNull() => false;
-  toString() => "unknown";
-}
-
-/**
- * The null base type.
- */
-class NullBaseType implements BaseType {
-  const NullBaseType();
-  bool operator ==(BaseType other) => identical(other, this);
-  int get hashCode => 1;
-  bool isClass() => false;
-  bool isUnknown() => false;
-  bool isNull() => true;
-  toString() => "null";
-}
-
-/**
- * An immutable set of base types, like [: {int, bool} :] or the unknown
- * concrete type.
- */
-abstract class ConcreteType {
-  ConcreteType();
-
-  factory ConcreteType.empty(int maxConcreteTypeSize,
-                             BaseTypes classBaseTypes) {
-    return new UnionType(maxConcreteTypeSize, classBaseTypes,
-                         new Set<BaseType>());
-  }
-
-  /**
-   * The singleton constituted of the unknown base type is the unknown concrete
-   * type.
-   */
-  factory ConcreteType.singleton(int maxConcreteTypeSize,
-                                 BaseTypes classBaseTypes, BaseType baseType) {
-    if (baseType.isUnknown() || maxConcreteTypeSize < 1) {
-      return const UnknownConcreteType();
-    }
-    Set<BaseType> singletonSet = new Set<BaseType>();
-    singletonSet.add(baseType);
-    return new UnionType(maxConcreteTypeSize, classBaseTypes, singletonSet);
-  }
-
-  factory ConcreteType.unknown() {
-    return const UnknownConcreteType();
-  }
-
-  ConcreteType union(ConcreteType other);
-  bool isUnknown();
-  bool isEmpty();
-  Set<BaseType> get baseTypes;
-
-  /**
-   * Returns the unique element of [: this :] if [: this :] is a singleton,
-   * null otherwise.
-   */
-  ClassElement getUniqueType();
-}
-
-/**
- * The unkown concrete type: it is absorbing for the union.
- */
-class UnknownConcreteType implements ConcreteType {
-  const UnknownConcreteType();
-  bool isUnknown() => true;
-  bool isEmpty() => false;
-  bool operator ==(ConcreteType other) => identical(this, other);
-  Set<BaseType> get baseTypes =>
-      new Set<BaseType>.from([const UnknownBaseType()]);
-  int get hashCode => 0;
-  ConcreteType union(ConcreteType other) => this;
-  ClassElement getUniqueType() => null;
-  toString() => "unknown";
-}
-
-/**
- * An immutable set of base types, like [: {int, bool} :].
- */
-class UnionType implements ConcreteType {
-  final int maxConcreteTypeSize;
-  final BaseTypes classBaseTypes;
-
-  final Set<BaseType> baseTypes;
-
-  /**
-   * The argument should NOT be mutated later. Do not call directly, use
-   * ConcreteType.singleton instead.
-   */
-  UnionType(this.maxConcreteTypeSize, this.classBaseTypes, this.baseTypes);
-
-  bool isUnknown() => false;
-  bool isEmpty() => baseTypes.isEmpty;
-
-  bool operator ==(ConcreteType other) {
-    if (other is! UnionType) return false;
-    if (baseTypes.length != other.baseTypes.length) return false;
-    return baseTypes.containsAll(other.baseTypes);
-  }
-
-  int get hashCode {
-    int result = 1;
-    for (final baseType in baseTypes) {
-      result = 31 * result + baseType.hashCode;
-    }
-    return result;
-  }
-
-  ConcreteType union(ConcreteType other) {
-    if (other.isUnknown()) {
-      return const UnknownConcreteType();
-    }
-    UnionType otherUnion = other;  // cast
-    Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes);
-    newBaseTypes.addAll(otherUnion.baseTypes);
-
-    // normalize {int, float}, {int, num} or {float, num} into num
-    // TODO(polux): generalize this to all types when we extend the concept of
-    //     "concrete type" to other abstract classes than num
-    if (newBaseTypes.contains(classBaseTypes.numBaseType) ||
-        (newBaseTypes.contains(classBaseTypes.intBaseType)
-            && newBaseTypes.contains(classBaseTypes.doubleBaseType))) {
-      newBaseTypes.remove(classBaseTypes.intBaseType);
-      newBaseTypes.remove(classBaseTypes.doubleBaseType);
-      newBaseTypes.add(classBaseTypes.numBaseType);
-    }
-
-    // widen big types to dynamic
-    return newBaseTypes.length > maxConcreteTypeSize
-        ? const UnknownConcreteType()
-        : new UnionType(maxConcreteTypeSize, classBaseTypes, newBaseTypes);
-  }
-
-  ClassElement getUniqueType() {
-    if (baseTypes.length == 1) {
-      var iterator = baseTypes.iterator;
-      iterator.moveNext();
-      BaseType uniqueBaseType = iterator.current;
-      if (uniqueBaseType.isClass()) {
-        ClassBaseType uniqueClassType = uniqueBaseType;
-        return uniqueClassType.element;
-      }
-    }
-    return null;
-  }
-
-  String toString() => baseTypes.toString();
-}
-
-/**
- * The cartesian product of concrete types: an iterable of [BaseTypeTuple]s. For
- * instance, the cartesian product of the concrete types [: {A, B} :] and
- * [: {C, D} :] is an itearble whose iterators will yield [: (A, C) :],
- * [: (A, D) :], [: (B, C) :] and finally [: (B, D) :].
- */
-class ConcreteTypeCartesianProduct
-    extends IterableBase<ConcreteTypesEnvironment> {
-  final ConcreteTypesInferrer inferrer;
-  final ClassElement typeOfThis;
-  final Map<Element, ConcreteType> concreteTypes;
-  ConcreteTypeCartesianProduct(this.inferrer, this.typeOfThis,
-                               this.concreteTypes);
-  Iterator get iterator => concreteTypes.isEmpty
-      ? [new ConcreteTypesEnvironment(inferrer, new ClassBaseType(typeOfThis))]
-            .iterator
-      : new ConcreteTypeCartesianProductIterator(inferrer,
-            new ClassBaseType(typeOfThis), concreteTypes);
-  String toString() {
-    List<ConcreteTypesEnvironment> cartesianProduct =
-        new List<ConcreteTypesEnvironment>.from(this);
-    return cartesianProduct.toString();
-  }
-}
-
-/**
- * An helper class for [ConcreteTypeCartesianProduct].
- */
-class ConcreteTypeCartesianProductIterator
-    implements Iterator<ConcreteTypesEnvironment> {
-  final ConcreteTypesInferrer inferrer;
-  final BaseType baseTypeOfThis;
-  final Map<Element, ConcreteType> concreteTypes;
-  final Map<Element, BaseType> nextValues;
-  final Map<Element, Iterator> state;
-  int size = 1;
-  int counter = 0;
-  ConcreteTypesEnvironment _current;
-
-  ConcreteTypeCartesianProductIterator(this.inferrer, this.baseTypeOfThis,
-      Map<Element, ConcreteType> concreteTypes)
-      : this.concreteTypes = concreteTypes,
-        nextValues = new Map<Element, BaseType>(),
-        state = new Map<Element, Iterator>() {
-    if (concreteTypes.isEmpty) {
-      size = 0;
-      return;
-    }
-    for (final e in concreteTypes.keys) {
-      final baseTypes = concreteTypes[e].baseTypes;
-      size *= baseTypes.length;
-    }
-  }
-
-  ConcreteTypesEnvironment get current => _current;
-
-  ConcreteTypesEnvironment takeSnapshot() {
-    Map<Element, ConcreteType> result = new Map<Element, ConcreteType>();
-    nextValues.forEach((k, v) {
-      result[k] = inferrer.singletonConcreteType(v);
-    });
-    return new ConcreteTypesEnvironment.of(inferrer, result, baseTypeOfThis);
-  }
-
-  bool moveNext() {
-    if (counter >= size) {
-      _current = null;
-      return false;
-    }
-    Element keyToIncrement = null;
-    for (final key in concreteTypes.keys) {
-      final iterator = state[key];
-      if (iterator != null && iterator.moveNext()) {
-        nextValues[key] = state[key].current;
-        break;
-      }
-      Iterator newIterator = concreteTypes[key].baseTypes.iterator;
-      state[key] = newIterator;
-      newIterator.moveNext();
-      nextValues[key] = newIterator.current;
-    }
-    counter++;
-    _current = takeSnapshot();
-    return true;
-  }
-}
-
-/**
- * [BaseType] Constants.
- */
-class BaseTypes {
-  final ClassBaseType intBaseType;
-  final ClassBaseType doubleBaseType;
-  final ClassBaseType numBaseType;
-  final ClassBaseType boolBaseType;
-  final ClassBaseType stringBaseType;
-  final ClassBaseType listBaseType;
-  final ClassBaseType growableListBaseType;
-  final ClassBaseType fixedListBaseType;
-  final ClassBaseType constListBaseType;
-  final ClassBaseType mapBaseType;
-  final ClassBaseType objectBaseType;
-  final ClassBaseType typeBaseType;
-  final ClassBaseType functionBaseType;
-
-  BaseTypes(Compiler compiler) :
-    intBaseType = new ClassBaseType(compiler.backend.intImplementation),
-    doubleBaseType = new ClassBaseType(compiler.backend.doubleImplementation),
-    numBaseType = new ClassBaseType(compiler.backend.numImplementation),
-    boolBaseType = new ClassBaseType(compiler.backend.boolImplementation),
-    stringBaseType = new ClassBaseType(compiler.backend.stringImplementation),
-    listBaseType = new ClassBaseType(compiler.backend.listImplementation),
-    growableListBaseType =
-        new ClassBaseType(compiler.backend.growableListImplementation),
-    fixedListBaseType =
-        new ClassBaseType(compiler.backend.fixedListImplementation),
-    constListBaseType =
-        new ClassBaseType(compiler.backend.constListImplementation),
-    mapBaseType = new ClassBaseType(compiler.backend.mapImplementation),
-    objectBaseType = new ClassBaseType(compiler.objectClass),
-    typeBaseType = new ClassBaseType(compiler.backend.typeImplementation),
-    functionBaseType
-        = new ClassBaseType(compiler.backend.functionImplementation);
-}
-
-/**
- * A method-local immutable mapping from variables to their inferred
- * [ConcreteTypes]. Each visitor owns one.
- */
-class ConcreteTypesEnvironment {
-  final ConcreteTypesInferrer inferrer;
-  final Map<Element, ConcreteType> environment;
-  final BaseType typeOfThis;
-
-  ConcreteTypesEnvironment(this.inferrer, [this.typeOfThis]) :
-      environment = new Map<Element, ConcreteType>();
-  ConcreteTypesEnvironment.of(this.inferrer, this.environment, this.typeOfThis);
-
-  ConcreteType lookupType(Element element) => environment[element];
-  ConcreteType lookupTypeOfThis() {
-    return (typeOfThis == null)
-        ? null
-        : inferrer.singletonConcreteType(typeOfThis);
-  }
-
-  ConcreteTypesEnvironment put(Element element, ConcreteType type) {
-    Map<Element, ConcreteType> newMap =
-        new Map<Element, ConcreteType>.from(environment);
-    newMap[element] = type;
-    return new ConcreteTypesEnvironment.of(inferrer, newMap, typeOfThis);
-  }
-
-  ConcreteTypesEnvironment join(ConcreteTypesEnvironment other) {
-    if (typeOfThis != other.typeOfThis) {
-      throw "trying to join incompatible environments";
-    }
-    Map<Element, ConcreteType> newMap =
-        new Map<Element, ConcreteType>.from(environment);
-    other.environment.forEach((element, type) {
-      ConcreteType currentType = newMap[element];
-      if (currentType == null) {
-        newMap[element] = type;
-      } else {
-        newMap[element] = currentType.union(type);
-      }
-    });
-    return new ConcreteTypesEnvironment.of(inferrer, newMap, typeOfThis);
-  }
-
-  bool operator ==(ConcreteTypesEnvironment other) {
-    if (other is! ConcreteTypesEnvironment) return false;
-    if (typeOfThis != other.typeOfThis) return false;
-    if (environment.length != other.environment.length) return false;
-    for (Element key in environment.keys) {
-      if (!other.environment.containsKey(key)
-          || (environment[key] != other.environment[key])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  int get hashCode {
-    int result = (typeOfThis != null) ? typeOfThis.hashCode : 1;
-    environment.forEach((element, concreteType) {
-      result = 31 * (31 * result + element.hashCode) +
-          concreteType.hashCode;
-    });
-    return result;
-  }
-
-  String toString() => "{ this: $typeOfThis, env: $environment }";
-}
-
-/**
- * A work item for the type inference queue.
- */
-class InferenceWorkItem {
-  Element methodOrField;
-  ConcreteTypesEnvironment environment;
-  InferenceWorkItem(this.methodOrField, this.environment);
-
-  toString() {
-    final elementType = methodOrField.isField() ? "field" : "method";
-    final elementRepresentation = methodOrField.name;
-    return "{ $elementType = $elementRepresentation"
-           ", environment = $environment }";
-  }
-}
-
-/**
- * A sentinel type mask class representing the dynamicType. It is absorbing
- * for [:ConcreteTypesEnvironment.typeMaskUnion:].
- */
-class DynamicTypeMask implements TypeMask {
-  const DynamicTypeMask();
-
-  String toString() => 'sentinel type mask';
-
-  TypeMask nullable() {
-    throw new UnsupportedError("");
-  }
-
-  TypeMask nonNullable() {
-    throw new UnsupportedError("");
-  }
-
-  TypeMask simplify(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool get isEmpty {
-    throw new UnsupportedError("");
-  }
-
-  bool get isNullable {
-    throw new UnsupportedError("");
-  }
-
-  bool get isExact {
-    throw new UnsupportedError("");
-  }
-
-  bool get isUnion {
-    throw new UnsupportedError("");
-  }
-
-  bool get isContainer {
-    throw new UnsupportedError("");
-  }
-
-  bool get isMap {
-    throw new UnsupportedError("");
-  }
-
-  bool get isForwarding {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnlyInt(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnlyDouble(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnlyNum(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnlyBool(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnlyString(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsOnly(ClassElement element) {
-    throw new UnsupportedError("");
-  }
-
-  bool satisfies(ClassElement cls, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool contains(ClassElement type, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsAll(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  ClassElement singleClass(Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  TypeMask union(TypeMask other, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  TypeMask intersection(TypeMask other, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool canHit(Element element, Selector selector, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  Element locateSingleElement(Selector selector, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool isInMask(TypeMask other, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-
-  bool containsMask(TypeMask other, Compiler compiler) {
-    throw new UnsupportedError("");
-  }
-}
-
-/**
- * A task which conservatively infers a [ConcreteType] for each sub expression
- * of the program. The entry point is [analyzeMain].
- */
-class ConcreteTypesInferrer extends TypesInferrer {
-  static final bool LOG_FAILURES = true;
-
-  final String name = "Type inferrer";
-
-  final Compiler compiler;
-
-  /**
-   * When true, the string literal [:"__dynamic_for_test":] is inferred to
-   * have the unknown type.
-   */
-  // TODO(polux): get rid of this hack once we have a natural way of inferring
-  // the unknown type.
-  bool testMode = false;
-
-  /**
-   * Constants representing builtin base types. Initialized in [initialize]
-   * and not in the constructor because the compiler elements are not yet
-   * populated.
-   */
-  BaseTypes baseTypes;
-
-  /**
-   * Constant representing [:ConcreteList#[]:] where [:ConcreteList:] is the
-   * concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listIndex;
-
-  /**
-   * Constant representing [:ConcreteList#[]=:] where [:ConcreteList:] is the
-   * concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listIndexSet;
-
-  /**
-   * Constant representing [:ConcreteList#add:] where [:ConcreteList:] is the
-   * concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listAdd;
-
-  /**
-   * Constant representing [:ConcreteList#removeAt:] where [:ConcreteList:] is
-   * the concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listRemoveAt;
-
-  /**
-   * Constant representing [:ConcreteList#insert:] where [:ConcreteList:] is
-   * the concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listInsert;
-
-  /**
-   * Constant representing [:ConcreteList#removeLast:] where [:ConcreteList:] is
-   * the concrete implementation of lists for the selected backend.
-   */
-  FunctionElement listRemoveLast;
-
-  /**
-   * Constant representing [:List():].
-   */
-  FunctionElement listConstructor;
-
-  /**
-   * Constant mapping between types returned by native calls and concrete types.
-   */
-  Map<ClassElement, ConcreteType> nativeTypesToConcreteTypes;
-
-  /**
-   * Constant mapping between types returned by native calls and the set of
-   * classes that should augment [seenClasses] when encountered.
-   */
-  Map<ClassElement, List<ClassElement>> nativeTypesToSeenClasses;
-
-  /**
-   * Constant list of concrete classes seen by the resolver.
-   */
-  List<ClassElement> concreteSeenClasses;
-
-  /**
-   * A cache from (function x argument base types) to concrete types,
-   * used to memoize [analyzeMonoSend]. Another way of seeing [cache] is as a
-   * map from [FunctionElement]s to "templates" in the sense of "The Cartesian
-   * Product Algorithm - Simple and Precise Type Inference of Parametric
-   * Polymorphism" by Ole Agesen.
-   */
-  // TODO(polux): rename and build a better abstraction.
-  final Map<FunctionElement, Map<ConcreteTypesEnvironment, ConcreteType>> cache;
-
-  /** A map from expressions to their inferred concrete types. */
-  final Map<Node, ConcreteType> inferredTypes;
-
-  /** A map from fields to their inferred concrete types. */
-  final Map<Element, ConcreteType> inferredFieldTypes;
-
-  /** The work queue consumed by [analyzeMain]. */
-  final Queue<InferenceWorkItem> workQueue;
-
-  /**
-   * [:callers[f]:] is the list of [:f:]'s possible callers or fields
-   * whose initialization is a call to [:f:].
-   */
-  final Map<FunctionElement, Set<Element>> callers;
-
-  /**
-   * [:readers[field]:] is the list of [:field:]'s possible readers or fields
-   * whose initialization is a read of [:field:].
-   */
-  final Map<Element, Set<Element>> readers;
-
-  /// The set of classes encountered so far.
-  final Set<ClassElement> seenClasses;
-
-  /**
-   * A map from method names to callers of methods with this name on objects
-   * of unknown inferred type.
-   */
-  final Map<String, Set<FunctionElement>> dynamicCallers;
-
-  /** The inferred type of elements stored in Lists. */
-  ConcreteType listElementType;
-
-  /**
-   * A map from parameters to their inferred concrete types. It plays no role
-   * in the analysis, it is write only.
-   */
-  final Map<VariableElement, ConcreteType> inferredParameterTypes;
-
-  /**
-   * A map from selectors to their inferred type masks, indexed by the mask
-   * of the receiver. It plays no role in the analysis, it is write only.
-   */
-  final Map<Selector, Map<TypeMask, TypeMask>> inferredSelectorTypes;
-
-  ConcreteTypesInferrer(Compiler compiler)
-      : this.compiler = compiler,
-        cache = new Map<FunctionElement,
-            Map<ConcreteTypesEnvironment, ConcreteType>>(),
-        inferredTypes = new Map<Node, ConcreteType>(),
-        inferredFieldTypes = new Map<Element, ConcreteType>(),
-        inferredParameterTypes = new Map<VariableElement, ConcreteType>(),
-        workQueue = new Queue<InferenceWorkItem>(),
-        callers = new Map<FunctionElement, Set<Element>>(),
-        readers = new Map<Element, Set<Element>>(),
-        seenClasses = new Set<ClassElement>(),
-        dynamicCallers = new Map<String, Set<FunctionElement>>(),
-        inferredSelectorTypes = new Map<Selector, Map<TypeMask, TypeMask>>() {
-    unknownConcreteType = new ConcreteType.unknown();
-  }
-
-  // --- utility methods ---
-
-  /** The unknown concrete type */
-  ConcreteType unknownConcreteType;
-
-  /** The empty concrete type */
-  ConcreteType emptyConcreteType;
-
-  /** The null concrete type */
-  ConcreteType nullConcreteType;
-
-  /** Creates a singleton concrete type containing [baseType]. */
-  ConcreteType singletonConcreteType(BaseType baseType) {
-    return new ConcreteType.singleton(compiler.maxConcreteTypeSize, baseTypes,
-                                      baseType);
-  }
-
-  /**
-   * Computes the union of [mask1] and [mask2] where [mask1] and [mask2] are
-   * possibly equal to [: DynamicTypeMask.instance :].
-   */
-  TypeMask typeMaskUnion(TypeMask mask1, TypeMask mask2) {
-    if (mask1 == const DynamicTypeMask()
-        || mask2 == const DynamicTypeMask()) {
-      return const DynamicTypeMask();
-    }
-    return mask1.union(mask2, compiler);
-  }
-
-  /**
-   * Returns all the members with name [methodName].
-   */
-  List<Element> getMembersByName(String methodName) {
-    // TODO(polux): memoize?
-    var result = new List<Element>();
-    for (ClassElement cls in seenClasses) {
-      Element elem = cls.lookupMember(methodName);
-      if (elem != null) {
-        result.add(elem.implementation);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Sets the concrete type associated to [node] to the union of the inferred
-   * concrete type so far and [type].
-   */
-  void augmentInferredType(Node node, ConcreteType type) {
-    ConcreteType currentType = inferredTypes[node];
-    inferredTypes[node] = (currentType == null)
-        ? type
-        : currentType.union(type);
-  }
-
-  /**
-   * Sets the concrete type associated to [selector] to the union of the
-   * inferred concrete type so far and [type].
-   * Precondition: [:typeOfThis != null:]
-   */
-  void augmentInferredSelectorType(Selector selector, TypeMask typeOfThis,
-                                   TypeMask returnType) {
-    assert(returnType != null);
-    assert(typeOfThis != null);
-    selector = selector.asUntyped;
-    Map<TypeMask, TypeMask> currentMap = inferredSelectorTypes.putIfAbsent(
-        selector, () => new Map<TypeMask, TypeMask>());
-    TypeMask currentReturnType = currentMap[typeOfThis];
-    currentMap[typeOfThis] = (currentReturnType == null)
-        ? returnType
-        : typeMaskUnion(currentReturnType, returnType);
-  }
-
-  /**
-   * Returns the current inferred concrete type of [field].
-   */
-  ConcreteType getFieldType(Selector selector, Element field) {
-    ConcreteType result = inferredFieldTypes[field];
-    if (result == null) {
-      // field is a toplevel variable, we trigger its analysis because no object
-      // creation is ever going to trigger it
-      result = analyzeFieldInitialization(field);
-      return (result == null) ? emptyConcreteType : result;
-    }
-    if (selector != null) {
-      Element enclosing = field.enclosingElement;
-      if (enclosing.isClass()) {
-        ClassElement cls = enclosing;
-        TypeMask receiverMask = new TypeMask.exact(cls);
-        TypeMask resultMask = concreteTypeToTypeMask(result);
-        augmentInferredSelectorType(selector, receiverMask, resultMask);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Sets the concrete type associated to [field] to the union of the inferred
-   * concrete type so far and [type].
-   */
-  void augmentFieldType(Element field, ConcreteType type) {
-    ConcreteType oldType = inferredFieldTypes[field];
-    ConcreteType newType = (oldType != null)
-        ? oldType.union(type)
-        : type;
-    if (oldType != newType) {
-      inferredFieldTypes[field] = newType;
-      final fieldReaders = readers[field];
-      if (fieldReaders != null) {
-        fieldReaders.forEach(invalidate);
-      }
-    }
-  }
-
-  /// Augment the inferred type of elements stored in Lists.
-  void augmentListElementType(ConcreteType type) {
-    ConcreteType newType = listElementType.union(type);
-    if (newType != listElementType) {
-      invalidateCallers(listIndex);
-      listElementType = newType;
-    }
-  }
-
-  /**
-   * Sets the concrete type associated to [parameter] to the union of the
-   * inferred concrete type so far and [type].
-   */
-  void augmentParameterType(VariableElement parameter, ConcreteType type) {
-    ConcreteType oldType = inferredParameterTypes[parameter];
-    inferredParameterTypes[parameter] =
-        (oldType == null) ? type : oldType.union(type);
-  }
-
-  /// Augments the set of classes encountered so far.
-  void augmentSeenClasses(ClassElement cls) {
-    if (!seenClasses.contains(cls)) {
-      seenClasses.add(cls);
-      cls.forEachMember((_, Element member) {
-        Set<FunctionElement> functions = dynamicCallers[member.name];
-        if (functions == null) return;
-        for (FunctionElement function in functions) {
-          invalidate(function);
-        }
-      }, includeSuperAndInjectedMembers: true);
-    }
-  }
-
-  /**
-   * Add [caller] to the set of [callee]'s callers.
-   */
-  void addCaller(FunctionElement callee, Element caller) {
-    Set<Element> current = callers[callee];
-    if (current != null) {
-      current.add(caller);
-    } else {
-      Set<Element> newSet = new Set<Element>();
-      newSet.add(caller);
-      callers[callee] = newSet;
-    }
-  }
-
-  /**
-   * Add [caller] to the set of [callee]'s dynamic callers.
-   */
-  void addDynamicCaller(String callee, FunctionElement caller) {
-    Set<FunctionElement> current = dynamicCallers[callee];
-    if (current != null) {
-      current.add(caller);
-    } else {
-      Set<FunctionElement> newSet = new Set<FunctionElement>();
-      newSet.add(caller);
-      dynamicCallers[callee] = newSet;
-    }
-  }
-
-  /**
-   * Add [reader] to the set of [field]'s readers.
-   */
-  void addReader(Element field, Element reader) {
-    Set<Element> current = readers[field];
-    if (current != null) {
-      current.add(reader);
-    } else {
-      Set<Element> newSet = new Set<Element>();
-      newSet.add(reader);
-      readers[field] = newSet;
-    }
-  }
-
-  /**
-   * Add callers of [function] to the workqueue.
-   */
-  void invalidateCallers(FunctionElement function) {
-    Set<Element> methodCallers = callers[function];
-    if (methodCallers == null) return;
-    for (Element caller in methodCallers) {
-      invalidate(caller);
-    }
-  }
-
-  /**
-   * Add all instances of [methodOrField] to the workqueue.
-   */
-  void invalidate(Element methodOrField) {
-    if (methodOrField.isField()) {
-      workQueue.addLast(new InferenceWorkItem(
-          methodOrField, new ConcreteTypesEnvironment(this)));
-    } else {
-      Map<ConcreteTypesEnvironment, ConcreteType> instances =
-          cache[methodOrField];
-      if (instances != null) {
-        instances.forEach((environment, _) {
-          workQueue.addLast(
-              new InferenceWorkItem(methodOrField, environment));
-        });
-      }
-    }
-  }
-
-  /**
-   * Returns the template associated to [function] in cache or create an
-   * empty template for [function] in cache and returns it.
-   */
-  Map<ConcreteTypesEnvironment, ConcreteType>
-      getTemplatesOrEmpty(FunctionElement function) {
-    return cache.putIfAbsent(
-        function,
-        () => new Map<ConcreteTypesEnvironment, ConcreteType>());
-  }
-
-  // -- query --
-
-  /**
-   * Returns the [TypeMask] representation of [baseType].
-   */
-  TypeMask baseTypeToTypeMask(BaseType baseType) {
-    if (baseType.isUnknown()) {
-      return const DynamicTypeMask();
-    } else if (baseType.isNull()) {
-      return new TypeMask.empty();
-    } else {
-      ClassBaseType classBaseType = baseType;
-      final element = classBaseType.element;
-      assert(element != null);
-      if (element == compiler.backend.numImplementation) {
-        return new TypeMask.nonNullSubclass(
-            compiler.backend.numImplementation);
-      } else if (element == compiler.dynamicClass) {
-        return new TypeMask.nonNullSubclass(compiler.objectClass);
-      } else {
-        return new TypeMask.nonNullExact(element);
-      }
-    }
-  }
-
-  /**
-   * Returns the [TypeMask] representation of [concreteType].
-   */
-  TypeMask concreteTypeToTypeMask(ConcreteType concreteType) {
-    if (concreteType == null) return null;
-    TypeMask typeMask = new TypeMask.nonNullEmpty();
-    for (BaseType baseType in concreteType.baseTypes) {
-      TypeMask baseMask = baseTypeToTypeMask(baseType);
-      if (baseMask == const DynamicTypeMask()) return baseMask;
-      typeMask = typeMask.union(baseMask, compiler);
-    }
-    return typeMask;
-  }
-
-  /**
-   * Get the inferred concrete type of [node].
-   */
-  TypeMask getTypeOfNode(Element owner, Node node) {
-    TypeMask result = concreteTypeToTypeMask(inferredTypes[node]);
-    return result == const DynamicTypeMask() ? null : result;
-  }
-
-  /**
-   * Get the inferred concrete type of [element].
-   */
-  TypeMask getTypeOfElement(Element element) {
-    TypeMask result = null;
-    if (element.isParameter()) {
-      result = concreteTypeToTypeMask(inferredParameterTypes[element]);
-    } else if (element.isField()) {
-      result = concreteTypeToTypeMask(inferredFieldTypes[element]);
-    }
-    // TODO(polux): handle field parameters
-    return result == const DynamicTypeMask() ? null : result;
-  }
-
-  /**
-   * Get the inferred concrete return type of [element].
-   */
-  TypeMask getReturnTypeOfElement(Element element) {
-    if (!element.isFunction()) return null;
-    Map<ConcreteTypesEnvironment, ConcreteType> templates = cache[element];
-    if (templates == null) return null;
-    ConcreteType returnType = emptyConcreteType;
-    templates.forEach((_, concreteType) {
-      returnType = returnType.union(concreteType);
-    });
-    TypeMask result = concreteTypeToTypeMask(returnType);
-    return result == const DynamicTypeMask() ? null : result;
-  }
-
-  /**
-   * Get the inferred concrete type of [selector]. A null return value means
-   * "I don't know".
-   */
-  TypeMask getTypeOfSelector(Selector selector) {
-    Map<TypeMask, TypeMask> candidates =
-        inferredSelectorTypes[selector.asUntyped];
-    if (candidates == null) {
-      return null;
-    }
-    TypeMask result = new TypeMask.nonNullEmpty();
-    if (selector.mask == null) {
-      candidates.forEach((TypeMask receiverType, TypeMask returnType) {
-        result = typeMaskUnion(result, returnType);
-      });
-    } else {
-      candidates.forEach((TypeMask receiverType, TypeMask returnType) {
-        TypeMask intersection =
-            receiverType.intersection(selector.mask, compiler);
-        if (!intersection.isEmpty || intersection.isNullable) {
-          result = typeMaskUnion(result, returnType);
-        }
-      });
-    }
-    return result == const DynamicTypeMask() ? null : result;
-  }
-
-  void clear() {}
-
-  bool isCalledOnce(Element element) {
-    throw new UnsupportedError("");
-  }
-
-  bool isFixedArrayCheckedForGrowable(Node node) {
-    throw new UnsupportedError("");
-  }
-
-  // --- analysis ---
-
-  /**
-   * Returns the concrete type returned by [function] given arguments of
-   * concrete types [argumentsTypes]. If [function] is static then
-   * [receiverType] must be null, else [function] must be a member of the class
-   * of [receiverType].
-   */
-  ConcreteType getSendReturnType(Selector selector,
-                                 FunctionElement function,
-                                 ClassElement receiverType,
-                                 ArgumentsTypes argumentsTypes) {
-    ConcreteType result = emptyConcreteType;
-    Map<Element, ConcreteType> argumentMap =
-        associateArguments(function, argumentsTypes);
-    // if the association failed, this send will never occur or will fail
-    if (argumentMap == null) {
-      return emptyConcreteType;
-    }
-
-    argumentMap.forEach(augmentParameterType);
-    ConcreteTypeCartesianProduct product =
-        new ConcreteTypeCartesianProduct(this, receiverType, argumentMap);
-    for (ConcreteTypesEnvironment environment in product) {
-      result =
-          result.union(getMonomorphicSendReturnType(function, environment));
-    }
-
-    if (selector != null && receiverType != null) {
-      // TODO(polux): generalize to any abstract class if we ever handle other
-      // abstract classes than num.
-      TypeMask receiverMask =
-          (receiverType == compiler.backend.numImplementation)
-              ? new TypeMask.nonNullSubclass(receiverType)
-              : new TypeMask.nonNullExact(receiverType);
-      TypeMask resultMask = concreteTypeToTypeMask(result);
-      augmentInferredSelectorType(selector, receiverMask, resultMask);
-    }
-
-    return result;
-  }
-
-  /**
-   * Given a method signature and a list of concrete types, builds a map from
-   * formals to their corresponding concrete types. Returns null if the
-   * association is impossible (for instance: too many arguments).
-   */
-  Map<Element, ConcreteType> associateArguments(FunctionElement function,
-                                                ArgumentsTypes argumentsTypes) {
-    final Map<Element, ConcreteType> result = new Map<Element, ConcreteType>();
-    final FunctionSignature signature = function.computeSignature(compiler);
-
-    // guard 1: too many arguments
-    if (argumentsTypes.length > signature.parameterCount) {
-      return null;
-    }
-    // guard 2: not enough arguments
-    if (argumentsTypes.positional.length < signature.requiredParameterCount) {
-      return null;
-    }
-    // guard 3: too many positional arguments
-    if (signature.optionalParametersAreNamed &&
-        argumentsTypes.positional.length > signature.requiredParameterCount) {
-      return null;
-    }
-
-    handleLeftoverOptionalParameter(Element parameter) {
-      // TODO(polux): use default value whenever available
-      // TODO(polux): add a marker to indicate whether an argument was provided
-      //     in order to handle "?parameter" tests
-      result[parameter] = nullConcreteType;
-    }
-
-    final Iterator<ConcreteType> remainingPositionalArguments =
-        argumentsTypes.positional.iterator;
-    // we attach each positional parameter to its corresponding positional
-    // argument
-    for (Link<Element> requiredParameters = signature.requiredParameters;
-        !requiredParameters.isEmpty;
-        requiredParameters = requiredParameters.tail) {
-      final Element requiredParameter = requiredParameters.head;
-      // we know moveNext() succeeds because of guard 2
-      remainingPositionalArguments.moveNext();
-      result[requiredParameter] = remainingPositionalArguments.current;
-    }
-    if (signature.optionalParametersAreNamed) {
-      // we build a map out of the remaining named parameters
-      Link<Element> remainingOptionalParameters = signature.optionalParameters;
-      final Map<String, Element> leftOverNamedParameters =
-          new Map<String, Element>();
-      for (;
-           !remainingOptionalParameters.isEmpty;
-           remainingOptionalParameters = remainingOptionalParameters.tail) {
-        final Element namedParameter = remainingOptionalParameters.head;
-        leftOverNamedParameters[namedParameter.name] = namedParameter;
-      }
-      // we attach the named arguments to their corresponding optional
-      // parameters
-      for (Identifier identifier in argumentsTypes.named.keys) {
-        final ConcreteType concreteType = argumentsTypes.named[identifier];
-        String source = identifier.source;
-        final Element namedParameter = leftOverNamedParameters[source];
-        // unexisting or already used named parameter
-        if (namedParameter == null) return null;
-        result[namedParameter] = concreteType;
-        leftOverNamedParameters.remove(source);
-      }
-      leftOverNamedParameters.forEach((_, Element parameter) {
-        handleLeftoverOptionalParameter(parameter);
-      });
-    } else { // optional parameters are positional
-      // we attach the remaining positional arguments to their corresponding
-      // optional parameters
-      Link<Element> remainingOptionalParameters = signature.optionalParameters;
-      while (remainingPositionalArguments.moveNext()) {
-        final Element optionalParameter = remainingOptionalParameters.head;
-        result[optionalParameter] = remainingPositionalArguments.current;
-        // we know tail is defined because of guard 1
-        remainingOptionalParameters = remainingOptionalParameters.tail;
-      }
-      for (;
-           !remainingOptionalParameters.isEmpty;
-           remainingOptionalParameters = remainingOptionalParameters.tail) {
-        handleLeftoverOptionalParameter(remainingOptionalParameters.head);
-      }
-    }
-    return result;
-  }
-
-  ConcreteType getMonomorphicSendReturnType(
-      FunctionElement function,
-      ConcreteTypesEnvironment environment) {
-    Map<ConcreteTypesEnvironment, ConcreteType> template =
-        getTemplatesOrEmpty(function);
-    ConcreteType type = template[environment];
-    ConcreteType specialType = getSpecialCaseReturnType(function, environment);
-    if (type != null) {
-      return specialType != null ? specialType : type;
-    } else {
-      workQueue.addLast(new InferenceWorkItem(function, environment));
-      // in case of a constructor, optimize by returning the class
-      return specialType != null ? specialType : emptyConcreteType;
-    }
-  }
-
-  /**
-   * Computes the type of a call to the magic 'JS' function.
-   */
-  ConcreteType getNativeCallReturnType(Send node) {
-    native.NativeBehavior nativeBehavior =
-        compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
-    assert(nativeBehavior != null);
-    List typesReturned = nativeBehavior.typesReturned;
-    if (typesReturned.isEmpty) return unknownConcreteType;
-
-    ConcreteType result = emptyConcreteType;
-    void registerClass(ClassElement element) {
-      if (!element.isAbstract) {
-        result =
-            result.union(singletonConcreteType(new ClassBaseType(element)));
-        augmentSeenClasses(element);
-      }
-    }
-    void registerDynamic() {
-      result = unknownConcreteType;
-      concreteSeenClasses.forEach(augmentSeenClasses);
-    }
-
-    for (final type in typesReturned) {
-      if (type == native.SpecialType.JsObject) {
-        registerDynamic();
-      } else if (type.treatAsDynamic) {
-        registerDynamic();
-      } else {
-        ClassElement element = type.element;
-        ConcreteType concreteType = nativeTypesToConcreteTypes[element];
-        if (concreteType != null) {
-          result = result.union(concreteType);
-          nativeTypesToSeenClasses[element].forEach(augmentSeenClasses);
-        } else {
-          if (compiler.enqueuer.resolution.seenClasses.contains(element)) {
-            registerClass(element);
-          }
-          Set<ClassElement> subtypes = compiler.world.subtypesOf(element);
-          if (subtypes != null) {
-            subtypes.forEach(registerClass);
-          }
-        }
-      }
-    }
-    return result;
-  }
-
-  /// Replaces native types by their backend implementation.
-  Element normalize(Element cls) {
-    if (cls == compiler.boolClass) {
-      return compiler.backend.boolImplementation;
-    }
-    if (cls == compiler.intClass) {
-      return compiler.backend.intImplementation;
-    }
-    if (cls == compiler.doubleClass) {
-      return compiler.backend.doubleImplementation;
-    }
-    if (cls == compiler.numClass) {
-      return compiler.backend.numImplementation;
-    }
-    if (cls == compiler.stringClass) {
-      return compiler.backend.stringImplementation;
-    }
-    if (cls == compiler.listClass) {
-      return compiler.backend.listImplementation;
-    }
-    return cls;
-  }
-
-  /**
-   * Handles external methods that cannot be cached because they depend on some
-   * other state of [ConcreteTypesInferrer] like [:List#[]:] and
-   * [:List#[]=:]. Returns null if [function] and [environment] don't form a
-   * special case
-   */
-  ConcreteType getSpecialCaseReturnType(FunctionElement function,
-                                        ConcreteTypesEnvironment environment) {
-    // Handles int + int, double + double, int - int, ...
-    // We cannot compare function to int#+, int#-, etc. because int and double
-    // don't override these methods. So for 1+2, getSpecialCaseReturnType will
-    // be invoked with function = num#+. We use environment.typeOfThis instead.
-    BaseType baseType = environment.typeOfThis;
-    if (baseType != null && baseType.isClass()) {
-      ClassBaseType classBaseType = baseType;
-      ClassElement cls = classBaseType.element;
-      String name = function.name;
-      if ((cls == baseTypes.intBaseType.element
-          || cls == baseTypes.doubleBaseType.element)
-          && (name == '+' || name == '-' || name == '*')) {
-        Link<Element> parameters =
-            function.functionSignature.requiredParameters;
-        ConcreteType argumentType = environment.lookupType(parameters.head);
-        if (argumentType.getUniqueType() == cls) {
-          return singletonConcreteType(new ClassBaseType(cls));
-        }
-      }
-    }
-
-    if (function == listIndex || function == listRemoveAt) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType indexType = environment.lookupType(parameters.head);
-      if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
-        return emptyConcreteType;
-      }
-      return listElementType;
-    } else if (function == listIndexSet || function == listInsert) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType indexType = environment.lookupType(parameters.head);
-      if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
-        return emptyConcreteType;
-      }
-      ConcreteType elementType = environment.lookupType(parameters.tail.head);
-      augmentListElementType(elementType);
-      return emptyConcreteType;
-    } else if (function == listAdd) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType elementType = environment.lookupType(parameters.head);
-      augmentListElementType(elementType);
-      return emptyConcreteType;
-    } else if (function == listRemoveLast) {
-      return listElementType;
-    }
-    return null;
-  }
-
-  /**
-   * [element] must be either a field with an initializing expression,
-   * a generative constructor or a function.
-   */
-  ConcreteType analyze(Selector selector,
-                       Element element,
-                       ConcreteTypesEnvironment environment) {
-    if (element.isGenerativeConstructor()) {
-      return analyzeConstructor(selector, element, environment);
-    } else if (element.isField()) {
-      analyzeFieldInitialization(element);
-      return emptyConcreteType;
-    } else {
-      assert(element is FunctionElement);
-      return analyzeMethod(element, environment);
-    }
-  }
-
-  ConcreteType analyzeMethod(FunctionElement element,
-                             ConcreteTypesEnvironment environment) {
-    TreeElements elements =
-        compiler.enqueuer.resolution.resolvedElements[element.declaration];
-    assert(elements != null);
-    handleSpecialMethod(element, environment);
-    FunctionExpression tree = element.parseNode(compiler);
-    if (tree.hasBody()) {
-      Visitor visitor =
-          new TypeInferrerVisitor(elements, element, this, environment);
-      return tree.accept(visitor);
-    } else {
-      // TODO(polux): handle num#<, num#>, etc. in order to get rid of this
-      //     else branch
-      return new ConcreteType.unknown();
-    }
-  }
-
-  /**
-   * Analyzes the initialization of a field. Returns [:null:] if and only if
-   * [element] has no initialization expression.
-   */
-  ConcreteType analyzeFieldInitialization(VariableElement element) {
-    TreeElements elements =
-        compiler.enqueuer.resolution.resolvedElements[element];
-    assert(elements != null);
-    Visitor visitor = new TypeInferrerVisitor(elements, element, this,
-        new ConcreteTypesEnvironment(this));
-    Node tree = element.parseNode(compiler);
-    ConcreteType type = initializerDo(tree, (node) => node.accept(visitor));
-    if (type != null) {
-      augmentFieldType(element, type);
-    }
-    return type;
-  }
-
-  ConcreteType analyzeConstructor(Selector selector,
-                                  FunctionElement element,
-                                  ConcreteTypesEnvironment environment) {
-    Set<Element> uninitializedFields = new Set<Element>();
-
-    // initialize fields
-    ClassElement enclosingClass = element.enclosingElement;
-    augmentSeenClasses(enclosingClass);
-    enclosingClass.forEachInstanceField((_, VariableElement field) {
-      ConcreteType type = analyzeFieldInitialization(field);
-      if (type == null) {
-        uninitializedFields.add(field);
-      }
-    });
-
-    // handle initializing formals
-    element.computeSignature(compiler).forEachParameter((param) {
-      if (param.kind == ElementKind.FIELD_PARAMETER) {
-        FieldParameterElement fieldParam = param;
-        augmentFieldType(fieldParam.fieldElement,
-            environment.lookupType(param));
-        uninitializedFields.remove(fieldParam.fieldElement);
-      }
-    });
-
-    // analyze initializers, including a possible call to super or a redirect
-    FunctionExpression tree = compiler.parser.parse(element);
-    TreeElements elements =
-        compiler.enqueuer.resolution.resolvedElements[element.declaration];
-    assert(elements != null);
-    Visitor visitor =
-        new TypeInferrerVisitor(elements, element, this, environment);
-
-    bool foundSuperOrRedirect = false;
-    if (tree != null && tree.initializers != null) {
-      // we look for a possible call to super in the initializer list
-      for (final init in tree.initializers) {
-        init.accept(visitor);
-        SendSet sendSet = init.asSendSet();
-        if (init.asSendSet() == null) {
-          foundSuperOrRedirect = true;
-        } else {
-          uninitializedFields.remove(elements[init]);
-        }
-      }
-    }
-
-    // set uninitialized fields to null
-    for (VariableElement field in uninitializedFields) {
-      augmentFieldType(field, nullConcreteType);
-    }
-
-    // if no call to super or redirect has been found, call the default
-    // constructor (if the current class is not Object).
-    if (!foundSuperOrRedirect) {
-      ClassElement superClass = enclosingClass.superclass;
-      if (enclosingClass != compiler.objectClass) {
-        FunctionElement target = superClass.lookupConstructor(
-            new Selector.callDefaultConstructor(enclosingClass.getLibrary()))
-                .implementation;
-        final superClassConcreteType = singletonConcreteType(
-            new ClassBaseType(enclosingClass));
-        getSendReturnType(selector, target, enclosingClass,
-            new ArgumentsTypes(new List(), new Map()));
-      }
-    }
-
-    if (tree != null) tree.accept(visitor);
-    return singletonConcreteType(new ClassBaseType(enclosingClass));
-  }
-
-  /**
-   * Hook that performs side effects on some special method calls (like
-   * [:List(length):]) and possibly returns a concrete type.
-   */
-  void handleSpecialMethod(FunctionElement element,
-                                   ConcreteTypesEnvironment environment) {
-    // When List([length]) is called with some length, we must augment
-    // listElementType with {null}.
-    if (element == listConstructor) {
-      Link<Element> parameters =
-          listConstructor.functionSignature.optionalParameters;
-      ConcreteType lengthType = environment.lookupType(parameters.head);
-      if (lengthType.baseTypes.contains(baseTypes.intBaseType)) {
-        augmentListElementType(nullConcreteType);
-      }
-    }
-  }
-
-  /* Initialization code that cannot be run in the constructor because it
-   * requires the compiler's elements to be populated.
-   */
-  void initialize() {
-    baseTypes = new BaseTypes(compiler);
-    ClassElement jsArrayClass = baseTypes.listBaseType.element;
-    listIndex = jsArrayClass.lookupMember('[]');
-    listIndexSet = jsArrayClass.lookupMember('[]=');
-    listAdd = jsArrayClass.lookupMember('add');
-    listRemoveAt = jsArrayClass.lookupMember('removeAt');
-    listInsert = jsArrayClass.lookupMember('insert');
-    listRemoveLast =
-        jsArrayClass.lookupMember('removeLast');
-    List<String> typePreservingOps = const ['+', '-', '*'];
-    listConstructor =
-        compiler.listClass.lookupConstructor(
-            new Selector.callConstructor(
-                '',
-                compiler.listClass.getLibrary())).implementation;
-    emptyConcreteType = new ConcreteType.empty(compiler.maxConcreteTypeSize,
-                                               baseTypes);
-    nullConcreteType = singletonConcreteType(const NullBaseType());
-    listElementType = emptyConcreteType;
-    concreteSeenClasses = compiler.enqueuer.resolution
-        .seenClasses
-        .where((cls) => !cls.isAbstract)
-        .toList()
-        ..add(baseTypes.numBaseType.element);
-    nativeTypesToConcreteTypes = new Map<ClassElement, ConcreteType>()
-        ..[compiler.nullClass] = nullConcreteType
-        ..[compiler.objectClass] = unknownConcreteType
-        ..[compiler.stringClass] =
-            singletonConcreteType(baseTypes.stringBaseType)
-        ..[compiler.intClass] = singletonConcreteType(baseTypes.intBaseType)
-        ..[compiler.doubleClass] =
-            singletonConcreteType(baseTypes.doubleBaseType)
-        ..[compiler.numClass] = singletonConcreteType(baseTypes.numBaseType)
-        ..[compiler.boolClass] = singletonConcreteType(baseTypes.boolBaseType);
-    nativeTypesToSeenClasses = new Map<dynamic, List<ClassElement>>()
-        ..[compiler.nullClass] = []
-        ..[compiler.objectClass] = concreteSeenClasses
-        ..[compiler.stringClass] = [baseTypes.stringBaseType.element]
-        ..[compiler.intClass] = [baseTypes.intBaseType.element]
-        ..[compiler.doubleClass] = [baseTypes.doubleBaseType.element]
-        ..[compiler.numClass] = [baseTypes.numBaseType.element,
-                                 baseTypes.intBaseType.element,
-                                 baseTypes.doubleBaseType.element]
-        ..[compiler.boolClass] = [baseTypes.boolBaseType.element];
-  }
-
-  /**
-   * Performs concrete type inference of the code reachable from [element].
-   * Returns [:true:] if and only if analysis succeeded.
-   */
-  bool analyzeMain(Element element) {
-    initialize();
-    try {
-      workQueue.addLast(
-          new InferenceWorkItem(element, new ConcreteTypesEnvironment(this)));
-      while (!workQueue.isEmpty) {
-        InferenceWorkItem item = workQueue.removeFirst();
-        if (item.methodOrField.isField()) {
-          analyze(null, item.methodOrField, item.environment);
-        } else {
-          Map<ConcreteTypesEnvironment, ConcreteType> template =
-              getTemplatesOrEmpty(item.methodOrField);
-          template.putIfAbsent(item.environment, () => emptyConcreteType);
-          ConcreteType concreteType =
-              analyze(null, item.methodOrField, item.environment);
-          if (template[item.environment] != concreteType) {
-            template[item.environment] = concreteType;
-            invalidateCallers(item.methodOrField);
-          }
-        }
-      }
-      return true;
-    } on CancelTypeInferenceException catch(e) {
-      if (LOG_FAILURES) {
-        compiler.log(e.reason);
-      }
-      return false;
-    }
-  }
-
-  /**
-   * Dumps debugging information on the standard output.
-   */
-  void debug() {
-    print("seen classes:");
-    for (ClassElement cls in seenClasses) {
-      print("  ${cls.name}");
-    }
-    print("callers:");
-    callers.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("dynamic callers:");
-    dynamicCallers.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("readers:");
-    readers.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("inferredFieldTypes:");
-    inferredFieldTypes.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("listElementType:");
-    print("  $listElementType");
-    print("inferredParameterTypes:");
-    inferredParameterTypes.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("inferred selector types:");
-    inferredSelectorTypes.forEach((selector, map) {
-      print("  $selector:");
-      map.forEach((k, v) {
-        print("    $k: $v");
-      });
-    });
-    print("cache:");
-    cache.forEach((k,v) {
-      print("  $k: $v");
-    });
-    print("inferred expression types:");
-    inferredTypes.forEach((k,v) {
-      print("  $k: $v");
-    });
-  }
-
-  /**
-   * Fail with a message and abort.
-   */
-  void fail(node, [reason]) {
-    String message = 'cannot infer types';
-    if (reason != null) {
-      message = '$message: $reason';
-    }
-    throw new CancelTypeInferenceException(node, message);
-  }
-}
-
-/**
- * Represents the concrete types of the arguments of a send, indexed by
- * position or name.
- */
-class ArgumentsTypes {
-  final List<ConcreteType> positional;
-  final Map<Identifier, ConcreteType> named;
-  ArgumentsTypes(this.positional, this.named);
-  int get length => positional.length + named.length;
-  toString() => "{ positional = $positional, named = $named }";
-}
-
-/**
- * The core logic of the type inference algorithm.
- */
-class TypeInferrerVisitor extends ResolvedVisitor<ConcreteType> {
-  final ConcreteTypesInferrer inferrer;
-  /// Invariant: backend = inferrer.compiler.backend
-  final Backend backend;
-
-  final Element currentMethodOrField;
-  ConcreteTypesEnvironment environment;
-  Node lastSeenNode;
-
-  TypeInferrerVisitor(TreeElements elements, this.currentMethodOrField,
-                      ConcreteTypesInferrer inferrer, this.environment)
-      : this.inferrer = inferrer
-      , this.backend = inferrer.compiler.backend
-      , super(elements, inferrer.compiler) {
-        for (Element element in elements.otherDependencies) {
-          if (element.isClass()) {
-            inferrer.augmentSeenClasses(inferrer.normalize(element));
-          } else {
-            FunctionElement functionElement = element;
-            List<ConcreteType> unknowns = new List.filled(
-                functionElement.computeSignature(inferrer.compiler)
-                               .requiredParameterCount,
-                inferrer.unknownConcreteType);
-            inferrer.getSendReturnType(
-                null,
-                functionElement,
-                functionElement.getEnclosingClass(),
-                new ArgumentsTypes(unknowns, new Map()));
-          }
-        }
-      }
-
-  ArgumentsTypes analyzeArguments(Link<Node> arguments) {
-    final positional = new List<ConcreteType>();
-    final named = new Map<Identifier, ConcreteType>();
-    for(Link<Node> iterator = arguments;
-        !iterator.isEmpty;
-        iterator = iterator.tail) {
-      Node node = iterator.head;
-      NamedArgument namedArgument = node.asNamedArgument();
-      if (namedArgument != null) {
-        named[namedArgument.name] = analyze(namedArgument.expression);
-      } else {
-        positional.add(analyze(node));
-      }
-    }
-    return new ArgumentsTypes(positional, named);
-  }
-
-  /**
-   * A proxy to accept which does book keeping and error reporting. Returns null
-   * if [node] is a non-returning statement, its inferred concrete type
-   * otherwise.
-   */
-  ConcreteType analyze(Node node) {
-    if (node == null) {
-      final String error = 'internal error: unexpected node: null';
-      inferrer.fail(lastSeenNode, error);
-    } else {
-      lastSeenNode = node;
-    }
-    ConcreteType result = node.accept(this);
-    if (result == null) {
-      inferrer.fail(node, 'internal error: inferred type is null');
-    }
-    inferrer.augmentInferredType(node, result);
-    return result;
-  }
-
-  ConcreteType visitBlock(Block node) {
-    return analyze(node.statements);
-  }
-
-  ConcreteType visitCascade(Cascade node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitCascadeReceiver(CascadeReceiver node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitClassNode(ClassNode node) {
-    inferrer.fail(node, 'not implemented');
-    return null;
-  }
-
-  ConcreteType visitDoWhile(DoWhile node) {
-    analyze(node.body);
-    analyze(node.condition);
-    ConcreteTypesEnvironment oldEnvironment;
-    do {
-      oldEnvironment = environment;
-      analyze(node.body);
-      analyze(node.condition);
-      environment = oldEnvironment.join(environment);
-    } while (oldEnvironment != environment);
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitExpressionStatement(ExpressionStatement node) {
-    analyze(node.expression);
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitFor(For node) {
-    if (node.initializer != null) {
-      analyze(node.initializer);
-    }
-    analyze(node.conditionStatement);
-    ConcreteTypesEnvironment oldEnvironment;
-    do {
-      oldEnvironment = environment;
-      analyze(node.conditionStatement);
-      analyze(node.body);
-      analyze(node.update);
-      environment = oldEnvironment.join(environment);
-    // TODO(polux): Maybe have a destructive join-method that returns a boolean
-    // value indicating whether something changed to avoid performing this
-    // comparison twice.
-    } while (oldEnvironment != environment);
-    return inferrer.emptyConcreteType;
-  }
-
-  void analyzeClosure(FunctionExpression node) {
-    for (VariableDefinitions definitions in node.parameters) {
-      for (Node parameter in definitions.definitions) {
-        environment = environment.put(elements[parameter],
-            inferrer.unknownConcreteType);
-      }
-    }
-    analyze(node.body);
-  }
-
-  ConcreteType visitFunctionDeclaration(FunctionDeclaration node) {
-    analyzeClosure(node.function);
-    environment = environment.put(elements[node],
-        inferrer.singletonConcreteType(inferrer.baseTypes.functionBaseType));
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitFunctionExpression(FunctionExpression node) {
-    // Naive handling of closures: we assume their body is always executed,
-    // and that each of their arguments has type dynamic.
-    // TODO(polux): treat closures as classes
-    if (node.name == null) {
-      analyzeClosure(node);
-      return inferrer.singletonConcreteType(
-          inferrer.baseTypes.functionBaseType);
-    } else {
-      return analyze(node.body);
-    }
-  }
-
-  ConcreteType visitIdentifier(Identifier node) {
-    if (node.isThis()) {
-      ConcreteType result = environment.lookupTypeOfThis();
-      if (result == null) {
-        inferrer.fail(node, '"this" has no type');
-      }
-      return result;
-    }
-    Element element = elements[node];
-    assert(element != null);
-    ConcreteType result = environment.lookupType(element);
-    if (result != null) {
-      assert(element.isParameter());
-      return result;
-    } else {
-      environment = environment.put(element, inferrer.nullConcreteType);
-      return inferrer.nullConcreteType;
-    }
-  }
-
-  ConcreteType visitIf(If node) {
-    analyze(node.condition);
-    ConcreteType thenType = analyze(node.thenPart);
-    ConcreteTypesEnvironment snapshot = environment;
-    ConcreteType elseType = node.hasElsePart ? analyze(node.elsePart)
-                                             : inferrer.emptyConcreteType;
-    environment = environment.join(snapshot);
-    return thenType.union(elseType);
-  }
-
-  ConcreteType visitLoop(Loop node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType analyzeSetElement(Selector selector,
-                                 Element receiver, ConcreteType argumentType) {
-    environment = environment.put(receiver, argumentType);
-    if (receiver.isField()) {
-      inferrer.augmentFieldType(receiver, argumentType);
-    } else if (receiver.isSetter()){
-      FunctionElement setter = receiver;
-      // TODO(polux): A setter always returns void so there's no need to
-      // invalidate its callers even if it is called with new arguments.
-      // However, if we start to record more than returned types, like
-      // exceptions for instance, we need to do it by uncommenting the following
-      // line.
-      // inferrer.addCaller(setter, currentMethod);
-      inferrer.getSendReturnType(selector, setter, receiver.enclosingElement,
-          new ArgumentsTypes([argumentType], new Map()));
-    }
-    return argumentType;
-  }
-
-  ConcreteType analyzeSetNode(Selector selector,
-                              Node receiver, ConcreteType argumentType,
-                              String name) {
-    ConcreteType receiverType = analyze(receiver);
-
-    void augmentField(ClassElement receiverType, Element member) {
-      if (member.isField()) {
-        inferrer.augmentFieldType(member, argumentType);
-      } else if (member.isAbstractField()){
-        AbstractFieldElement abstractField = member;
-        FunctionElement setter = abstractField.setter;
-        // TODO(polux): A setter always returns void so there's no need to
-        // invalidate its callers even if it is called with new arguments.
-        // However, if we start to record more than returned types, like
-        // exceptions for instance, we need to do it by uncommenting the
-        // following line.
-        // inferrer.addCaller(setter, currentMethod);
-        inferrer.getSendReturnType(selector, setter, receiverType,
-            new ArgumentsTypes([argumentType], new Map()));
-      }
-      // since this is a sendSet we ignore non-fields
-    }
-
-    if (receiverType.isUnknown()) {
-      inferrer.addDynamicCaller(name, currentMethodOrField);
-      for (Element member in inferrer.getMembersByName(name)) {
-        if (!(member.isField() || member.isAbstractField())) continue;
-        Element cls = member.getEnclosingClass();
-        augmentField(cls, member);
-      }
-    } else {
-      for (BaseType baseReceiverType in receiverType.baseTypes) {
-        if (!baseReceiverType.isClass()) continue;
-        ClassBaseType baseReceiverClassType = baseReceiverType;
-        Element member = baseReceiverClassType.element.lookupMember(name);
-        if (member != null) {
-          augmentField(baseReceiverClassType.element, member);
-        }
-      }
-    }
-    return argumentType;
-  }
-
-  String canonicalizeCompoundOperator(String op) {
-    // TODO(ahe): This class should work on elements or selectors, not
-    // names.  Otherwise, it is repeating work the resolver has
-    // already done (or should have done).  In this case, the problem
-    // is that the resolver is not recording the selectors it is
-    // registering in registerBinaryOperator in
-    // ResolverVisitor.visitSendSet.
-    if (op == '++') return '+';
-    else if (op == '--') return '-';
-    else return Elements.mapToUserOperatorOrNull(op);
-  }
-
-  ConcreteType visitSendSet(SendSet node) {
-    // Operator []= has a different behaviour than other send sets: it is
-    // actually a send whose return type is that of its second argument.
-    if (node.selector.asIdentifier().source == '[]') {
-      ConcreteType receiverType = analyze(node.receiver);
-      ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
-      analyzeDynamicSend(elements.getSelector(node), receiverType,
-                         '[]=', argumentsTypes);
-      return argumentsTypes.positional[1];
-    }
-
-    // All other operators have a single argument (++ and -- have an implicit
-    // argument: 1). We will store its type in argumentType.
-    ConcreteType argumentType;
-    String operatorName = node.assignmentOperator.source;
-    String compoundOperatorName =
-        canonicalizeCompoundOperator(node.assignmentOperator.source);
-    // ++, --, +=, -=, ...
-    if (compoundOperatorName != null) {
-      ConcreteType receiverType = visitGetterSendForSelector(node,
-          elements.getGetterSelectorInComplexSendSet(node));
-      // argumentsTypes is either computed from the actual arguments or [{int}]
-      // in case of ++ or --.
-      ArgumentsTypes argumentsTypes;
-      if (operatorName == '++' || operatorName == '--') {
-        List<ConcreteType> positionalArguments = <ConcreteType>[
-            inferrer.singletonConcreteType(inferrer.baseTypes.intBaseType)];
-        argumentsTypes = new ArgumentsTypes(positionalArguments, new Map());
-      } else {
-        argumentsTypes = analyzeArguments(node.arguments);
-      }
-      argumentType = analyzeDynamicSend(
-          elements.getOperatorSelectorInComplexSendSet(node),
-          receiverType,
-          compoundOperatorName,
-          argumentsTypes);
-    // The simple assignment case: receiver = argument.
-    } else {
-      argumentType = analyze(node.argumentsNode);
-    }
-
-    Element element = elements[node];
-    if (element != null) {
-      return analyzeSetElement(elements.getSelector(node),
-                               element, argumentType);
-    } else {
-      return analyzeSetNode(elements.getSelector(node),
-                            node.receiver, argumentType,
-                            node.selector.asIdentifier().source);
-    }
-  }
-
-  ConcreteType visitLiteralInt(LiteralInt node) {
-    inferrer.augmentSeenClasses(backend.intImplementation);
-    inferrer.augmentSeenClasses(backend.numImplementation);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.intBaseType);
-  }
-
-  ConcreteType visitLiteralDouble(LiteralDouble node) {
-    inferrer.augmentSeenClasses(backend.doubleImplementation);
-    inferrer.augmentSeenClasses(backend.numImplementation);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.doubleBaseType);
-  }
-
-  ConcreteType visitLiteralBool(LiteralBool node) {
-    inferrer.augmentSeenClasses(backend.boolImplementation);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
-  }
-
-  ConcreteType visitLiteralString(LiteralString node) {
-    // TODO(polux): get rid of this hack once we have a natural way of inferring
-    // the unknown type.
-    if (inferrer.testMode
-        && node.dartString.slowToString() == "__dynamic_for_test") {
-      return inferrer.unknownConcreteType;
-    }
-    inferrer.augmentSeenClasses(inferrer.compiler.stringClass);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
-  }
-
-  ConcreteType visitStringJuxtaposition(StringJuxtaposition node) {
-    analyze(node.first);
-    analyze(node.second);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
-  }
-
-  ConcreteType visitLiteralNull(LiteralNull node) {
-    return inferrer.nullConcreteType;
-  }
-
-  ConcreteType visitNewExpression(NewExpression node) {
-    Element constructor = elements[node.send].implementation;
-    inferrer.addCaller(constructor, currentMethodOrField);
-    ClassElement cls = constructor.enclosingElement;
-    return inferrer.getSendReturnType(null, constructor, cls,
-                                      analyzeArguments(node.send.arguments));
-  }
-
-  ConcreteType visitLiteralList(LiteralList node) {
-    ConcreteType elementsType = inferrer.emptyConcreteType;
-    // We compute the union of the types of the list literal's elements.
-    for (Link<Node> link = node.elements.nodes;
-         !link.isEmpty;
-         link = link.tail) {
-      elementsType = elementsType.union(analyze(link.head));
-    }
-    inferrer.augmentListElementType(elementsType);
-    inferrer.augmentSeenClasses(backend.listImplementation);
-    return inferrer.singletonConcreteType(
-        inferrer.baseTypes.growableListBaseType);
-  }
-
-  ConcreteType visitNodeList(NodeList node) {
-    ConcreteType type = inferrer.emptyConcreteType;
-    // The concrete type of a sequence of statements is the union of the
-    // statement's types.
-    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      type = type.union(analyze(link.head));
-    }
-    return type;
-  }
-
-  ConcreteType visitOperator(Operator node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitReturn(Return node) {
-    final expression = node.expression;
-    return (expression == null)
-        ? inferrer.nullConcreteType
-        : analyze(expression);
-  }
-
-  ConcreteType visitThrow(Throw node) {
-    if (node.expression != null) analyze(node.expression);
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitTypeAnnotation(TypeAnnotation node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitTypeVariable(TypeVariable node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitVariableDefinitions(VariableDefinitions node) {
-    for (Link<Node> link = node.definitions.nodes; !link.isEmpty;
-         link = link.tail) {
-      analyze(link.head);
-    }
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitWhile(While node) {
-    analyze(node.condition);
-    ConcreteTypesEnvironment oldEnvironment;
-    do {
-      oldEnvironment = environment;
-      analyze(node.condition);
-      analyze(node.body);
-      environment = oldEnvironment.join(environment);
-    } while (oldEnvironment != environment);
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitParenthesizedExpression(ParenthesizedExpression node) {
-    return analyze(node.expression);
-  }
-
-  ConcreteType visitConditional(Conditional node) {
-    analyze(node.condition);
-    ConcreteType thenType = analyze(node.thenExpression);
-    ConcreteType elseType = analyze(node.elseExpression);
-    return thenType.union(elseType);
-  }
-
-  ConcreteType visitModifiers(Modifiers node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitStringInterpolation(StringInterpolation node) {
-    node.visitChildren(this);
-    inferrer.augmentSeenClasses(inferrer.compiler.stringClass);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
-  }
-
-  ConcreteType visitStringInterpolationPart(StringInterpolationPart node) {
-    node.visitChildren(this);
-    inferrer.augmentSeenClasses(inferrer.compiler.stringClass);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
-  }
-
-  ConcreteType visitEmptyStatement(EmptyStatement node) {
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitBreakStatement(BreakStatement node) {
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitContinueStatement(ContinueStatement node) {
-    // TODO(polux): we can be more precise
-    return inferrer.emptyConcreteType;
-  }
-
-  ConcreteType visitForIn(ForIn node) {
-    Element declaredIdentifier = elements[node.declaredIdentifier];
-    assert(declaredIdentifier != null);
-    ConcreteType iterableType = analyze(node.expression);
-
-    // var n0 = e.iterator
-    ConcreteType iteratorType = analyzeDynamicGetterSend(
-        elements.getIteratorSelector(node),
-        iterableType);
-    ConcreteType result = inferrer.emptyConcreteType;
-    ConcreteTypesEnvironment oldEnvironment;
-    do {
-      oldEnvironment = environment;
-      // n0.moveNext();
-      analyzeDynamicSend(
-          elements.getMoveNextSelector(node),
-          iteratorType,
-          "moveNext",
-          new ArgumentsTypes(const [], const {}));
-      // id = n0.current
-      ConcreteType currentType = analyzeDynamicGetterSend(
-          elements.getCurrentSelector(node),
-          iteratorType);
-      environment = environment.put(declaredIdentifier, currentType);
-      result = result.union(analyze(node.body));
-      environment = oldEnvironment.join(environment);
-    } while (oldEnvironment != environment);
-    return result;
-  }
-
-  ConcreteType visitLabel(Label node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitLabeledStatement(LabeledStatement node) {
-    return analyze(node.statement);
-  }
-
-  ConcreteType visitLiteralMap(LiteralMap node) {
-    visitNodeList(node.entries);
-    inferrer.augmentSeenClasses(inferrer.compiler.mapClass);
-    return inferrer.singletonConcreteType(inferrer.baseTypes.mapBaseType);
-  }
-
-  ConcreteType visitLiteralMapEntry(LiteralMapEntry node) {
-    // We don't need to visit the key, it's always a string.
-    return analyze(node.value);
-  }
-
-  ConcreteType visitNamedArgument(NamedArgument node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitSwitchStatement(SwitchStatement node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitSwitchCase(SwitchCase node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitCaseMatch(CaseMatch node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitTryStatement(TryStatement node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitCatchBlock(CatchBlock node) {
-    inferrer.fail(node, 'not yet implemented');
-    return null;
-  }
-
-  ConcreteType visitTypedef(Typedef node) {
-    inferrer.fail(node, 'not implemented');
-    return null;
-  }
-
-  ConcreteType visitSuperSend(Send node) {
-    inferrer.fail(node, 'not implemented');
-    return null;
-  }
-
-  ConcreteType visitOperatorSend(Send node) {
-    String name =
-        canonicalizeMethodName(node.selector.asIdentifier().source);
-    if (name == 'is') {
-      return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
-    }
-    return visitDynamicSend(node);
-  }
-
-  ConcreteType analyzeFieldRead(Selector selector, Element field) {
-    inferrer.addReader(field, currentMethodOrField);
-    return inferrer.getFieldType(selector, field);
-  }
-
-  ConcreteType analyzeGetterSend(Selector selector,
-                                 ClassElement receiverType,
-                                 FunctionElement getter) {
-      inferrer.addCaller(getter, currentMethodOrField);
-      return inferrer.getSendReturnType(selector, getter, receiverType,
-                                        new ArgumentsTypes([], new Map()));
-  }
-
-  ConcreteType visitGetterSend(Send node) {
-    Selector selector = elements.getSelector(node);
-    return visitGetterSendForSelector(node, selector);
-  }
-
-  ConcreteType analyzeDynamicGetterSend(Selector selector,
-                                        ConcreteType receiverType) {
-    ConcreteType result = inferrer.emptyConcreteType;
-    void augmentResult(ClassElement baseReceiverType, Element member) {
-      if (member.isField()) {
-        result = result.union(analyzeFieldRead(selector, member));
-      } else if (member.isAbstractField()){
-        // call to a getter
-        AbstractFieldElement abstractField = member;
-        ConcreteType getterReturnType = analyzeGetterSend(
-            selector, baseReceiverType, abstractField.getter);
-        result = result.union(getterReturnType);
-      }
-      // since this is a get we ignore non-fields
-    }
-
-    if (receiverType.isUnknown()) {
-      inferrer.addDynamicCaller(selector.name, currentMethodOrField);
-      List<Element> members = inferrer.getMembersByName(selector.name);
-      for (Element member in members) {
-        Element cls = member.getEnclosingClass();
-        augmentResult(cls, member);
-      }
-    } else {
-      for (BaseType baseReceiverType in receiverType.baseTypes) {
-        if (!baseReceiverType.isNull()) {
-          ClassBaseType classBaseType = baseReceiverType;
-          ClassElement cls = classBaseType.element;
-          Element getterOrField = cls.lookupMember(selector.name);
-          if (getterOrField != null) {
-            augmentResult(cls, getterOrField.implementation);
-          }
-        }
-      }
-    }
-    return result;
-  }
-
-  ConcreteType visitGetterSendForSelector(Send node, Selector selector) {
-    Element element = elements[node];
-    if (element != null) {
-      // node is a local variable or a field of this
-      ConcreteType result = environment.lookupType(element);
-      if (result != null) {
-        // node is a local variable
-        return result;
-      } else {
-        // node is a field or a getter of this
-        if (element.isField()) {
-          return analyzeFieldRead(selector, element);
-        } else {
-          assert(element.isGetter());
-          ClassElement receiverType = element.enclosingElement;
-          return analyzeGetterSend(selector, receiverType, element);
-        }
-      }
-    } else {
-      // node is a field/getter which doesn't belong to the current class or
-      // the field/getter of a mixed-in class
-      ConcreteType receiverType = node.receiver != null
-          ? analyze(node.receiver)
-          : environment.lookupTypeOfThis();
-      return analyzeDynamicGetterSend(selector, receiverType);
-    }
-  }
-
-  ConcreteType visitClosureSend(Send node) {
-    return inferrer.unknownConcreteType;
-  }
-
-  ConcreteType analyzeDynamicSend(Selector selector,
-                                  ConcreteType receiverType,
-                                  String canonicalizedMethodName,
-                                  ArgumentsTypes argumentsTypes) {
-    ConcreteType result = inferrer.emptyConcreteType;
-
-    if (receiverType.isUnknown()) {
-      inferrer.addDynamicCaller(canonicalizedMethodName, currentMethodOrField);
-      List<Element> methods =
-          inferrer.getMembersByName(canonicalizedMethodName);
-      for (Element element in methods) {
-        // TODO(polux): when we handle closures, we must handle sends to fields
-        // that are closures.
-        if (!element.isFunction()) continue;
-        FunctionElement method = element;
-        inferrer.addCaller(method, currentMethodOrField);
-        Element cls = method.enclosingElement;
-        result = result.union(
-            inferrer.getSendReturnType(selector, method, cls, argumentsTypes));
-      }
-
-    } else {
-      for (BaseType baseReceiverType in receiverType.baseTypes) {
-        if (!baseReceiverType.isNull()) {
-          ClassBaseType classBaseReceiverType = baseReceiverType;
-          ClassElement cls = classBaseReceiverType.element;
-          FunctionElement method = cls.lookupMember(canonicalizedMethodName);
-          if (method != null) {
-            method = method.implementation;
-            inferrer.addCaller(method, currentMethodOrField);
-            result = result.union(
-                inferrer.getSendReturnType(selector, method, cls,
-                                           argumentsTypes));
-          }
-        }
-      }
-    }
-    return result;
-  }
-
-  String canonicalizeMethodName(String name) {
-    // TODO(polux): handle unary-
-    String operatorName = Elements.constructOperatorNameOrNull(name, false);
-    if (operatorName != null) return operatorName;
-    return name;
-  }
-
-  ConcreteType visitDynamicSend(Send node) {
-    ConcreteType receiverType = (node.receiver != null)
-        ? analyze(node.receiver)
-        : environment.lookupTypeOfThis();
-    String name = canonicalizeMethodName(node.selector.asIdentifier().source);
-    if (name == '!=') {
-      ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
-      ConcreteType returnType = analyzeDynamicSend(elements.getSelector(node),
-                                                   receiverType,
-                                                   '==',
-                                                   argumentsTypes);
-      return returnType.isEmpty()
-          ? returnType
-          : inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
-    } else if (name == '&&' || name == '||') {
-      ConcreteTypesEnvironment oldEnvironment = environment;
-      analyze(node.arguments.head);
-      environment = oldEnvironment.join(environment);
-      return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
-    } else {
-      ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
-      return analyzeDynamicSend(elements.getSelector(node),
-                                receiverType, name, argumentsTypes);
-    }
-  }
-
-  ConcreteType visitForeignSend(Send node) {
-    return inferrer.unknownConcreteType;
-  }
-
-  ConcreteType visitAssert(Send node) {
-    if (!compiler.enableUserAssertions) {
-      return inferrer.nullConcreteType;
-    } else {
-      return visitStaticSend(node);
-    }
-  }
-
-  ConcreteType visitStaticSend(Send node) {
-    if (elements.getSelector(node).name == 'JS') {
-      return inferrer.getNativeCallReturnType(node);
-    }
-    Element element = elements[node].implementation;
-    inferrer.addCaller(element, currentMethodOrField);
-    return inferrer.getSendReturnType(elements.getSelector(node),
-                                      element, null,
-                                      analyzeArguments(node.arguments));
-  }
-
-  void internalError(String reason, {Node node}) {
-    inferrer.fail(node, reason);
-  }
-
-  ConcreteType visitTypeReferenceSend(Send) {
-    return inferrer.singletonConcreteType(inferrer.baseTypes.typeBaseType);
-  }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index 39b99c2..dd25e09 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -65,8 +65,6 @@
     return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
   }
 
-  TypeMask simplify(Compiler compiler) => this;
-
   bool contains(ClassElement type, Compiler compiler) {
     assert(type.isDeclaration);
     if (isEmpty) {
@@ -606,10 +604,7 @@
     Set<ClassElement> subtypes = compiler.world.subtypesOf(y);
     if (subtypes != null && subtypes.contains(x)) return true;
     if (y != compiler.functionClass) return false;
-    // TODO(johnniwinther): Clean this up (function inheritance).
-    Member member =
-        x.lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
-    return member != null && member.isMethod;
+    return x.callType != null;
   }
 
   static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index 724c27c..145a066 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -97,7 +97,5 @@
     return forwardTo.locateSingleElement(selector, compiler);
   }
 
-  TypeMask simplify(Compiler compiler) => forwardTo.simplify(compiler);
-
   bool equalsDisregardNull(other);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 22dca73..9e02183 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -44,8 +44,6 @@
    */
   TypeMask nonNullable();
 
-  TypeMask simplify(Compiler compiler);
-
   bool get isEmpty;
   bool get isNullable;
   bool get isExact;
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 5b9999e..a44d78e 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -10,7 +10,7 @@
 import '../tree/tree.dart';
 import '../util/util.dart';
 import '../universe/universe.dart';
-import 'concrete_types_inferrer.dart' show ConcreteTypesInferrer;
+import '../inferrer/concrete_types_inferrer.dart' show ConcreteTypesInferrer;
 
 part 'container_type_mask.dart';
 part 'map_type_mask.dart';
@@ -37,7 +37,8 @@
  * The types task infers guaranteed types globally.
  */
 class TypesTask extends CompilerTask {
-  static final bool DUMP_SURPRISING_RESULTS = false;
+  static final bool DUMP_BAD_CPA_RESULTS = false;
+  static final bool DUMP_GOOD_CPA_RESULTS = false;
 
   final String name = 'Type inference';
   TypesInferrer typesInferrer;
@@ -220,121 +221,35 @@
     return nullTypeCache;
   }
 
-
-  /// Replaces native types by their backend implementation.
-  Element normalize(Element cls) {
-    if (cls == compiler.boolClass) {
-      return compiler.backend.boolImplementation;
-    }
-    if (cls == compiler.intClass) {
-      return compiler.backend.intImplementation;
-    }
-    if (cls == compiler.doubleClass) {
-      return compiler.backend.doubleImplementation;
-    }
-    if (cls == compiler.numClass) {
-      return compiler.backend.numImplementation;
-    }
-    if (cls == compiler.stringClass) {
-      return compiler.backend.stringImplementation;
-    }
-    if (cls == compiler.listClass) {
-      return compiler.backend.listImplementation;
-    }
-    return cls;
+  /** Helper method for [intersection]. */
+  TypeMask _intersection(TypeMask type1, TypeMask type2) {
+    if (type1 == null) return type2;
+    if (type2 == null) return type1;
+    return type1.intersection(type2, compiler);
   }
 
-  /// Checks that two types are the same modulo normalization.
-  bool same(ClassElement type1, ClassElement type2) {
-    return (type1 == type2) || normalize(type1) == normalize(type2);
-  }
-
-  /**
-   * Checks that one of [type1] and [type2] is a subtype of the other.
-   */
-  bool related(ClassElement type1, ClassElement type2) {
-    return compiler.types.isSubtype(type1.rawType, type2.rawType)
-        || compiler.types.isSubtype(type2.rawType, type1.rawType);
-  }
-
-  /**
-   * Return the more precise of both types, giving precedence in that order to
-   * exactness, subclassing, subtyping and nullability. The [element] parameter
-   * is for debugging purposes only and can be omitted.
-   */
-  FlatTypeMask best(TypeMask type1, TypeMask type2, [element]) {
-    // TODO(polux): Handle [UnionTypeMask].
-    if (type1 != null) type1 = type1.simplify(compiler);
-    if (type2 != null) type2 = type2.simplify(compiler);
-    FlatTypeMask result = _best(type1, type2);
-    // Tests type1 and type2 for equality modulo normalization of native types.
-    // Only called when DUMP_SURPRISING_RESULTS is true.
-    bool similar() {
-      if (type1 == null || type2 == null || type1.isEmpty || type2.isEmpty) {
-        return type1 == type2;
-      }
-      FlatTypeMask flat1 = type1;
-      FlatTypeMask flat2 = type2;
-      return same(flat1.base, flat2.base);
+  /** Computes the intersection of [type1] and [type2] */
+  TypeMask intersection(TypeMask type1, TypeMask type2, element) {
+    TypeMask result = _intersection(type1, type2);
+    if (DUMP_BAD_CPA_RESULTS && better(type1, type2)) {
+      print("CPA is worse for $element: $type1 /\ $type2 = $result");
     }
-    if (DUMP_SURPRISING_RESULTS && result == type1 && !similar()) {
-      print("$type1 better than $type2 for $element");
+    if (DUMP_GOOD_CPA_RESULTS && better(type2, type1)) {
+      print("CPA is better for $element: $type1 /\ $type2 = $result");
     }
     return result;
   }
 
-  /// Helper method for [best].
-  FlatTypeMask _best(var type1, var type2) {
-    if (type1 == null) return type2;
-    if (type2 == null) return type1;
-    FlatTypeMask flat1 = type1.isContainer ? type1.asFlat : type1;
-    FlatTypeMask flat2 = type2.isContainer ? type2.asFlat : type2;
-    if (flat1.isExact) {
-      if (flat2.isExact) {
-        // TODO(polux): Update the code to not have this situation.
-        if (flat1.base != flat2.base) return flat1;
-        assert(same(flat1.base, flat2.base));
-        return flat1.isNullable ? flat2 : flat1;
-      } else {
-        return flat1;
-      }
-    } else if (flat2.isExact) {
-      return flat2;
-    } else if (flat1.isSubclass) {
-      if (flat2.isSubclass) {
-        assert(related(flat1.base, flat2.base));
-        if (same(flat1.base, flat2.base)) {
-          return flat1.isNullable ? flat2 : flat1;
-        } else if (compiler.types.isSubtype(flat1.base.rawType,
-                                            flat2.base.rawType)) {
-          return flat1;
-        } else {
-          return flat2;
-        }
-      } else {
-        return flat1;
-      }
-    } else if (flat2.isSubclass) {
-      return flat2;
-    } else if (flat1.isSubtype) {
-      if (flat2.isSubtype) {
-        assert(related(flat1.base, flat2.base));
-        if (same(flat1.base, flat2.base)) {
-          return flat1.isNullable ? flat2 : flat1;
-        } else if (compiler.types.isSubtype(flat1.base.rawType,
-                                            flat2.base.rawType)) {
-          return flat1;
-        } else {
-          return flat2;
-        }
-      } else {
-        return flat1;
-      }
-    } else if (flat2.isSubtype) {
-      return flat2;
-    } else {
-      return flat1.isNullable ? flat2 : flat1;
+  /** Returns true if [type1] is strictly bettern than [type2]. */
+  bool better(TypeMask type1, TypeMask type2) {
+    if (type1 == null) return false;
+    if (type2 == null) {
+      return (type1 != null) &&
+             (type1 != new TypeMask.subclass(compiler.objectClass));
     }
+    return (type1 != type2) &&
+           type2.containsMask(type1, compiler) &&
+           !type1.containsMask(type2, compiler);
   }
 
   /**
@@ -364,9 +279,9 @@
       TypeMask guaranteedType = typesInferrer.getTypeOfElement(element);
       return (concreteTypesInferrer == null)
           ? guaranteedType
-          : best(guaranteedType,
-                 concreteTypesInferrer.getTypeOfElement(element),
-                 element);
+          : intersection(guaranteedType,
+                         concreteTypesInferrer.getTypeOfElement(element),
+                         element);
     });
   }
 
@@ -376,9 +291,9 @@
           typesInferrer.getReturnTypeOfElement(element);
       return (concreteTypesInferrer == null)
           ? guaranteedType
-          : best(guaranteedType,
-                 concreteTypesInferrer.getReturnTypeOfElement(element),
-                 element);
+          : intersection(guaranteedType,
+                         concreteTypesInferrer.getReturnTypeOfElement(element),
+                         element);
     });
   }
 
@@ -391,9 +306,9 @@
       TypeMask guaranteedType = typesInferrer.getTypeOfNode(owner, node);
       return (concreteTypesInferrer == null)
           ? guaranteedType
-          : best(guaranteedType,
-                 concreteTypesInferrer.getTypeOfNode(owner, node),
-                 node);
+          : intersection(guaranteedType,
+                         concreteTypesInferrer.getTypeOfNode(owner, node),
+                         node);
     });
   }
 
@@ -406,9 +321,9 @@
           typesInferrer.getTypeOfSelector(selector);
       return (concreteTypesInferrer == null)
           ? guaranteedType
-          : best(guaranteedType,
-                 concreteTypesInferrer.getTypeOfSelector(selector),
-                 selector);
+          : intersection(guaranteedType,
+                         concreteTypesInferrer.getTypeOfSelector(selector),
+                         selector);
     });
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index b17938d..cf1951a 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -188,8 +188,6 @@
     return new UnionTypeMask._(newIterable);
   }
 
-  TypeMask simplify(Compiler compiler) => flatten(disjointMasks, compiler);
-
   bool get isEmpty => false;
   bool get isNullable => disjointMasks.any((e) => e.isNullable);
   bool get isExact => false;
diff --git a/sdk/lib/_internal/compiler/implementation/use_unused_api.dart b/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
index 7dfac97..eb3f390 100644
--- a/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
+++ b/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
@@ -22,7 +22,7 @@
 
 import 'js/js.dart' as js;
 
-import 'types/concrete_types_inferrer.dart' as concrete_types_inferrer;
+import 'inferrer/concrete_types_inferrer.dart' as concrete_types_inferrer;
 
 import 'colors.dart' as colors;
 
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index e1d1406..0b51aed 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -115,58 +115,64 @@
   int maxLineNoLength = 0;
   int maxColumnNoLength = 0;
 
+  String stackTrace = '$s';
   List<_StackTraceLine> lines = <_StackTraceLine>[];
-  for (String line in '$s'.split('\n')) {
-    index++;
-    if (rangeStart != null && index < rangeStart) continue;
-    if (rangeEnd != null && index > rangeEnd) continue;
-    if (line.isEmpty) continue;
+  for (String line in stackTrace.split('\n')) {
+    try {
+      index++;
+      if (rangeStart != null && index < rangeStart) continue;
+      if (rangeEnd != null && index > rangeEnd) continue;
+      if (line.isEmpty) continue;
 
-    // Strip index.
-    line = line.replaceFirst(new RegExp(r'#\d+\s*'), '');
+      // Strip index.
+      line = line.replaceFirst(new RegExp(r'#\d+\s*'), '');
 
-    int leftParenPos = line.indexOf('(');
-    int rightParenPos = line.indexOf(')', leftParenPos);
-    int lastColon = line.lastIndexOf(':', rightParenPos);
-    int nextToLastColon = line.lastIndexOf(':', lastColon-1);
+      int leftParenPos = line.indexOf('(');
+      int rightParenPos = line.indexOf(')', leftParenPos);
+      int lastColon = line.lastIndexOf(':', rightParenPos);
+      int nextToLastColon = line.lastIndexOf(':', lastColon-1);
 
-    String lineNo;
-    String columnNo;
-    if (nextToLastColon != -1) {
-      lineNo = line.substring(nextToLastColon+1, lastColon);
-      columnNo = line.substring(lastColon+1, rightParenPos);
-      try {
-        int.parse(lineNo);
-      } on FormatException catch (e) {
-        lineNo = columnNo;
+      String lineNo;
+      String columnNo;
+      if (nextToLastColon != -1) {
+        lineNo = line.substring(nextToLastColon+1, lastColon);
+        columnNo = line.substring(lastColon+1, rightParenPos);
+        try {
+          int.parse(lineNo);
+        } on FormatException catch (e) {
+          lineNo = columnNo;
+          columnNo = '';
+          nextToLastColon = lastColon;
+        }
+      } else {
+        lineNo = line.substring(lastColon+1, rightParenPos);
         columnNo = '';
         nextToLastColon = lastColon;
       }
-    } else {
-      lineNo = line.substring(lastColon+1, rightParenPos);
-      columnNo = '';
-      nextToLastColon = lastColon;
-    }
 
-    if (lineNo.length > maxLineNoLength) {
-      maxLineNoLength = lineNo.length;
-    }
-    if (columnNo.length > maxColumnNoLength) {
-      maxColumnNoLength = columnNo.length;
-    }
+      if (lineNo.length > maxLineNoLength) {
+        maxLineNoLength = lineNo.length;
+      }
+      if (columnNo.length > maxColumnNoLength) {
+        maxColumnNoLength = columnNo.length;
+      }
 
-    String file = line.substring(leftParenPos+1, nextToLastColon);
-    if (filePrefix != null && file.startsWith(filePrefix)) {
-      file = file.substring(filePrefix.length);
+      String file = line.substring(leftParenPos+1, nextToLastColon);
+      if (filePrefix != null && file.startsWith(filePrefix)) {
+        file = file.substring(filePrefix.length);
+      }
+      if (file.length > maxFileLength) {
+        maxFileLength = file.length;
+      }
+      String method = line.substring(0, leftParenPos-1);
+      if (lambda != null) {
+        method = method.replaceAll('<anonymous closure>', lambda);
+      }
+      lines.add(new _StackTraceLine(index, file, lineNo, columnNo, method));
+    } catch (e) {
+      print('Error prettifying "$line": $e');
+      return stackTrace;
     }
-    if (file.length > maxFileLength) {
-      maxFileLength = file.length;
-    }
-    String method = line.substring(0, leftParenPos-1);
-    if (lambda != null) {
-      method = method.replaceAll('<anonymous closure>', lambda);
-    }
-    lines.add(new _StackTraceLine(index, file, lineNo, columnNo, method));
   }
 
   StringBuffer sb = new StringBuffer();
@@ -181,7 +187,6 @@
     sb.write('  $file $lineNo$columnNo $method\n');
     dots = !dots;
   }
-
   return sb.toString();
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 014e40a..8cef76f 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -9,50 +9,45 @@
 /**
  * The messages in this file should meet the following guide lines:
  *
- * 1. The message should start with exactly one of "Error", "Internal error",
- * "Warning", "Info", or "Hint" followed by a colon. It is crucial to users to
- * be able to locate errors in the midst of warnings.
- * TODO(ahe): Remove these prefixes from the error message.
+ * 1. The message should be a complete sentence starting with an uppercase
+ * letter, and ending with a period.
  *
- * 2. After the colon, one space and a complete sentence starting with an
- * uppercase letter, and ending with a period.
- *
- * 3. Reserved words and embedded identifiers should be in single quotes, so
- * prefer double quotes for the complete message. For example, "Error: The
+ * 2. Reserved words and embedded identifiers should be in single quotes, so
+ * prefer double quotes for the complete message. For example, "The
  * class '#{className}' can't use 'super'." Notice that the word 'class' in the
  * preceding message is not quoted as it refers to the concept 'class', not the
  * reserved word. On the other hand, 'super' refers to the reserved word. Do
  * not quote 'null' and numeric literals.
  *
- * 4. Do not try to compose messages, as it can make translating them hard.
+ * 3. Do not try to compose messages, as it can make translating them hard.
  *
- * 5. Try to keep the error messages short, but informative.
+ * 4. Try to keep the error messages short, but informative.
  *
- * 6. Use simple words and terminology, assume the reader of the message
+ * 5. Use simple words and terminology, assume the reader of the message
  * doesn't have an advanced degree in math, and that English is not the
  * reader's native language. Do not assume any formal computer science
  * training. For example, do not use Latin abbreviations (prefer "that is" over
  * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
  * only if" and "iff", that level of precision is unnecessary.
  *
- * 7. Prefer contractions when they are in common use, for example, prefer
+ * 6. Prefer contractions when they are in common use, for example, prefer
  * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
  * off-putting to people new to programming.
  *
- * 8. Use common terminology, preferably from the Dart Language
+ * 7. Use common terminology, preferably from the Dart Language
  * Specification. This increases the user's chance of finding a good
  * explanation on the web.
  *
- * 9. Do not try to be cute or funny. It is extremely frustrating to work on a
+ * 8. Do not try to be cute or funny. It is extremely frustrating to work on a
  * product that crashes with a "tongue-in-cheek" message, especially if you did
  * not want to use this product to begin with with.
  *
- * 10. Do not lie, that is, do not write error messages containing phrases like
+ * 9. Do not lie, that is, do not write error messages containing phrases like
  * "can't happen".  If the user ever saw this message, it would be a
  * lie. Prefer messages like: "Internal error: This function should not be
  * called when 'x' is null.".
  *
- * 11. Prefer to not use imperative tone. That is, the message should not sound
+ * 10. Prefer to not use imperative tone. That is, the message should not sound
  * accusing or like it is ordering the user around. The computer should
  * describe the problem, not criticize for violating the specification.
  *
@@ -93,88 +88,81 @@
   /// above.
   static const MessageKind GENERIC = const MessageKind('#{text}');
 
-  static const DualKind NOT_ASSIGNABLE = const DualKind(
-      error: const MessageKind(
-          "Error: '#{fromType}' is not assignable to '#{toType}'."),
-      warning: const MessageKind(
-          "Warning: '#{fromType}' is not assignable to '#{toType}'."));
+  static const MessageKind NOT_ASSIGNABLE = const MessageKind(
+      "'#{fromType}' is not assignable to '#{toType}'.");
 
   static const MessageKind VOID_EXPRESSION = const MessageKind(
-      "Warning: Expression does not yield a value.");
+      "Expression does not yield a value.");
 
   static const MessageKind VOID_VARIABLE = const MessageKind(
-      "Warning: Variable cannot be of type void.");
+      "Variable cannot be of type void.");
 
   static const MessageKind RETURN_VALUE_IN_VOID = const MessageKind(
-      "Warning: Cannot return value from void function.");
+      "Cannot return value from void function.");
 
   static const MessageKind RETURN_NOTHING = const MessageKind(
-      "Warning: Value of type '#{returnType}' expected.");
+      "Value of type '#{returnType}' expected.");
 
   static const MessageKind MISSING_ARGUMENT = const MessageKind(
-      "Warning: Missing argument of type '#{argumentType}'.");
+      "Missing argument of type '#{argumentType}'.");
 
   static const MessageKind ADDITIONAL_ARGUMENT = const MessageKind(
-      "Warning: Additional argument.");
+      "Additional argument.");
 
   static const MessageKind NAMED_ARGUMENT_NOT_FOUND = const MessageKind(
-      "Warning: No named argument '#{argumentName}' found on method.");
+      "No named argument '#{argumentName}' found on method.");
 
-  static const DualKind MEMBER_NOT_FOUND = const DualKind(
-      error: const MessageKind(
-          "Error: No member named '#{memberName}' in class '#{className}'."),
-      warning: const MessageKind(
-          "Warning: No member named '#{memberName}' in class '#{className}'."));
+  static const MessageKind MEMBER_NOT_FOUND = const MessageKind(
+      "No member named '#{memberName}' in class '#{className}'.");
 
   static const MessageKind METHOD_NOT_FOUND = const MessageKind(
-      "Warning: No method named '#{memberName}' in class '#{className}'.");
+      "No method named '#{memberName}' in class '#{className}'.");
 
   static const MessageKind OPERATOR_NOT_FOUND = const MessageKind(
-      "Warning: No operator '#{memberName}' in class '#{className}'.");
+      "No operator '#{memberName}' in class '#{className}'.");
 
-  static const MessageKind PROPERTY_NOT_FOUND = const MessageKind(
-      "Warning: No property named '#{memberName}' in class '#{className}'.");
+  static const MessageKind SETTER_NOT_FOUND = const MessageKind(
+      "No setter named '#{memberName}' in class '#{className}'.");
+
+  static const MessageKind GETTER_NOT_FOUND = const MessageKind(
+      "No getter named '#{memberName}' in class '#{className}'.");
 
   static const MessageKind NOT_CALLABLE = const MessageKind(
-      "Warning: '#{elementName}' is not callable.");
+      "'#{elementName}' is not callable.");
 
-  static const DualKind MEMBER_NOT_STATIC = const DualKind(
-      error: const MessageKind(
-          "Error: '#{className}.#{memberName}' is not static."),
-      warning: const MessageKind(
-          "Warning: '#{className}.#{memberName}' is not static."));
+  static const MessageKind MEMBER_NOT_STATIC = const MessageKind(
+      "'#{className}.#{memberName}' is not static.");
 
   static const MessageKind NO_INSTANCE_AVAILABLE = const MessageKind(
-      "Error: '#{name}' is only available in instance methods.");
+      "'#{name}' is only available in instance methods.");
 
   static const MessageKind PRIVATE_ACCESS = const MessageKind(
-      "Warning: '#{name}' is declared private within library "
+      "'#{name}' is declared private within library "
       "'#{libraryName}'.");
 
   static const MessageKind THIS_IS_THE_DECLARATION = const MessageKind(
-      "Info: This is the declaration of '#{name}'.");
+      "This is the declaration of '#{name}'.");
 
   static const MessageKind THIS_IS_THE_METHOD = const MessageKind(
-      "Info: This is the method declaration.");
+      "This is the method declaration.");
 
   static const MessageKind UNREACHABLE_CODE = const MessageKind(
-      "Warning: Unreachable code.");
+      "Unreachable code.");
 
   static const MessageKind MISSING_RETURN = const MessageKind(
-      "Warning: Missing return.");
+      "Missing return.");
 
   static const MessageKind MAYBE_MISSING_RETURN = const MessageKind(
-      "Warning: Not all paths lead to a return or throw statement.");
+      "Not all paths lead to a return or throw statement.");
 
-  static const DualKind CANNOT_RESOLVE = const DualKind(
-      error: const MessageKind("Error: Cannot resolve '#{name}'."),
-      warning: const MessageKind("Warning: Cannot resolve '#{name}'."));
+  static const MessageKind CANNOT_RESOLVE = const MessageKind(
+      "Cannot resolve '#{name}'.");
 
   static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
-      "Error: Cannot resolve constructor '#{constructorName}'.");
+      "Cannot resolve constructor '#{constructorName}'.");
 
   static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT =
-      const MessageKind("Error: cannot resolve constructor '#{constructorName}'"
+      const MessageKind("cannot resolve constructor '#{constructorName}'"
           " for implicit super call.",
       howToFix: "Try explicitly invoking a constructor of the super class",
       examples: const ["""
@@ -188,28 +176,25 @@
 """]);
 
   static const MessageKind INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
-      "Error: Unnamed constructor name must be '#{name}'.");
+      "Unnamed constructor name must be '#{name}'.");
 
   static const MessageKind INVALID_CONSTRUCTOR_NAME = const MessageKind(
-      "Error: Constructor name must start with '#{name}'.");
+      "Constructor name must start with '#{name}'.");
 
-  static const DualKind CANNOT_RESOLVE_TYPE = const DualKind(
-      error: const MessageKind("Error: Cannot resolve type '#{typeName}'."),
-      warning: const MessageKind(
-          "Warning: Cannot resolve type '#{typeName}'."));
+  static const MessageKind CANNOT_RESOLVE_TYPE = const MessageKind(
+      "Cannot resolve type '#{typeName}'.");
 
   static const MessageKind DUPLICATE_DEFINITION = const MessageKind(
-      "Error: Duplicate definition of '#{name}'.");
+      "Duplicate definition of '#{name}'.");
 
   static const MessageKind EXISTING_DEFINITION = const MessageKind(
-      "Info: Existing definition of '#{name}'.");
+      "Existing definition of '#{name}'.");
 
-  static const DualKind DUPLICATE_IMPORT = const DualKind(
-      error: const MessageKind("Error: Duplicate import of '#{name}'."),
-      warning: const MessageKind("Warning: Duplicate import of '#{name}'."));
+  static const MessageKind DUPLICATE_IMPORT = const MessageKind(
+      "Duplicate import of '#{name}'.");
 
   static const MessageKind HIDDEN_IMPORT = const MessageKind(
-      "Warning: '#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+      "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
       "from library '#{hidingUri}'.",
       howToFix: "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
       examples: const [
@@ -277,7 +262,7 @@
 
 
   static const MessageKind HIDDEN_IMPLICIT_IMPORT = const MessageKind(
-      "Warning: '#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+      "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
       "from library '#{hidingUri}'.",
       howToFix: "Try adding an explicit "
                 "'import \"#{hiddenUri}\" hide #{name}'.",
@@ -327,7 +312,7 @@
 """}]);
 
   static const MessageKind DUPLICATE_EXPORT = const MessageKind(
-      "Error: Duplicate export of '#{name}'.",
+      "Duplicate export of '#{name}'.",
       howToFix: "Trying adding 'hide #{name}' to one of the exports.",
       examples: const [const {
 'main.dart': """
@@ -339,68 +324,64 @@
 'decl2.dart': "class Class {}"}]);
 
   static const MessageKind DUPLICATE_EXPORT_CONT = const MessageKind(
-      "Info: This is another export of '#{name}'.");
+      "This is another export of '#{name}'.");
 
   static const MessageKind DUPLICATE_EXPORT_DECL = const MessageKind(
-      "Info: The exported '#{name}' from export #{uriString} is defined here.");
+      "The exported '#{name}' from export #{uriString} is defined here.");
 
-  static const DualKind NOT_A_TYPE = const DualKind(
-      error: const MessageKind("Error: '#{node}' is not a type."),
-      warning: const MessageKind("Warning: '#{node}' is not a type."));
+  static const MessageKind NOT_A_TYPE = const MessageKind(
+      "'#{node}' is not a type.");
 
   static const MessageKind NOT_A_PREFIX = const MessageKind(
-      "Error: '#{node}' is not a prefix.");
+      "'#{node}' is not a prefix.");
 
-  static const DualKind CANNOT_FIND_CONSTRUCTOR = const DualKind(
-      error: const MessageKind(
-          "Error: Cannot find constructor '#{constructorName}'."),
-      warning: const MessageKind(
-          "Warning: Cannot find constructor '#{constructorName}'."));
+  static const MessageKind CANNOT_FIND_CONSTRUCTOR = const MessageKind(
+      "Cannot find constructor '#{constructorName}'.");
 
   static const MessageKind CYCLIC_CLASS_HIERARCHY = const MessageKind(
-      "Error: '#{className}' creates a cycle in the class hierarchy.");
+      "'#{className}' creates a cycle in the class hierarchy.");
 
   static const MessageKind CYCLIC_REDIRECTING_FACTORY = const MessageKind(
-      'Error: Redirecting factory leads to a cyclic redirection.');
+      'Redirecting factory leads to a cyclic redirection.');
 
   static const MessageKind INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
-      "Error: Field initializer expected.");
+      "Field initializer expected.");
 
   static const MessageKind NO_SUPER_IN_STATIC = const MessageKind(
-      "Error: 'super' is only available in instance methods.");
+      "'super' is only available in instance methods.");
 
   static const MessageKind DUPLICATE_INITIALIZER = const MessageKind(
-      "Error: Field '#{fieldName}' is initialized more than once.");
+      "Field '#{fieldName}' is initialized more than once.");
 
   static const MessageKind ALREADY_INITIALIZED = const MessageKind(
-      "Info: '#{fieldName}' was already initialized here.");
+      "'#{fieldName}' was already initialized here.");
 
   static const MessageKind INIT_STATIC_FIELD = const MessageKind(
-      "Error: Cannot initialize static field '#{fieldName}'.");
+      "Cannot initialize static field '#{fieldName}'.");
 
   static const MessageKind NOT_A_FIELD = const MessageKind(
-      "Error: '#{fieldName}' is not a field.");
+      "'#{fieldName}' is not a field.");
 
   static const MessageKind CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
-      "Error: only call to 'this' or 'super' constructor allowed.");
+      "only call to 'this' or 'super' constructor allowed.");
 
   static const MessageKind INVALID_FOR_IN = const MessageKind(
-      "Error: Invalid for-in variable declaration.");
+      "Invalid for-in variable declaration.");
 
   static const MessageKind INVALID_INITIALIZER = const MessageKind(
-      "Error: Invalid initializer.");
+      "Invalid initializer.");
 
   static const MessageKind FUNCTION_WITH_INITIALIZER = const MessageKind(
-      "Error: Only constructors can have initializers.");
+      "Only constructors can have initializers.");
 
   static const MessageKind REDIRECTING_CONSTRUCTOR_CYCLE = const MessageKind(
-      "Error: Cyclic constructor redirection.");
+      "Cyclic constructor redirection.");
 
   static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_BODY = const MessageKind(
-      "Error: Redirecting constructor can't have a body.");
+      "Redirecting constructor can't have a body.");
 
   static const MessageKind CONST_CONSTRUCTOR_HAS_BODY = const MessageKind(
-      "Error: Const constructor or factory can't have a body.",
+      "Const constructor or factory can't have a body.",
       howToFix: "Remove the 'const' keyword or the body",
       examples: const ["""
 class C {
@@ -411,36 +392,31 @@
 
   static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER =
       const MessageKind(
-          "Error: Redirecting constructor cannot have other initializers.");
+          "Redirecting constructor cannot have other initializers.");
 
   static const MessageKind SUPER_INITIALIZER_IN_OBJECT = const MessageKind(
-      "Error: 'Object' cannot have a super initializer.");
+      "'Object' cannot have a super initializer.");
 
   static const MessageKind DUPLICATE_SUPER_INITIALIZER = const MessageKind(
-      "Error: Cannot have more than one super initializer.");
+      "Cannot have more than one super initializer.");
 
-  static const DualKind INVALID_ARGUMENTS = const DualKind(
-      error: const MessageKind(
-          "Error: Arguments do not match the expected parameters of "
-          "'#{methodName}'."),
-      warning: const MessageKind(
-          "Warning: Arguments do not match the expected parameters of "
-          "'#{methodName}'."));
+  static const MessageKind INVALID_ARGUMENTS = const MessageKind(
+      "Arguments do not match the expected parameters of '#{methodName}'.");
 
   static const MessageKind NO_MATCHING_CONSTRUCTOR = const MessageKind(
-      "Error: 'super' call arguments and constructor parameters do not match.");
+      "'super' call arguments and constructor parameters do not match.");
 
   static const MessageKind NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT =
       const MessageKind(
-          "Error: Implicit 'super' call arguments and constructor parameters "
+          "Implicit 'super' call arguments and constructor parameters "
           "do not match.");
 
   static const MessageKind CONST_CALLS_NON_CONST = const MessageKind(
-      "Error: 'const' constructor cannot call a non-const constructor.");
+      "'const' constructor cannot call a non-const constructor.");
 
   static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS =
       const MessageKind(
-          "Error: Can't declare constructor 'const' on class #{className} "
+          "Can't declare constructor 'const' on class #{className} "
           "because the class contains non-final instance fields.",
           howToFix: "Try making all fields final.",
           examples: const ["""
@@ -453,86 +429,80 @@
 main() => new C(0);"""]);
 
   static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD =
-      const MessageKind("Info: This non-final field prevents using const "
+      const MessageKind("This non-final field prevents using const "
                         "constructors.");
 
   static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR =
-      const MessageKind("Info: This const constructor is not allowed due to "
+      const MessageKind("This const constructor is not allowed due to "
                         "non-final fields.");
 
 
   static const MessageKind INITIALIZING_FORMAL_NOT_ALLOWED = const MessageKind(
-      "Error: Initializing formal parameter only allowed in generative "
+      "Initializing formal parameter only allowed in generative "
       "constructor.");
 
   static const MessageKind INVALID_PARAMETER = const MessageKind(
-      "Error: Cannot resolve parameter.");
+      "Cannot resolve parameter.");
 
   static const MessageKind NOT_INSTANCE_FIELD = const MessageKind(
-      "Error: '#{fieldName}' is not an instance field.");
+      "'#{fieldName}' is not an instance field.");
 
   static const MessageKind NO_CATCH_NOR_FINALLY = const MessageKind(
-      "Error: Expected 'catch' or 'finally'.");
+      "Expected 'catch' or 'finally'.");
 
   static const MessageKind EMPTY_CATCH_DECLARATION = const MessageKind(
-      "Error: Expected an identifier in catch declaration.");
+      "Expected an identifier in catch declaration.");
 
   static const MessageKind EXTRA_CATCH_DECLARATION = const MessageKind(
-      "Error: Extra parameter in catch declaration.");
+      "Extra parameter in catch declaration.");
 
   static const MessageKind PARAMETER_WITH_TYPE_IN_CATCH = const MessageKind(
-      "Error: Cannot use type annotations in catch.");
+      "Cannot use type annotations in catch.");
 
   static const MessageKind PARAMETER_WITH_MODIFIER_IN_CATCH = const MessageKind(
-      "Error: Cannot use modifiers in catch.");
+      "Cannot use modifiers in catch.");
 
   static const MessageKind OPTIONAL_PARAMETER_IN_CATCH = const MessageKind(
-      "Error: Cannot use optional parameters in catch.");
+      "Cannot use optional parameters in catch.");
 
   static const MessageKind THROW_WITHOUT_EXPRESSION = const MessageKind(
-      "Error: Cannot use re-throw outside of catch block "
+      "Cannot use re-throw outside of catch block "
       "(expression expected after 'throw').");
 
   static const MessageKind UNBOUND_LABEL = const MessageKind(
-      "Error: Cannot resolve label '#{labelName}'.");
+      "Cannot resolve label '#{labelName}'.");
 
   static const MessageKind NO_BREAK_TARGET = const MessageKind(
-      "Error: 'break' statement not inside switch or loop.");
+      "'break' statement not inside switch or loop.");
 
   static const MessageKind NO_CONTINUE_TARGET = const MessageKind(
-      "Error: 'continue' statement not inside loop.");
+      "'continue' statement not inside loop.");
 
   static const MessageKind EXISTING_LABEL = const MessageKind(
-      "Info: Original declaration of duplicate label '#{labelName}'.");
+      "Original declaration of duplicate label '#{labelName}'.");
 
-  static const DualKind DUPLICATE_LABEL = const DualKind(
-      error: const MessageKind(
-          "Error: Duplicate declaration of label '#{labelName}'."),
-      warning: const MessageKind(
-          "Warning: Duplicate declaration of label '#{labelName}'."));
+  static const MessageKind DUPLICATE_LABEL = const MessageKind(
+      "Duplicate declaration of label '#{labelName}'.");
 
   static const MessageKind UNUSED_LABEL = const MessageKind(
-      "Warning: Unused label '#{labelName}'.");
+      "Unused label '#{labelName}'.");
 
   static const MessageKind INVALID_CONTINUE = const MessageKind(
-      "Error: Target of continue is not a loop or switch case.");
+      "Target of continue is not a loop or switch case.");
 
   static const MessageKind INVALID_BREAK = const MessageKind(
-      "Error: Target of break is not a statement.");
+      "Target of break is not a statement.");
 
   static const MessageKind DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
-      "Error: Type variable '#{typeVariableName}' already declared.");
+      "Type variable '#{typeVariableName}' already declared.");
 
-  static const DualKind TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const DualKind(
-      error: const MessageKind(
-          "Error: Cannot refer to type variable '#{typeVariableName}' "
-          "within a static member."),
-      warning: const MessageKind(
-          "Warning: Cannot refer to type variable '#{typeVariableName}' "
-          "within a static member."));
+  static const MessageKind TYPE_VARIABLE_WITHIN_STATIC_MEMBER =
+      const MessageKind(
+          "Cannot refer to type variable '#{typeVariableName}' "
+          "within a static member.");
 
   static const MessageKind TYPE_VARIABLE_IN_CONSTANT = const MessageKind(
-      "Error: Constant expressions can't refer to type variables.",
+      "Constant expressions can't refer to type variables.",
       howToFix: "Try removing the type variable or replacing it with a "
                 "concrete type.",
       examples: const ["""
@@ -548,7 +518,7 @@
 
 
   static const MessageKind INVALID_TYPE_VARIABLE_BOUND = const MessageKind(
-      "Warning: '#{typeArgument}' is not a subtype of bound '#{bound}' for "
+      "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
       "type variable '#{typeVariable}' of type '#{thisType}'.",
       howToFix: "Try to change or remove the type argument.",
       examples: const ["""
@@ -559,47 +529,44 @@
 """]);
 
   static const MessageKind INVALID_USE_OF_SUPER = const MessageKind(
-      "Error: 'super' not allowed here.");
+      "'super' not allowed here.");
 
   static const MessageKind INVALID_CASE_DEFAULT = const MessageKind(
-      "Error: 'default' only allowed on last case of a switch.");
+      "'default' only allowed on last case of a switch.");
 
   static const MessageKind SWITCH_CASE_TYPES_NOT_EQUAL = const MessageKind(
-      "Error: 'case' expressions do not all have type '#{type}'.");
+      "'case' expressions do not all have type '#{type}'.");
 
   static const MessageKind SWITCH_CASE_TYPES_NOT_EQUAL_CASE = const MessageKind(
-      "Info: 'case' expression of type '#{type}'.");
+      "'case' expression of type '#{type}'.");
 
   static const MessageKind SWITCH_CASE_VALUE_OVERRIDES_EQUALS =
       const MessageKind(
-          "Error: 'case' expression type '#{type}' overrides 'operator =='.");
+          "'case' expression type '#{type}' overrides 'operator =='.");
 
   static const MessageKind INVALID_ARGUMENT_AFTER_NAMED = const MessageKind(
-      "Error: Unnamed argument after named argument.");
+      "Unnamed argument after named argument.");
 
   static const MessageKind NOT_A_COMPILE_TIME_CONSTANT = const MessageKind(
-      "Error: Not a compile-time constant.");
+      "Not a compile-time constant.");
 
   static const MessageKind CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
-      "Error: Cycle in the compile-time constant computation.");
+      "Cycle in the compile-time constant computation.");
 
   static const MessageKind CONSTRUCTOR_IS_NOT_CONST = const MessageKind(
-      "Error: Constructor is not a 'const' constructor.");
+      "Constructor is not a 'const' constructor.");
 
   static const MessageKind KEY_NOT_A_STRING_LITERAL = const MessageKind(
-      "Error: Map-literal key not a string literal.");
+      "Map-literal key not a string literal.");
 
-  static const DualKind NO_SUCH_LIBRARY_MEMBER = const DualKind(
-      error: const MessageKind(
-          "Error: '#{libraryName}' has no member named '#{memberName}'."),
-      warning: const MessageKind(
-          "Warning: '#{libraryName}' has no member named '#{memberName}'."));
+  static const MessageKind NO_SUCH_LIBRARY_MEMBER = const MessageKind(
+      "'#{libraryName}' has no member named '#{memberName}'.");
 
   static const MessageKind CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
-      "Error: Cannot instantiate typedef '#{typedefName}'.");
+      "Cannot instantiate typedef '#{typedefName}'.");
 
   static const MessageKind REQUIRED_PARAMETER_WITH_DEFAULT = const MessageKind(
-      "Error: Non-optional parameters can't have a default value.",
+      "Non-optional parameters can't have a default value.",
       howToFix:
         "Try removing the default value or making the parameter optional.",
       examples: const ["""
@@ -613,7 +580,7 @@
 }"""]);
 
   static const MessageKind NAMED_PARAMETER_WITH_EQUALS = const MessageKind(
-      "Error: Named optional parameters can't use '=' to specify a default "
+      "Named optional parameters can't use '=' to specify a default "
       "value.",
       howToFix: "Try replacing '=' with ':'.",
       examples: const ["""
@@ -623,7 +590,7 @@
 }"""]);
 
   static const MessageKind POSITIONAL_PARAMETER_WITH_EQUALS = const MessageKind(
-      "Error: Positional optional parameters can't use ':' to specify a "
+      "Positional optional parameters can't use ':' to specify a "
       "default value.",
       howToFix: "Try replacing ':' with '='.",
       examples: const ["""
@@ -633,7 +600,7 @@
 }"""]);
 
   static const MessageKind TYPEDEF_FORMAL_WITH_DEFAULT = const MessageKind(
-      "Error: A parameter of a typedef can't specify a default value.",
+      "A parameter of a typedef can't specify a default value.",
       howToFix:
         "Try removing the default value.",
       examples: const ["""
@@ -649,7 +616,7 @@
 }"""]);
 
   static const MessageKind FUNCTION_TYPE_FORMAL_WITH_DEFAULT = const MessageKind(
-      "Error: A function type parameter can't specify a default value.",
+      "A function type parameter can't specify a default value.",
       howToFix:
         "Try removing the default value.",
       examples: const ["""
@@ -665,7 +632,7 @@
 }"""]);
 
   static const MessageKind REDIRECTING_FACTORY_WITH_DEFAULT = const MessageKind(
-      "Error: A parameter of a redirecting factory constructor can't specify a "
+      "A parameter of a redirecting factory constructor can't specify a "
       "default value.",
       howToFix:
         "Try removing the default value.",
@@ -688,7 +655,7 @@
 }"""]);
 
   static const MessageKind FORMAL_DECLARED_CONST = const MessageKind(
-      "Error: A formal parameter can't be declared const.",
+      "A formal parameter can't be declared const.",
       howToFix: "Try removing 'const'.",
       examples: const ["""
 foo(const x) {}
@@ -702,7 +669,7 @@
 """]);
 
   static const MessageKind FORMAL_DECLARED_STATIC = const MessageKind(
-      "Error: A formal parameter can't be declared static.",
+      "A formal parameter can't be declared static.",
       howToFix: "Try removing 'static'.",
       examples: const ["""
 foo(static x) {}
@@ -716,7 +683,7 @@
 """]);
 
   static const MessageKind FINAL_FUNCTION_TYPE_PARAMETER = const MessageKind(
-      "Error: A function type parameter can't be declared final.",
+      "A function type parameter can't be declared final.",
       howToFix: "Try removing 'final'.",
       examples: const ["""
 foo(final int x(int a)) {}
@@ -730,7 +697,7 @@
 """]);
 
   static const MessageKind VAR_FUNCTION_TYPE_PARAMETER = const MessageKind(
-      "Error: A function type parameter can't be declared with 'var'.",
+      "A function type parameter can't be declared with 'var'.",
       howToFix: "Try removing 'var'.",
       examples: const ["""
 foo(var int x(int a)) {}
@@ -744,13 +711,13 @@
 """]);
 
   static const MessageKind CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
-      "Error: Cannot instantiate type variable '#{typeVariableName}'.");
+      "Cannot instantiate type variable '#{typeVariableName}'.");
 
   static const MessageKind CYCLIC_TYPE_VARIABLE = const MessageKind(
-      "Warning: Type variable '#{typeVariableName}' is a supertype of itself.");
+      "Type variable '#{typeVariableName}' is a supertype of itself.");
 
   static const CYCLIC_TYPEDEF = const MessageKind(
-      "Error: A typedef can't refer to itself.",
+      "A typedef can't refer to itself.",
       howToFix: "Try removing all references to '#{typedefName}' "
                 "in the definition of '#{typedefName}'.",
       examples: const ["""
@@ -758,7 +725,7 @@
 main() { F f = null; }"""]);
 
   static const CYCLIC_TYPEDEF_ONE = const MessageKind(
-      "Error: A typedef can't refer to itself through another typedef.",
+      "A typedef can't refer to itself through another typedef.",
       howToFix: "Try removing all references to "
                 "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
       examples: const ["""
@@ -772,16 +739,16 @@
 main() { F f = null; }"""]);
 
   static const MessageKind CLASS_NAME_EXPECTED = const MessageKind(
-      "Error: Class name expected.");
+      "Class name expected.");
 
   static const MessageKind CANNOT_EXTEND = const MessageKind(
-      "Error: '#{type}' cannot be extended.");
+      "'#{type}' cannot be extended.");
 
   static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
-      "Error: '#{type}' cannot be implemented.");
+      "'#{type}' cannot be implemented.");
 
   static const MessageKind CANNOT_EXTEND_MALFORMED = const MessageKind(
-      "Error: A class can't extend a malformed type.",
+      "A class can't extend a malformed type.",
       howToFix: "Try correcting the malformed type annotation or removing the "
         "'extends' clause.",
       examples: const ["""
@@ -789,7 +756,7 @@
 main() => new A();"""]);
 
   static const MessageKind CANNOT_IMPLEMENT_MALFORMED = const MessageKind(
-      "Error: A class can't implement a malformed type.",
+      "A class can't implement a malformed type.",
       howToFix: "Try correcting the malformed type annotation or removing the "
         "type from the 'implements' clause.",
       examples: const ["""
@@ -797,7 +764,7 @@
 main() => new A();"""]);
 
   static const MessageKind CANNOT_MIXIN_MALFORMED = const MessageKind(
-      "Error: A class can't mixin a malformed type.",
+      "A class can't mixin a malformed type.",
       howToFix: "Try correcting the malformed type annotation or removing the "
         "type from the 'with' clause.",
       examples: const ["""
@@ -805,7 +772,7 @@
 main() => new A();"""]);
 
   static const MessageKind CANNOT_MIXIN = const MessageKind(
-      "Error: The type '#{type}' can't be mixed in.",
+      "The type '#{type}' can't be mixed in.",
       howToFix: "Try removing '#{type}' from the 'with' clause.",
       examples: const ["""
 class C extends Object with String {}
@@ -818,190 +785,183 @@
 """]);
 
   static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
-      "Error: '#{type}' can not be both extended and implemented.");
+      "'#{type}' can not be both extended and implemented.");
 
   static const MessageKind DUPLICATE_IMPLEMENTS = const MessageKind(
-      "Error: '#{type}' must not occur more than once "
+      "'#{type}' must not occur more than once "
       "in the implements clause.");
 
   static const MessageKind MULTI_INHERITANCE = const MessageKind(
-      "Internal Error: Inheritance of the same class with different type "
+      "Inheritance of the same class with different type "
       "arguments is not supported: Both #{firstType} and #{secondType} are "
       "supertypes of #{thisType}.");
 
   static const MessageKind ILLEGAL_SUPER_SEND = const MessageKind(
-      "Error: '#{name}' cannot be called on super.");
+      "'#{name}' cannot be called on super.");
 
-  static const DualKind NO_SUCH_SUPER_MEMBER = const DualKind(
-      error: const MessageKind(
-          "Error: Cannot resolve '#{memberName}' in a superclass of "
-          "'#{className}'."),
-      warning: const MessageKind(
-          "Warning: Cannot resolve '#{memberName}' in a superclass of "
-          "'#{className}'."));
+  static const MessageKind NO_SUCH_SUPER_MEMBER = const MessageKind(
+      "Cannot resolve '#{memberName}' in a superclass of '#{className}'.");
 
-  static const DualKind ADDITIONAL_TYPE_ARGUMENT = const DualKind(
-      error: const MessageKind("Error: Additional type argument."),
-      warning: const MessageKind("Warning: Additional type argument."));
+  static const MessageKind ADDITIONAL_TYPE_ARGUMENT = const MessageKind(
+      "Additional type argument.");
 
-  static const DualKind MISSING_TYPE_ARGUMENT = const DualKind(
-      error: const MessageKind("Error: Missing type argument."),
-      warning: const MessageKind("Warning: Missing type argument."));
+  static const MessageKind MISSING_TYPE_ARGUMENT = const MessageKind(
+      "Missing type argument.");
 
   // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or MISSING_TYPE_ARGUMENT
   // instead.
   static const MessageKind TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
-      "Error: Incorrect number of type arguments on '#{type}'.");
+      "Incorrect number of type arguments on '#{type}'.");
 
   static const MessageKind GETTER_MISMATCH = const MessageKind(
-      "Error: Setter disagrees on: '#{modifiers}'.");
+      "Setter disagrees on: '#{modifiers}'.");
 
   static const MessageKind SETTER_MISMATCH = const MessageKind(
-      "Error: Getter disagrees on: '#{modifiers}'.");
+      "Getter disagrees on: '#{modifiers}'.");
 
   static const MessageKind ILLEGAL_SETTER_FORMALS = const MessageKind(
-      "Error: A setter must have exactly one argument.");
+      "A setter must have exactly one argument.");
 
   static const MessageKind NO_STATIC_OVERRIDE = const MessageKind(
-      "Error: Static member cannot override instance member '#{memberName}' of "
+      "Static member cannot override instance member '#{memberName}' of "
       "'#{className}'.");
 
   static const MessageKind NO_STATIC_OVERRIDE_CONT = const MessageKind(
-      "Info: This is the instance member that cannot be overridden "
+      "This is the instance member that cannot be overridden "
       "by a static member.");
 
   static const MessageKind INSTANCE_STATIC_SAME_NAME = const MessageKind(
-      "Warning: Instance member '#{memberName}' and static member of "
+      "Instance member '#{memberName}' and static member of "
       "superclass '#{className}' have the same name.");
 
   static const MessageKind INSTANCE_STATIC_SAME_NAME_CONT = const MessageKind(
-      "Info: This is the static member with the same name.");
+      "This is the static member with the same name.");
 
   static const MessageKind INVALID_OVERRIDE_METHOD = const MessageKind(
-      "Warning: The type '#{declaredType}' of method '#{name}' declared in "
+      "The type '#{declaredType}' of method '#{name}' declared in "
       "'#{class}' is not a subtype of the overridden method type "
       "'#{inheritedType}' inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDDEN_METHOD = const MessageKind(
-      "Info: This is the overridden method '#{name}' declared in class "
+      "This is the overridden method '#{name}' declared in class "
       "'#{class}'.");
 
   static const MessageKind INVALID_OVERRIDE_GETTER = const MessageKind(
-      "Warning: The type '#{declaredType}' of getter '#{name}' declared in "
+      "The type '#{declaredType}' of getter '#{name}' declared in "
       "'#{class}' is not assignable to the type '#{inheritedType}' of the "
       "overridden getter inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDDEN_GETTER = const MessageKind(
-      "Info: This is the overridden getter '#{name}' declared in class "
+      "This is the overridden getter '#{name}' declared in class "
       "'#{class}'.");
 
   static const MessageKind INVALID_OVERRIDE_GETTER_WITH_FIELD =
       const MessageKind(
-          "Warning: The type '#{declaredType}' of field '#{name}' declared in "
+          "The type '#{declaredType}' of field '#{name}' declared in "
           "'#{class}' is not assignable to the type '#{inheritedType}' of the "
           "overridden getter inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDE_FIELD_WITH_GETTER =
       const MessageKind(
-          "Warning: The type '#{declaredType}' of getter '#{name}' declared in "
+          "The type '#{declaredType}' of getter '#{name}' declared in "
           "'#{class}' is not assignable to the type '#{inheritedType}' of the "
           "overridden field inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDE_SETTER = const MessageKind(
-      "Warning: The type '#{declaredType}' of setter '#{name}' declared in "
+      "The type '#{declaredType}' of setter '#{name}' declared in "
       "'#{class}' is not assignable to the type '#{inheritedType}' of the "
       "overridden setter inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDDEN_SETTER = const MessageKind(
-      "Info: This is the overridden setter '#{name}' declared in class "
+      "This is the overridden setter '#{name}' declared in class "
       "'#{class}'.");
 
   static const MessageKind INVALID_OVERRIDE_SETTER_WITH_FIELD =
       const MessageKind(
-          "Warning: The type '#{declaredType}' of field '#{name}' declared in "
+          "The type '#{declaredType}' of field '#{name}' declared in "
           "'#{class}' is not assignable to the type '#{inheritedType}' of the "
           "overridden setter inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDE_FIELD_WITH_SETTER =
       const MessageKind(
-          "Warning: The type '#{declaredType}' of setter '#{name}' declared in "
+          "The type '#{declaredType}' of setter '#{name}' declared in "
           "'#{class}' is not assignable to the type '#{inheritedType}' of the "
           "overridden field inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDE_FIELD = const MessageKind(
-      "Warning: The type '#{declaredType}' of field '#{name}' declared in "
+      "The type '#{declaredType}' of field '#{name}' declared in "
       "'#{class}' is not assignable to the type '#{inheritedType}' of the "
       "overridden field inherited from '#{inheritedClass}'.");
 
   static const MessageKind INVALID_OVERRIDDEN_FIELD = const MessageKind(
-      "Info: This is the overridden field '#{name}' declared in class "
+      "This is the overridden field '#{name}' declared in class "
       "'#{class}'.");
 
   static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD =
       const MessageKind(
-          "Error: Method '#{name}' in '#{class}' can't override field from "
+          "Method '#{name}' in '#{class}' can't override field from "
           "'#{inheritedClass}'.");
 
   static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT =
       const MessageKind(
-          "Info: This is the field that cannot be overridden by a method.");
+          "This is the field that cannot be overridden by a method.");
 
   static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD =
       const MessageKind(
-          "Error: Field '#{name}' in '#{class}' can't override method from "
+          "Field '#{name}' in '#{class}' can't override method from "
           "'#{inheritedClass}'.");
 
   static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT =
       const MessageKind(
-          "Info: This is the method that cannot be overridden by a field.");
+          "This is the method that cannot be overridden by a field.");
 
   static const MessageKind CANNOT_OVERRIDE_GETTER_WITH_METHOD =
       const MessageKind(
-          "Error: Method '#{name}' in '#{class}' can't override getter from "
+          "Method '#{name}' in '#{class}' can't override getter from "
           "'#{inheritedClass}'.");
 
   static const MessageKind CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT =
       const MessageKind(
-          "Info: This is the getter that cannot be overridden by a method.");
+          "This is the getter that cannot be overridden by a method.");
 
   static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_GETTER =
       const MessageKind(
-          "Error: Getter '#{name}' in '#{class}' can't override method from "
+          "Getter '#{name}' in '#{class}' can't override method from "
           "'#{inheritedClass}'.");
 
   static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT =
       const MessageKind(
-          "Info: This is the method that cannot be overridden by a getter.");
+          "This is the method that cannot be overridden by a getter.");
 
   static const MessageKind MISSING_FORMALS = const MessageKind(
-      "Error: Formal parameters are missing.");
+      "Formal parameters are missing.");
 
   static const MessageKind EXTRA_FORMALS = const MessageKind(
-      "Error: Formal parameters are not allowed here.");
+      "Formal parameters are not allowed here.");
 
   static const MessageKind UNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator '#{operatorName}' must have no parameters.");
+      "Operator '#{operatorName}' must have no parameters.");
 
   static const MessageKind MINUS_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator '-' must have 0 or 1 parameters.");
+      "Operator '-' must have 0 or 1 parameters.");
 
   static const MessageKind BINARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator '#{operatorName}' must have exactly 1 parameter.");
+      "Operator '#{operatorName}' must have exactly 1 parameter.");
 
   static const MessageKind TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator '#{operatorName}' must have exactly 2 parameters.");
+      "Operator '#{operatorName}' must have exactly 2 parameters.");
 
   static const MessageKind OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
-      "Error: Operator '#{operatorName}' cannot have optional parameters.");
+      "Operator '#{operatorName}' cannot have optional parameters.");
 
   static const MessageKind OPERATOR_NAMED_PARAMETERS = const MessageKind(
-      "Error: Operator '#{operatorName}' cannot have named parameters.");
+      "Operator '#{operatorName}' cannot have named parameters.");
 
   static const MessageKind CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
-      "Error: Cannot have return type for constructor.");
+      "Cannot have return type for constructor.");
 
   static const MessageKind CANNOT_RETURN_FROM_CONSTRUCTOR = const MessageKind(
-      "Error: Constructors can't return values.",
+      "Constructors can't return values.",
       howToFix: "Remove the return statement or use a factory constructor.",
       examples: const ["""
 class C {
@@ -1013,57 +973,52 @@
 main() => new C();"""]);
 
   static const MessageKind ILLEGAL_FINAL_METHOD_MODIFIER = const MessageKind(
-      "Error: Cannot have final modifier on method.");
+      "Cannot have final modifier on method.");
 
   static const MessageKind ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
-      "Error: Illegal constructor modifiers: '#{modifiers}'.");
+      "Illegal constructor modifiers: '#{modifiers}'.");
 
   static const MessageKind ILLEGAL_MIXIN_APPLICATION_MODIFIERS =
       const MessageKind(
-          "Error: Illegal mixin application modifiers: '#{modifiers}'.");
+          "Illegal mixin application modifiers: '#{modifiers}'.");
 
   static const MessageKind ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
-      "Error: Class used as mixin must have Object as superclass.");
+      "Class used as mixin must have Object as superclass.");
 
   static const MessageKind ILLEGAL_MIXIN_OBJECT = const MessageKind(
-      "Error: Cannot use Object as mixin.");
+      "Cannot use Object as mixin.");
 
   static const MessageKind ILLEGAL_MIXIN_CONSTRUCTOR = const MessageKind(
-      "Error: Class used as mixin cannot have non-factory constructor.");
+      "Class used as mixin cannot have non-factory constructor.");
 
   static const MessageKind ILLEGAL_MIXIN_CYCLE = const MessageKind(
-      "Error: Class used as mixin introduces mixin cycle: "
+      "Class used as mixin introduces mixin cycle: "
       "'#{mixinName1}' <-> '#{mixinName2}'.");
 
   static const MessageKind ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
-      "Error: Cannot use class '#{className}' as a mixin because it uses "
+      "Cannot use class '#{className}' as a mixin because it uses "
       "'super'.");
 
   static const MessageKind ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
-      "Info: Use of 'super' in class used as mixin.");
+      "Use of 'super' in class used as mixin.");
 
   static const MessageKind PARAMETER_NAME_EXPECTED = const MessageKind(
-      "Error: parameter name expected.");
+      "parameter name expected.");
 
-  static const DualKind CANNOT_RESOLVE_GETTER = const DualKind(
-      error: const MessageKind("Error: Cannot resolve getter."),
-      warning: const MessageKind("Warning: Cannot resolve getter."));
+  static const MessageKind CANNOT_RESOLVE_GETTER = const MessageKind(
+      "Cannot resolve getter.");
 
-  static const DualKind CANNOT_RESOLVE_SETTER = const DualKind(
-      error: const MessageKind("Error: Cannot resolve setter."),
-      warning: const MessageKind("Warning: Cannot resolve setter."));
+  static const MessageKind CANNOT_RESOLVE_SETTER = const MessageKind(
+      "Cannot resolve setter.");
 
-  static const DualKind ASSIGNING_METHOD = const DualKind(
-      error: const MessageKind("Error: Cannot resolve setter."),
-      warning:
-        const MessageKind("Warning: Cannot assign a value to a method."));
+  static const MessageKind ASSIGNING_METHOD = const MessageKind(
+      "Cannot assign a value to a method.");
 
-  static const DualKind ASSIGNING_TYPE = const DualKind(
-      error: const MessageKind("Error: Cannot resolve setter."),
-      warning: const MessageKind("Warning: Cannot assign a value to a type."));
+  static const MessageKind ASSIGNING_TYPE = const MessageKind(
+      "Cannot assign a value to a type.");
 
   static const MessageKind VOID_NOT_ALLOWED = const MessageKind(
-      "Error: Type 'void' can't be used here because it isn't a return type.",
+      "Type 'void' can't be used here because it isn't a return type.",
       howToFix: "Try removing 'void' keyword or replace it with 'var', 'final',"
           " or a type.",
       examples: const [
@@ -1072,13 +1027,13 @@
       ]);
 
   static const MessageKind NULL_NOT_ALLOWED = const MessageKind(
-      "Error: `null` can't be used here.");
+      "`null` can't be used here.");
 
   static const MessageKind BEFORE_TOP_LEVEL = const MessageKind(
-      "Error: Part header must come before top-level definitions.");
+      "Part header must come before top-level definitions.");
 
   static const MessageKind LIBRARY_NAME_MISMATCH = const MessageKind(
-      "Warning: Expected part of library name '#{libraryName}'.",
+      "Expected part of library name '#{libraryName}'.",
       howToFix: "Trying changing the directive to 'part of #{libraryName};'.",
       examples: const [const {
 'main.dart': """
@@ -1094,7 +1049,7 @@
 """}]);
 
   static const MessageKind MISSING_LIBRARY_NAME = const MessageKind(
-      "Warning: Library has no name. Part directive expected library name "
+      "Library has no name. Part directive expected library name "
       "to be '#{libraryName}'.",
       howToFix: "Trying adding 'library #{libraryName};' to the library.",
       examples: const [const {
@@ -1109,19 +1064,19 @@
 """}]);
 
   static const MessageKind THIS_IS_THE_PART_OF_TAG = const MessageKind(
-      "Info: This is the part of directive.");
+      "This is the part of directive.");
 
   static const MessageKind MISSING_PART_OF_TAG = const MessageKind(
-      "Error: This file has no part-of tag, but it is being used as a part.");
+      "This file has no part-of tag, but it is being used as a part.");
 
   static const MessageKind DUPLICATED_PART_OF = const MessageKind(
-      "Error: Duplicated part-of directive.");
+      "Duplicated part-of directive.");
 
   static const MessageKind ILLEGAL_DIRECTIVE = const MessageKind(
-      "Error: Directive not allowed here.");
+      "Directive not allowed here.");
 
   static const MessageKind DUPLICATED_LIBRARY_NAME = const MessageKind(
-      "Warning: Duplicated library name '#{libraryName}'.");
+      "Duplicated library name '#{libraryName}'.");
 
   // This is used as an exception.
   static const MessageKind INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
@@ -1131,10 +1086,10 @@
 
   static const MessageKind TOP_LEVEL_VARIABLE_DECLARED_STATIC =
       const MessageKind(
-          "Error: Top-level variable cannot be declared static.");
+          "Top-level variable cannot be declared static.");
 
   static const MessageKind REFERENCE_IN_INITIALIZATION = const MessageKind(
-       "Error: Variable '#{variableName}' is referenced during its "
+       "Variable '#{variableName}' is referenced during its "
        "initialization.",
        howToFix: "If you are trying to reference a shadowed variable, rename"
          " one of the variables.",
@@ -1148,7 +1103,7 @@
 """]);
 
   static const MessageKind CONST_WITHOUT_INITIALIZER = const MessageKind(
-      "Error: A constant variable must be initialized.",
+      "A constant variable must be initialized.",
       howToFix: "Try adding an initializer or "
                 "removing the 'const' modifier.",
       examples: const ["""
@@ -1157,14 +1112,14 @@
 }"""]);
 
   static const MessageKind FINAL_WITHOUT_INITIALIZER = const MessageKind(
-      "Error: A final variable must be initialized.",
+      "A final variable must be initialized.",
       howToFix: "Try adding an initializer or "
                 "removing the 'final' modifier.",
       examples: const [
           "class C { static final field; } main() => C.field;"]);
 
   static const MessageKind MEMBER_USES_CLASS_NAME = const MessageKind(
-      "Error: Member variable can't have the same name as the class it is "
+      "Member variable can't have the same name as the class it is "
       "declared in.",
       howToFix: "Try renaming the variable.",
       examples: const ["""
@@ -1180,64 +1135,76 @@
 
   static const MessageKind WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT =
       const MessageKind(
-          "Error: Wrong number of arguments to assert. Should be 1, but given "
+          "Wrong number of arguments to assert. Should be 1, but given "
           "#{argumentCount}.");
 
   static const MessageKind ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
-      "Error: 'assert' takes no named arguments, but given #{argumentCount}.");
+      "'assert' takes no named arguments, but given #{argumentCount}.");
 
   static const MessageKind FACTORY_REDIRECTION_IN_NON_FACTORY =
       const MessageKind(
-          "Error: Factory redirection only allowed in factories.");
+          "Factory redirection only allowed in factories.");
 
   static const MessageKind MISSING_FACTORY_KEYWORD = const MessageKind(
-      "Hint: Did you forget a factory keyword here?");
+      "Did you forget a factory keyword here?");
 
   static const MessageKind DEFERRED_LIBRARY_NOT_FROM_MAIN =
       const MessageKind(
-          "Info: DeferredLibrary used as an annotation here, "
+          "DeferredLibrary used as an annotation here, "
           "but not used in the main library. Will not split the output.",
           howToFix:
             "Try adding a '@DeferredLibrary(...)' annotation in the main "
             "library");
 
+  static const MessageKind DEFERRED_LIBRARY_WITHOUT_PREFIX =
+      const MessageKind(
+          "This import is deferred but there is no prefix keyword.",
+          howToFix:
+            "Try adding a prefix to the import.");
+
+  static const MessageKind DEFERRED_LIBRARY_DUPLICATE_PREFIX =
+      const MessageKind(
+          "The prefix of this deferred import is not unique.",
+          howToFix:
+            "Try changing the import prefix.");
+
   static const MessageKind ILLEGAL_STATIC = const MessageKind(
-      "Error: Modifier static is only allowed on functions declared in "
+      "Modifier static is only allowed on functions declared in "
       "a class.");
 
   static const MessageKind STATIC_FUNCTION_BLOAT = const MessageKind(
-      "Hint: Using '#{class}.#{name}' may lead to unnecessarily large "
+      "Using '#{class}.#{name}' may lead to unnecessarily large "
       "generated code.",
       howToFix:
           "Try adding '@MirrorsUsed(...)' as described at "
           "https://goo.gl/Akrrog.");
 
   static const MessageKind NON_CONST_BLOAT = const MessageKind(
-      "Hint: Using 'new #{name}' may lead to unnecessarily large generated "
+      "Using 'new #{name}' may lead to unnecessarily large generated "
       "code.",
       howToFix:
           "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
           "described at https://goo.gl/Akrrog.");
 
   static const MessageKind STRING_EXPECTED = const MessageKind(
-      "Error: Expected a 'String', but got an instance of '#{type}'.");
+      "Expected a 'String', but got an instance of '#{type}'.");
 
   static const MessageKind PRIVATE_IDENTIFIER = const MessageKind(
-      "Error: '#{value}' is not a valid Symbol name because it starts with "
+      "'#{value}' is not a valid Symbol name because it starts with "
       "'_'.");
 
   static const MessageKind PRIVATE_NAMED_PARAMETER = const MessageKind(
-      "Error: Named optional parameter can't have a library private name.",
+      "Named optional parameter can't have a library private name.",
       howToFix: "Try removing the '_' or making the parameter positional or "
         "required.",
       examples: const ["""foo({int _p}) {} main() => foo();"""]
       );
 
   static const MessageKind UNSUPPORTED_LITERAL_SYMBOL = const MessageKind(
-      "Internal Error: Symbol literal '##{value}' is currently unsupported.");
+      "Symbol literal '##{value}' is currently unsupported.");
 
   static const MessageKind INVALID_SYMBOL = const MessageKind('''
-Error: '#{value}' is not a valid Symbol name because is not:
+'#{value}' is not a valid Symbol name because is not:
  * an empty String,
  * a user defined operator,
  * a qualified non-private identifier optionally followed by '=', or
@@ -1245,52 +1212,52 @@
 "operator.");
 
   static const MessageKind AMBIGUOUS_REEXPORT = const MessageKind(
-      "Info: '#{name}' is (re)exported by multiple libraries.");
+      "'#{name}' is (re)exported by multiple libraries.");
 
   static const MessageKind AMBIGUOUS_LOCATION = const MessageKind(
-      "Info: '#{name}' is defined here.");
+      "'#{name}' is defined here.");
 
   static const MessageKind IMPORTED_HERE = const MessageKind(
-      "Info: '#{name}' is imported here.");
+      "'#{name}' is imported here.");
 
   static const MessageKind OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
-      "Hint: The class '#{class}' overrides 'operator==', "
+      "The class '#{class}' overrides 'operator==', "
       "but not 'get hashCode'.");
 
   static const MessageKind PACKAGE_ROOT_NOT_SET = const MessageKind(
-      "Error: Cannot resolve '#{uri}'. Package root has not been set.");
+      "Cannot resolve '#{uri}'. Package root has not been set.");
 
   static const MessageKind INTERNAL_LIBRARY_FROM = const MessageKind(
-      "Error: Internal library '#{resolvedUri}' is not accessible from "
+      "Internal library '#{resolvedUri}' is not accessible from "
       "'#{importingUri}'.");
 
   static const MessageKind INTERNAL_LIBRARY = const MessageKind(
-      "Error: Internal library '#{resolvedUri}' is not accessible.");
+      "Internal library '#{resolvedUri}' is not accessible.");
 
   static const MessageKind LIBRARY_NOT_FOUND = const MessageKind(
-      "Error: Library not found '#{resolvedUri}'.");
+      "Library not found '#{resolvedUri}'.");
 
   static const MessageKind UNSUPPORTED_EQ_EQ_EQ = const MessageKind(
-      "Error: '===' is not an operator. "
+      "'===' is not an operator. "
       "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?");
 
   static const MessageKind UNSUPPORTED_BANG_EQ_EQ = const MessageKind(
-      "Error: '!==' is not an operator. "
+      "'!==' is not an operator. "
       "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?");
 
   static const MessageKind UNSUPPORTED_PREFIX_PLUS = const MessageKind(
-      "Error: '+' is not a prefix operator. ",
+      "'+' is not a prefix operator. ",
       howToFix: "Try removing '+'.",
       examples: const [
           "main() => +2;  // No longer a valid way to write '2'"
       ]);
 
   static const MessageKind UNSUPPORTED_THROW_WITHOUT_EXP = const MessageKind(
-      "Error: No expression after 'throw'. "
+      "No expression after 'throw'. "
       "Did you mean 'rethrow'?");
 
   static const MessageKind DEPRECATED_TYPEDEF_MIXIN_SYNTAX = const MessageKind(
-      "Warning: 'typedef' not allowed here. ",
+      "'typedef' not allowed here. ",
       howToFix: "Try replacing 'typedef' with 'class'.",
       examples: const [
           """
@@ -1302,7 +1269,7 @@
 );
 
   static const MessageKind MIRRORS_EXPECTED_STRING = const MessageKind(
-      "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
+      "Can't use '#{name}' here because it's an instance of '#{type}' "
       "and a 'String' value is expected.",
       howToFix: "Did you forget to add quotes?",
       examples: const [
@@ -1317,7 +1284,7 @@
 """]);
 
   static const MessageKind MIRRORS_EXPECTED_STRING_OR_TYPE = const MessageKind(
-      "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
+      "Can't use '#{name}' here because it's an instance of '#{type}' "
       "and a 'String' or 'Type' value is expected.",
       howToFix: "Did you forget to add quotes?",
       examples: const [
@@ -1330,7 +1297,7 @@
 """]);
 
   static const MessageKind MIRRORS_EXPECTED_STRING_OR_LIST = const MessageKind(
-      "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
+      "Can't use '#{name}' here because it's an instance of '#{type}' "
       "and a 'String' or 'List' value is expected.",
       howToFix: "Did you forget to add quotes?",
       examples: const [
@@ -1346,7 +1313,7 @@
 
   static const MessageKind MIRRORS_EXPECTED_STRING_TYPE_OR_LIST =
       const MessageKind(
-      "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
+      "Can't use '#{name}' here because it's an instance of '#{type}' "
       "but a 'String', 'Type', or 'List' value is expected.",
       howToFix: "Did you forget to add quotes?",
       examples: const [
@@ -1360,7 +1327,7 @@
 
   static const MessageKind MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY =
       const MessageKind(
-      "Hint: Can't find '#{name}' in the current library.",
+      "Can't find '#{name}' in the current library.",
       // TODO(ahe): The closest identifiers in edit distance would be nice.
       howToFix: "Did you forget to add an import?",
       examples: const [
@@ -1374,7 +1341,7 @@
 
   static const MessageKind MIRRORS_CANNOT_RESOLVE_IN_LIBRARY =
       const MessageKind(
-      "Hint: Can't find '#{name}' in the library '#{library}'.",
+      "Can't find '#{name}' in the library '#{library}'.",
       // TODO(ahe): The closest identifiers in edit distance would be nice.
       howToFix: "Is '#{name}' spelled right?",
       examples: const [
@@ -1388,7 +1355,7 @@
 
   static const MessageKind MIRRORS_CANNOT_FIND_IN_ELEMENT =
       const MessageKind(
-      "Hint: Can't find '#{name}' in '#{element}'.",
+      "Can't find '#{name}' in '#{element}'.",
       // TODO(ahe): The closest identifiers in edit distance would be nice.
       howToFix: "Is '#{name}' spelled right?",
       examples: const [
@@ -1401,7 +1368,7 @@
 """]);
 
   static const MessageKind READ_SCRIPT_ERROR = const MessageKind(
-      "Error: Can't read '#{uri}' (#{exception}).",
+      "Can't read '#{uri}' (#{exception}).",
       // Don't know how to fix since the underlying error is unknown.
       howToFix: DONT_KNOW_HOW_TO_FIX,
       examples: const [
@@ -1413,7 +1380,7 @@
 """]);
 
   static const MessageKind EXTRANEOUS_MODIFIER = const MessageKind(
-      "Error: Can't have modifier '#{modifier}' here.",
+      "Can't have modifier '#{modifier}' here.",
       howToFix: "Try removing '#{modifier}'.",
       examples: const [
           "var String foo; main(){}",
@@ -1435,7 +1402,7 @@
           "external var foo; main(){}"]);
 
   static const MessageKind EXTRANEOUS_MODIFIER_REPLACE = const MessageKind(
-      "Error: Can't have modifier '#{modifier}' here.",
+      "Can't have modifier '#{modifier}' here.",
       howToFix: "Try replacing modifier '#{modifier}' with 'var', 'final',"
           " or a type.",
       examples: const [
@@ -1446,12 +1413,12 @@
           "external foo; main(){}"]);
 
   static const MessageKind ABSTRACT_CLASS_INSTANTIATION = const MessageKind(
-      "Warning: Can't instantiate abstract class.",
+      "Can't instantiate abstract class.",
       howToFix: DONT_KNOW_HOW_TO_FIX,
       examples: const ["abstract class A {} main() { new A(); }"]);
 
   static const MessageKind BODY_EXPECTED = const MessageKind(
-      "Error: Expected a function body or '=>'.",
+      "Expected a function body or '=>'.",
       // TODO(ahe): In some scenarios, we can suggest removing the 'static'
       // keyword.
       howToFix: "Try adding {}.",
@@ -1459,14 +1426,14 @@
           "main();"]);
 
   static const MessageKind MIRROR_BLOAT = const MessageKind(
-      "Hint: #{count} methods retained for use by dart:mirrors out of #{total}"
+      "#{count} methods retained for use by dart:mirrors out of #{total}"
       " total methods (#{percentage}%).");
 
   static const MessageKind MIRROR_IMPORT = const MessageKind(
-      "Info: Import of 'dart:mirrors'.");
+      "Import of 'dart:mirrors'.");
 
   static const MessageKind MIRROR_IMPORT_NO_USAGE = const MessageKind(
-      "Info: This import is not annotated with @MirrorsUsed, which may lead to "
+      "This import is not annotated with @MirrorsUsed, which may lead to "
       "unnecessarily large generated code.",
       howToFix:
           "Try adding '@MirrorsUsed(...)' as described at "
@@ -1474,21 +1441,21 @@
 
   static const MessageKind WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT =
       const MessageKind(
-      "Error: Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.");
+      "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.");
 
   static const MessageKind EXPECTED_IDENTIFIER_NOT_RESERVED_WORD =
       const MessageKind(
-          "Error: '#{keyword}' is a reserved word and can't be used here.",
+          "'#{keyword}' is a reserved word and can't be used here.",
           howToFix: "Try using a different name.",
           examples: const ["do() {} main() {}"]);
 
   static const MessageKind UNUSED_METHOD = const MessageKind(
-      "Hint: The method '#{method_name}' is never called.",
+      "The method '#{method_name}' is never called.",
       howToFix: "Consider deleting it.",
       examples: const ["deadCode() {} main() {}"]);
 
   static const MessageKind ABSTRACT_METHOD = const MessageKind(
-      "Warning: The method '#{name}' has no implementation in "
+      "The method '#{name}' has no implementation in "
       "class '#{class}'.",
       howToFix: "Try adding a body to '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1500,7 +1467,7 @@
 """]);
 
   static const MessageKind ABSTRACT_GETTER = const MessageKind(
-      "Warning: The getter '#{name}' has no implementation in "
+      "The getter '#{name}' has no implementation in "
       "class '#{class}'.",
       howToFix: "Try adding a body to '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1512,7 +1479,7 @@
 """]);
 
   static const MessageKind ABSTRACT_SETTER = const MessageKind(
-      "Warning: The setter '#{name}' has no implementation in "
+      "The setter '#{name}' has no implementation in "
       "class '#{class}'.",
       howToFix: "Try adding a body to '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1524,7 +1491,7 @@
 """]);
 
   static const MessageKind INHERIT_GETTER_AND_METHOD = const MessageKind(
-      "Warning: The class '#{class}' can't inherit both getters and methods "
+      "The class '#{class}' can't inherit both getters and methods "
       "by the named '#{name}'.",
       howToFix: DONT_KNOW_HOW_TO_FIX,
       examples: const ["""
@@ -1540,19 +1507,19 @@
 """]);
 
   static const MessageKind INHERITED_METHOD = const MessageKind(
-      "Info: The inherited method '#{name}' is declared here in class "
+      "The inherited method '#{name}' is declared here in class "
       "'#{class}'.");
 
   static const MessageKind INHERITED_EXPLICIT_GETTER = const MessageKind(
-      "Info: The inherited getter '#{name}' is declared here in class "
+      "The inherited getter '#{name}' is declared here in class "
       "'#{class}'.");
 
   static const MessageKind INHERITED_IMPLICIT_GETTER = const MessageKind(
-      "Info: The inherited getter '#{name}' is implicitly declared by this "
+      "The inherited getter '#{name}' is implicitly declared by this "
       "field in class '#{class}'.");
 
   static const MessageKind UNIMPLEMENTED_METHOD_ONE = const MessageKind(
-      "Warning: '#{class}' doesn't implement '#{method}' "
+      "'#{class}' doesn't implement '#{method}' "
       "declared in '#{declarer}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1571,7 +1538,7 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_METHOD = const MessageKind(
-      "Warning: '#{class}' doesn't implement '#{method}'.",
+      "'#{class}' doesn't implement '#{method}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
       examples: const ["""
@@ -1605,10 +1572,10 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_METHOD_CONT = const MessageKind(
-      "Info: The method '#{name}' is declared here in class '#{class}'.");
+      "The method '#{name}' is declared here in class '#{class}'.");
 
   static const MessageKind UNIMPLEMENTED_SETTER_ONE = const MessageKind(
-      "Warning: '#{class}' doesn't implement the setter '#{name}' "
+      "'#{class}' doesn't implement the setter '#{name}' "
       "declared in '#{declarer}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1627,7 +1594,7 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_SETTER = const MessageKind(
-      "Warning: '#{class}' doesn't implement the setter '#{name}'.",
+      "'#{class}' doesn't implement the setter '#{name}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
       examples: const ["""
@@ -1651,14 +1618,14 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_EXPLICIT_SETTER = const MessageKind(
-      "Info: The setter '#{name}' is declared here in class '#{class}'.");
+      "The setter '#{name}' is declared here in class '#{class}'.");
 
   static const MessageKind UNIMPLEMENTED_IMPLICIT_SETTER = const MessageKind(
-      "Info: The setter '#{name}' is implicitly declared by this field "
+      "The setter '#{name}' is implicitly declared by this field "
       "in class '#{class}'.");
 
   static const MessageKind UNIMPLEMENTED_GETTER_ONE = const MessageKind(
-      "Warning: '#{class}' doesn't implement the getter '#{name}' "
+      "'#{class}' doesn't implement the getter '#{name}' "
       "declared in '#{declarer}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
@@ -1677,7 +1644,7 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_GETTER = const MessageKind(
-      "Warning: '#{class}' doesn't implement the getter '#{name}'.",
+      "'#{class}' doesn't implement the getter '#{name}'.",
       howToFix: "Try adding an implementation of '#{name}' or declaring "
                 "'#{class}' to be 'abstract'.",
       examples: const ["""
@@ -1701,14 +1668,14 @@
 """]);
 
   static const MessageKind UNIMPLEMENTED_EXPLICIT_GETTER = const MessageKind(
-      "Info: The getter '#{name}' is declared here in class '#{class}'.");
+      "The getter '#{name}' is declared here in class '#{class}'.");
 
   static const MessageKind UNIMPLEMENTED_IMPLICIT_GETTER = const MessageKind(
-      "Info: The getter '#{name}' is implicitly declared by this field "
+      "The getter '#{name}' is implicitly declared by this field "
       "in class '#{class}'.");
 
   static const MessageKind EQUAL_MAP_ENTRY_KEY = const MessageKind(
-      "Warning: An entry with the same key already exists in the map.",
+      "An entry with the same key already exists in the map.",
       howToFix: "Try removing the previous entry or changing the key in one "
                 "of the entries.",
       examples: const ["""
@@ -1717,7 +1684,7 @@
 }"""]);
 
   static const MessageKind COMPILER_CRASHED = const MessageKind(
-      "Error: The compiler crashed when compiling this element.");
+      "The compiler crashed when compiling this element.");
 
   static const MessageKind PLEASE_REPORT_THE_CRASH = const MessageKind('''
 The compiler is broken.
@@ -1740,42 +1707,42 @@
 ''');
 
   static const MessageKind POTENTIAL_MUTATION = const MessageKind(
-      "Hint: Variable '#{variableName}' is not known to be of type "
+      "Variable '#{variableName}' is not known to be of type "
       "'#{shownType}' because it is potentially mutated in the scope for "
       "promotion.");
 
   static const MessageKind POTENTIAL_MUTATION_HERE = const MessageKind(
-      "Info: Variable '#{variableName}' is potentially mutated here.");
+      "Variable '#{variableName}' is potentially mutated here.");
 
   static const MessageKind POTENTIAL_MUTATION_IN_CLOSURE = const MessageKind(
-      "Hint: Variable '#{variableName}' is not known to be of type "
+      "Variable '#{variableName}' is not known to be of type "
       "'#{shownType}' because it is potentially mutated within a closure.");
 
   static const MessageKind POTENTIAL_MUTATION_IN_CLOSURE_HERE =
       const MessageKind(
-          "Info: Variable '#{variableName}' is potentially mutated in a "
+          "Variable '#{variableName}' is potentially mutated in a "
           "closure here.");
 
   static const MessageKind ACCESSED_IN_CLOSURE = const MessageKind(
-      "Hint: Variable '#{variableName}' is not known to be of type "
+      "Variable '#{variableName}' is not known to be of type "
       "'#{shownType}' because it is accessed by a closure in the scope for "
       "promotion and potentially mutated in the scope of '#{variableName}'.");
 
   static const MessageKind ACCESSED_IN_CLOSURE_HERE = const MessageKind(
-      "Info: Variable '#{variableName}' is accessed in a closure here.");
+      "Variable '#{variableName}' is accessed in a closure here.");
 
   static const MessageKind NOT_MORE_SPECIFIC = const MessageKind(
-      "Hint: Variable '#{variableName}' is not shown to have type "
+      "Variable '#{variableName}' is not shown to have type "
       "'#{shownType}' because '#{shownType}' is not more specific than the "
       "known type '#{knownType}' of '#{variableName}'.");
 
   static const MessageKind NOT_MORE_SPECIFIC_SUBTYPE = const MessageKind(
-      "Hint: Variable '#{variableName}' is not shown to have type "
+      "Variable '#{variableName}' is not shown to have type "
       "'#{shownType}' because '#{shownType}' is not a subtype of the "
       "known type '#{knownType}' of '#{variableName}'.");
 
   static const MessageKind NOT_MORE_SPECIFIC_SUGGESTION = const MessageKind(
-      "Hint: Variable '#{variableName}' is not shown to have type "
+      "Variable '#{variableName}' is not shown to have type "
       "'#{shownType}' because '#{shownType}' is not more specific than the "
       "known type '#{knownType}' of '#{variableName}'.",
       howToFix: "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'.");
@@ -1785,88 +1752,88 @@
   //////////////////////////////////////////////////////////////////////////////
 
   static const MessageKind PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
-      "Error: Patch return type '#{patchReturnType}' does not match "
+      "Patch return type '#{patchReturnType}' does not match "
       "'#{originReturnType}' on origin method '#{methodName}'.");
 
   static const MessageKind PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH =
       const MessageKind(
-          "Error: Required parameter count of patch method "
+          "Required parameter count of patch method "
           "(#{patchParameterCount}) does not match parameter count on origin "
           "method '#{methodName}' (#{originParameterCount}).");
 
   static const MessageKind PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH =
       const MessageKind(
-          "Error: Optional parameter count of patch method "
+          "Optional parameter count of patch method "
           "(#{patchParameterCount}) does not match parameter count on origin "
           "method '#{methodName}' (#{originParameterCount}).");
 
   static const MessageKind PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH =
       const MessageKind(
-          "Error: Optional parameters of origin and patch method "
+          "Optional parameters of origin and patch method "
           "'#{methodName}' must both be either named or positional.");
 
   static const MessageKind PATCH_PARAMETER_MISMATCH = const MessageKind(
-      "Error: Patch method parameter '#{patchParameter}' does not match "
+      "Patch method parameter '#{patchParameter}' does not match "
       "'#{originParameter}' on origin method '#{methodName}'.");
 
   static const MessageKind PATCH_PARAMETER_TYPE_MISMATCH = const MessageKind(
-      "Error: Patch method parameter '#{parameterName}' type "
+      "Patch method parameter '#{parameterName}' type "
       "'#{patchParameterType}' does not match '#{originParameterType}' on "
       "origin method '#{methodName}'.");
 
   static const MessageKind PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION =
-      const MessageKind("Error: External method without an implementation.");
+      const MessageKind("External method without an implementation.");
 
   static const MessageKind PATCH_POINT_TO_FUNCTION = const MessageKind(
-      "Info: This is the function patch '#{functionName}'.");
+      "This is the function patch '#{functionName}'.");
 
   static const MessageKind PATCH_POINT_TO_CLASS = const MessageKind(
-      "Info: This is the class patch '#{className}'.");
+      "This is the class patch '#{className}'.");
 
   static const MessageKind PATCH_POINT_TO_GETTER = const MessageKind(
-      "Info: This is the getter patch '#{getterName}'.");
+      "This is the getter patch '#{getterName}'.");
 
   static const MessageKind PATCH_POINT_TO_SETTER = const MessageKind(
-      "Info: This is the setter patch '#{setterName}'.");
+      "This is the setter patch '#{setterName}'.");
 
   static const MessageKind PATCH_POINT_TO_CONSTRUCTOR = const MessageKind(
-      "Info: This is the constructor patch '#{constructorName}'.");
+      "This is the constructor patch '#{constructorName}'.");
 
   static const MessageKind PATCH_POINT_TO_PARAMETER = const MessageKind(
-      "Info: This is the patch parameter '#{parameterName}'.");
+      "This is the patch parameter '#{parameterName}'.");
 
   static const MessageKind PATCH_NON_EXISTING = const MessageKind(
-      "Error: Origin does not exist for patch '#{name}'.");
+      "Origin does not exist for patch '#{name}'.");
 
   // TODO(ahe): Eventually, this error should be removed as it will be handled
   // by the regular parser.
   static const MessageKind PATCH_NONPATCHABLE = const MessageKind(
-      "Error: Only classes and functions can be patched.");
+      "Only classes and functions can be patched.");
 
   static const MessageKind PATCH_NON_EXTERNAL = const MessageKind(
-      "Error: Only external functions can be patched.");
+      "Only external functions can be patched.");
 
   static const MessageKind PATCH_NON_CLASS = const MessageKind(
-      "Error: Patching non-class with class patch '#{className}'.");
+      "Patching non-class with class patch '#{className}'.");
 
   static const MessageKind PATCH_NON_GETTER = const MessageKind(
-      "Error: Cannot patch non-getter '#{name}' with getter patch.");
+      "Cannot patch non-getter '#{name}' with getter patch.");
 
   static const MessageKind PATCH_NO_GETTER = const MessageKind(
-      "Error: No getter found for getter patch '#{getterName}'.");
+      "No getter found for getter patch '#{getterName}'.");
 
   static const MessageKind PATCH_NON_SETTER = const MessageKind(
-      "Error: Cannot patch non-setter '#{name}' with setter patch.");
+      "Cannot patch non-setter '#{name}' with setter patch.");
 
   static const MessageKind PATCH_NO_SETTER = const MessageKind(
-      "Error: No setter found for setter patch '#{setterName}'.");
+      "No setter found for setter patch '#{setterName}'.");
 
   static const MessageKind PATCH_NON_CONSTRUCTOR = const MessageKind(
-      "Error: Cannot patch non-constructor with constructor patch "
+      "Cannot patch non-constructor with constructor patch "
       "'#{constructorName}'.");
 
   static const MessageKind PATCH_NON_FUNCTION = const MessageKind(
-      "Error: Cannot patch non-function with function patch "
+      "Cannot patch non-function with function patch "
       "'#{functionName}'.");
 
   //////////////////////////////////////////////////////////////////////////////
@@ -1875,7 +1842,7 @@
 
   static const MessageKind CALL_NOT_SUPPORTED_ON_NATIVE_CLASS =
       const MessageKind(
-          "Error: Non-supported 'call' member on a native class, or a "
+          "Non-supported 'call' member on a native class, or a "
           "subclass of a native class.");
 
   toString() => template;
@@ -1884,20 +1851,9 @@
     return new Message(this, arguments, terse);
   }
 
-  CompilationError error([Map arguments = const {}, bool terse = false]) {
-    return new CompilationError(this, arguments, terse);
-  }
-
   bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
 }
 
-class DualKind {
-  final MessageKind error;
-  final MessageKind warning;
-
-  const DualKind({this.error, this.warning});
-}
-
 class Message {
   final MessageKind kind;
   final Map arguments;
@@ -1941,30 +1897,3 @@
 
   int get hashCode => throw new UnsupportedError('Message.hashCode');
 }
-
-class Diagnostic {
-  final Message message;
-  Diagnostic(MessageKind kind, Map arguments, bool terse)
-      : message = new Message(kind, arguments, terse);
-  String toString() => message.toString();
-}
-
-class TypeWarning extends Diagnostic {
-  TypeWarning(MessageKind kind, Map arguments, bool terse)
-    : super(kind, arguments, terse);
-}
-
-class ResolutionWarning extends Diagnostic {
-  ResolutionWarning(MessageKind kind, Map arguments, bool terse)
-    : super(kind, arguments, terse);
-}
-
-class CompileTimeConstantError extends Diagnostic {
-  CompileTimeConstantError(MessageKind kind, Map arguments, bool terse)
-    : super(kind, arguments, terse);
-}
-
-class CompilationError extends Diagnostic {
-  CompilationError(MessageKind kind, Map arguments, bool terse)
-    : super(kind, arguments, terse);
-}
diff --git a/sdk/lib/_internal/lib/async_patch.dart b/sdk/lib/_internal/lib/async_patch.dart
index 053e856..c26f29f 100644
--- a/sdk/lib/_internal/lib/async_patch.dart
+++ b/sdk/lib/_internal/lib/async_patch.dart
@@ -4,9 +4,15 @@
 
 // Patch file for the dart:async library.
 
-import 'dart:_js_helper' show Primitives;
-import 'dart:_isolate_helper' show IsolateNatives, TimerImpl;
-import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
+import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
+import 'dart:_isolate_helper' show
+    IsolateNatives,
+    TimerImpl,
+    leaveJsAsync,
+    enterJsAsync,
+    isWorker;
+
+import 'dart:_foreign_helper' show JS;
 
 patch Timer _createTimer(Duration duration, void callback()) {
   int milliseconds = duration.inMilliseconds;
@@ -41,7 +47,7 @@
                        libraryName, index));
     }
     Iterable<Future<bool>> allLoads =
-        hunkNames.map((libraryName) => _load(libraryName, uri));
+        hunkNames.map((hunkName) => _load(hunkName, uri));
     return Future.wait(allLoads).then((results) {
       return results.any((x) => x);
     });
@@ -60,57 +66,88 @@
     return future.then((_) => false);
   }
 
-  if (Primitives.isJsshell) {
-    // TODO(ahe): Move this code to a JavaScript command helper script that is
-    // not included in generated output.
-    return _loadedLibraries[hunkName] = new Future<bool>(() {
-      if (uri == null) uri = '$hunkName';
-      // Create a new function to avoid getting access to current function
-      // context.
-      JS('void', '(new Function(#))()', 'loadRelativeToScript("$uri")');
-      return true;
-    });
-  } else if (Primitives.isD8) {
-    // TODO(ahe): Move this code to a JavaScript command helper script that is
-    // not included in generated output.
-    return _loadedLibraries[hunkName] = new Future<bool>(() {
-      if (uri == null) {
-        uri = IsolateNatives.computeThisScriptD8();
-        int index = uri.lastIndexOf('/');
-        uri = '${uri.substring(0, index + 1)}$hunkName';
-      }
-      // Create a new function to avoid getting access to current function
-      // context.
-      JS('void', '(new Function(#))()', 'load("$uri")');
-      return true;
-    });
+  if (uri == null) {
+    uri = IsolateNatives.thisScript;
   }
+  int index = uri.lastIndexOf('/');
+  uri = '${uri.substring(0, index + 1)}$hunkName';
 
-  return _loadedLibraries[hunkName] = new Future<bool>(() {
-    Completer completer = new Completer<bool>();
-    if (uri == null) {
-      uri = IsolateNatives.thisScript;
+  if (Primitives.isJsshell || Primitives.isD8) {
+    // TODO(ahe): Move this code to a JavaScript command helper script that is
+    // not included in generated output.
+    return _loadedLibraries[hunkName] = new Future<bool>(() {
+      try {
+        // Create a new function to avoid getting access to current function
+        // context.
+        JS('void', '(new Function(#))()', 'load("$uri")');
+      } catch (error, stackTrace) {
+        throw new DeferredLoadException("Loading $uri failed.");
+      }
+      return true;
+    });
+  } else if (isWorker()) {
+    // We are in a web worker. Load the code with an XMLHttpRequest.
+    return _loadedLibraries[hunkName] = new Future<bool>(() {
+      Completer completer = new Completer<bool>();
+      enterJsAsync();
+      Future<bool> leavingFuture = completer.future.whenComplete(() {
+        leaveJsAsync();
+      });
+
       int index = uri.lastIndexOf('/');
       uri = '${uri.substring(0, index + 1)}$hunkName';
-    }
+      var xhr =  JS('dynamic', 'new XMLHttpRequest()');
+      JS('void', '#.open("GET", #)', xhr, uri);
+      JS('void', '#.addEventListener("load", #, false)',
+         xhr, convertDartClosureToJS((event) {
+        if (JS('int', '#.status', xhr) != 200) {
+          completer.completeError(
+              new DeferredLoadException("Loading $uri failed."));
+          return;
+        }
+        String code = JS('String', '#.responseText', xhr);
+        try {
+          // Create a new function to avoid getting access to current function
+          // context.
+          JS('void', '(new Function(#))()', code);
+        } catch (error, stackTrace) {
+          completer.completeError(
+            new DeferredLoadException("Evaluating $uri failed."));
+          return;
+        }
+        completer.complete(true);
+      }, 1));
 
+      var fail = convertDartClosureToJS((event) {
+        new DeferredLoadException("Loading $uri failed.");
+      }, 1);
+      JS('void', '#.addEventListener("error", #, false)', xhr, fail);
+      JS('void', '#.addEventListener("abort", #, false)', xhr, fail);
+
+      JS('void', '#.send()', xhr);
+      return leavingFuture;
+    });
+  }
+  // We are in a dom-context.
+  return _loadedLibraries[hunkName] = new Future<bool>(() {
+    Completer completer = new Completer<bool>();
     // Inject a script tag.
     var script = JS('', 'document.createElement("script")');
     JS('', '#.type = "text/javascript"', script);
     JS('', '#.src = #', script, uri);
-    var onLoad = JS('', '#.bind(null, #)',
-                    DART_CLOSURE_TO_JS(_onDeferredLibraryLoad), completer);
-    JS('', '#.addEventListener("load", #, false)', script, onLoad);
+    JS('', '#.addEventListener("load", #, false)',
+       script, convertDartClosureToJS((event) {
+      completer.complete(true);
+    }, 1));
+    JS('', '#.addEventListener("error", #, false)',
+       script, convertDartClosureToJS((event) {
+      completer.completeError(
+          new DeferredLoadException("Loading $uri failed."));
+    }, 1));
     JS('', 'document.body.appendChild(#)', script);
 
     return completer.future;
   });
 }
 
-/// Used to implement deferred loading. Used as callback on "load"
-/// event above in [load].
-_onDeferredLibraryLoad(Completer<bool> completer, event) {
-  completer.complete(true);
-}
-
 bool get _hasDocument => JS('String', 'typeof document') == 'object';
diff --git a/sdk/lib/_internal/lib/convert_patch.dart b/sdk/lib/_internal/lib/convert_patch.dart
index 70b4d5f..997db63 100644
--- a/sdk/lib/_internal/lib/convert_patch.dart
+++ b/sdk/lib/_internal/lib/convert_patch.dart
@@ -23,7 +23,7 @@
  *
  * Throws [FormatException] if the input is not valid JSON text.
  */
-patch _parseJson(String source, reviver(var key, var value)) {
+patch _parseJson(String source, reviver(key, value)) {
   if (source is! String) throw new ArgumentError(source);
 
   var parsed;
diff --git a/sdk/lib/_internal/lib/internal_patch.dart b/sdk/lib/_internal/lib/internal_patch.dart
index cccc6569..485c895 100644
--- a/sdk/lib/_internal/lib/internal_patch.dart
+++ b/sdk/lib/_internal/lib/internal_patch.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:_js_primitives' show printString;
+import 'dart:_js_helper' show JS;
+import 'dart:_interceptors' show JSArray;
 
 patch class Symbol implements core.Symbol {
   patch const Symbol(String name)
@@ -11,4 +13,9 @@
 
 patch void printToConsole(String line) {
   printString('$line');
-}
\ No newline at end of file
+}
+
+patch List makeListFixedLength(List growableList) {
+  JSArray.markFixedList(growableList);
+  return growableList;
+}
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index a07fe16..4dbab8c 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -322,6 +322,9 @@
   patch static int _socketType(nativeSocket) {
     throw new UnsupportedError("StdIOUtils._socketType");
   }
+  patch static _getStdioHandleType(int fd) {
+    throw new UnsupportedError("StdIOUtils._getStdioHandleType");
+  }
 }
 
 patch class _WindowsCodePageDecoder {
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index cd3ee4a..691cfe2 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -32,6 +32,32 @@
   return result;
 }
 
+/// Marks entering a javascript async operation to keep the worker alive.
+/// Marks entering a JavaScript async operation to keep the worker alive.
+///
+/// To be called by library code before starting an async operation controlled
+/// by the JavaScript event handler.
+///
+/// Also call [leaveJsAsync] in all callback handlers marking the end of that
+/// async operation (also error handlers) so the worker can be released.
+///
+/// These functions only has to be called for code that can be run from a
+/// worker-isolate (so not for general dom operations).
+enterJsAsync() {
+  _globalState.topEventLoop._activeJsAsyncCount++;
+}
+
+/// Marks leaving a javascript async operation.
+///
+/// See [enterJsAsync].
+leaveJsAsync() {
+  _globalState.topEventLoop._activeJsAsyncCount--;
+  assert(_globalState.topEventLoop._activeJsAsyncCount >= 0);
+}
+
+/// Returns true if we are currently in a worker context.
+bool isWorker() => _globalState.isWorker;
+
 /**
  * Called by the compiler to fetch the current isolate context.
  */
@@ -44,7 +70,14 @@
  * is needed. For single-isolate applications (e.g. hello world), this
  * call is not emitted.
  */
-void startRootIsolate(entry) {
+void startRootIsolate(entry, args) {
+  // The dartMainRunner can inject a new arguments array. We pass the arguments
+  // through a "JS", so that the type-inferrer loses track of it.
+  args = JS("", "#", args);
+  if (args == null) args = [];
+  if (args is! List) {
+    throw new ArgumentError("Arguments to main must be a List: $args");
+  }
   _globalState = new _Manager(entry);
 
   // Don't start the main loop again, if we are in a worker.
@@ -59,9 +92,9 @@
   _globalState.currentContext = rootContext;
 
   if (entry is _MainFunctionArgs) {
-    rootContext.eval(() { entry([]); });
+    rootContext.eval(() { entry(args); });
   } else if (entry is _MainFunctionArgsMessage) {
-    rootContext.eval(() { entry([], null); });
+    rootContext.eval(() { entry(args, null); });
   } else {
     rootContext.eval(entry);
   }
@@ -208,12 +241,12 @@
 
   /**
    * Close the worker running this code if all isolates are done and
-   * there is no active timer.
+   * there are no active async JavaScript tasks still running.
    */
   void maybeCloseWorker() {
     if (isWorker
         && isolates.isEmpty
-        && topEventLoop.activeTimerCount == 0) {
+        && topEventLoop._activeJsAsyncCount == 0) {
       mainManager.postMessage(_serializeMessage({'command': 'close'}));
     }
   }
@@ -238,7 +271,7 @@
 
   final Capability pauseCapability = new Capability();
 
-  // TODO(lrn): Store these in single "pausestate" object, so they don't take
+  // TODO(lrn): Store these in single "PauseState" object, so they don't take
   // up as much room when not pausing.
   bool isPaused = false;
   List<_IsolateEvent> delayedEvents = [];
@@ -253,6 +286,7 @@
     if (pauseTokens.add(resume) && !isPaused) {
       isPaused = true;
     }
+    _updateGlobalState();
   }
 
   void removePause(Capability resume) {
@@ -265,6 +299,7 @@
       }
       isPaused = false;
     }
+    _updateGlobalState();
   }
 
   /**
@@ -328,7 +363,7 @@
   }
 
   _updateGlobalState() {
-    if (ports.length - weakPorts.length > 0) {
+    if (ports.length - weakPorts.length > 0 || isPaused) {
       _globalState.isolates[id] = this; // indicate this isolate is active
     } else {
       _globalState.isolates.remove(id); // indicate this isolate is not active
@@ -346,7 +381,14 @@
 /** Represent the event loop on a javascript thread (DOM or worker). */
 class _EventLoop {
   final Queue<_IsolateEvent> events = new Queue<_IsolateEvent>();
-  int activeTimerCount = 0;
+
+  /// The number of waiting callbacks not controlled by the dart event loop.
+  ///
+  /// This could be timers or http requests. The worker will only be killed if
+  /// this count reaches 0.
+  /// Access this by using [enterJsAsync] before starting a JavaScript async
+  /// operation and [leaveJsAsync] when the callback has fired.
+  int _activeJsAsyncCount = 0;
 
   _EventLoop();
 
@@ -468,6 +510,8 @@
 typedef _MainFunctionArgs(args);
 typedef _MainFunctionArgsMessage(args, message);
 
+/// Note: IsolateNatives depends on _globalState which is only set up correctly
+/// when 'dart:isolate' has been imported.
 class IsolateNatives {
 
   static String thisScript = computeThisScript();
@@ -486,6 +530,8 @@
     }
     if (Primitives.isD8) return computeThisScriptD8();
     if (Primitives.isJsshell) return computeThisScriptJsshell();
+    // A worker has no script tag - so get an url from a stack-trace.
+    if (_globalState.isWorker) return computeThisScriptFromTrace();
     return null;
   }
 
@@ -493,10 +539,11 @@
     return JS('String|Null', 'thisFilename()');
   }
 
-  static String computeThisScriptD8() {
-    // TODO(ahe): The following is for supporting D8.  We should move this code
-    // to a helper library that is only loaded when testing on D8.
+  // TODO(ahe): The following is for supporting D8.  We should move this code
+  // to a helper library that is only loaded when testing on D8.
+  static String computeThisScriptD8() => computeThisScriptFromTrace();
 
+  static String computeThisScriptFromTrace() {
     var stack = JS('String|Null', 'new Error().stack');
     if (stack == null) {
       // According to Internet Explorer documentation, the stack
@@ -554,10 +601,12 @@
         var args = msg['args'];
         var message = _deserializeMessage(msg['msg']);
         var isSpawnUri = msg['isSpawnUri'];
+        var startPaused = msg['startPaused'];
         var replyTo = _deserializeMessage(msg['replyTo']);
         var context = new _IsolateContext();
         _globalState.topEventLoop.enqueue(context, () {
-          _startIsolate(entryPoint, args, message, isSpawnUri, replyTo);
+          _startIsolate(entryPoint, args, message,
+                        isSpawnUri, startPaused, replyTo);
         }, 'worker-start');
         // Make sure we always have a current context in this worker.
         // TODO(7907): This is currently needed because we're using
@@ -571,7 +620,8 @@
       case 'spawn-worker':
         _spawnWorker(msg['functionName'], msg['uri'],
                      msg['args'], msg['msg'],
-                     msg['isSpawnUri'], msg['replyPort']);
+                     msg['isSpawnUri'], msg['startPaused'],
+                     msg['replyPort']);
         break;
       case 'message':
         SendPort port = msg['port'];
@@ -639,17 +689,24 @@
   }
 
   static Future<List> spawnFunction(void topLevelFunction(message),
-                                        message) {
+                                    var message,
+                                    bool startPaused) {
     final name = _getJSFunctionName(topLevelFunction);
     if (name == null) {
       throw new UnsupportedError(
           "only top-level functions can be spawned.");
     }
-    return spawn(name, null, null, message, false, false);
+    bool isLight = false;
+    bool isSpawnUri = false;
+    return spawn(name, null, null, message, isLight, isSpawnUri, startPaused);
   }
 
-  static Future<List> spawnUri(Uri uri, List<String> args, message) {
-    return spawn(null, uri.toString(), args, message, false, true);
+  static Future<List> spawnUri(Uri uri, List<String> args, var message,
+                               bool startPaused) {
+    bool isLight = false;
+    bool isSpawnUri = true;
+    return spawn(null, uri.toString(), args, message,
+                 isLight, isSpawnUri, startPaused);
   }
 
   // TODO(sigmund): clean up above, after we make the new API the default:
@@ -657,7 +714,7 @@
   /// If [uri] is `null` it is replaced with the current script.
   static Future<List> spawn(String functionName, String uri,
                             List<String> args, message,
-                            bool isLight, bool isSpawnUri) {
+                            bool isLight, bool isSpawnUri, bool startPaused) {
     // Assume that the compiled version of the Dart file lives just next to the
     // dart file.
     // TODO(floitsch): support precompiled version of dart2js output.
@@ -672,10 +729,12 @@
     SendPort signalReply = port.sendPort;
 
     if (_globalState.useWorkers && !isLight) {
-      _startWorker(functionName, uri, args, message, isSpawnUri, signalReply);
+      _startWorker(functionName, uri, args, message, isSpawnUri, startPaused,
+                   signalReply);
     } else {
       _startNonWorker(
-          functionName, uri, args, message, isSpawnUri, signalReply);
+          functionName, uri, args, message, isSpawnUri, startPaused,
+          signalReply);
     }
     return result;
   }
@@ -684,6 +743,7 @@
       String functionName, String uri,
       List<String> args, message,
       bool isSpawnUri,
+      bool startPaused,
       SendPort replyPort) {
     if (_globalState.isWorker) {
       _globalState.mainManager.postMessage(_serializeMessage({
@@ -693,16 +753,19 @@
           'msg': message,
           'uri': uri,
           'isSpawnUri': isSpawnUri,
+          'startPaused': startPaused,
           'replyPort': replyPort}));
     } else {
-      _spawnWorker(functionName, uri, args, message, isSpawnUri, replyPort);
+      _spawnWorker(functionName, uri, args, message,
+                   isSpawnUri, startPaused, replyPort);
     }
   }
 
   static void _startNonWorker(
       String functionName, String uri,
-      List<String> args, message,
+      List<String> args, var message,
       bool isSpawnUri,
+      bool startPaused,
       SendPort replyPort) {
     // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
     if (uri != null) {
@@ -711,13 +774,14 @@
     }
     _globalState.topEventLoop.enqueue(new _IsolateContext(), () {
       final func = _getJSFunctionFromName(functionName);
-      _startIsolate(func, args, message, isSpawnUri, replyPort);
+      _startIsolate(func, args, message, isSpawnUri, startPaused, replyPort);
     }, 'nonworker start');
   }
 
   static void _startIsolate(Function topLevel,
                             List<String> args, message,
                             bool isSpawnUri,
+                            bool startPaused,
                             SendPort replyTo) {
     _IsolateContext context = JS_CURRENT_ISOLATE_CONTEXT();
     Primitives.initializeStatics(context.id);
@@ -725,14 +789,25 @@
     replyTo.send([_SPAWNED_SIGNAL,
                   context.controlPort.sendPort,
                   context.pauseCapability]);
-    if (!isSpawnUri) {
-      topLevel(message);
-    } else if (topLevel is _MainFunctionArgsMessage) {
-      topLevel(args, message);
-    } else if (topLevel is _MainFunctionArgs) {
-      topLevel(args);
+
+    void runStartFunction() {
+      if (!isSpawnUri) {
+        topLevel(message);
+      } else if (topLevel is _MainFunctionArgsMessage) {
+        topLevel(args, message);
+      } else if (topLevel is _MainFunctionArgs) {
+        topLevel(args);
+      } else {
+        topLevel();
+      }
+    }
+
+    if (startPaused) {
+      context.addPause(context.pauseCapability, context.pauseCapability);
+      _globalState.topEventLoop.enqueue(context, runStartFunction,
+                                        'start isolate');
     } else {
-      topLevel();
+      runStartFunction();
     }
   }
 
@@ -743,6 +818,7 @@
   static void _spawnWorker(functionName, String uri,
                            List<String> args, message,
                            bool isSpawnUri,
+                           bool startPaused,
                            SendPort replyPort) {
     if (uri == null) uri = thisScript;
     final worker = JS('var', 'new Worker(#)', uri);
@@ -767,6 +843,7 @@
         'args': args,
         'msg': _serializeMessage(message),
         'isSpawnUri': isSpawnUri,
+        'startPaused': startPaused,
         'functionName': functionName }));
   }
 }
@@ -806,7 +883,6 @@
     final isolate = _globalState.isolates[_isolateId];
     if (isolate == null) return;
     if (_receivePort._isClosed) return;
-
     // We force serialization/deserialization as a simple way to ensure
     // isolate communication restrictions are respected between isolates that
     // live in the same worker. [_NativeJsSendPort] delivers both messages
@@ -1365,11 +1441,12 @@
 
       void internalCallback() {
         _handle = null;
-        _globalState.topEventLoop.activeTimerCount--;
+        leaveJsAsync();
         callback();
       }
 
-      _globalState.topEventLoop.activeTimerCount++;
+      enterJsAsync();
+
       _handle = JS('int', '#.setTimeout(#, #)',
                    globalThis,
                    convertDartClosureToJS(internalCallback, 0),
@@ -1383,7 +1460,7 @@
   TimerImpl.periodic(int milliseconds, void callback(Timer timer))
       : _once = false {
     if (hasTimer()) {
-      _globalState.topEventLoop.activeTimerCount++;
+      enterJsAsync();
       _handle = JS('int', '#.setInterval(#, #)',
                    globalThis,
                    convertDartClosureToJS(() { callback(this); }, 0),
@@ -1399,7 +1476,7 @@
         throw new UnsupportedError("Timer in event loop cannot be canceled.");
       }
       if (_handle == null) return;
-      _globalState.topEventLoop.activeTimerCount--;
+      leaveJsAsync();
       if (_once) {
         JS('void', '#.clearTimeout(#)', globalThis, _handle);
       } else {
diff --git a/sdk/lib/_internal/lib/isolate_patch.dart b/sdk/lib/_internal/lib/isolate_patch.dart
index 9d931a9..3858c15 100644
--- a/sdk/lib/_internal/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/lib/isolate_patch.dart
@@ -12,9 +12,10 @@
                                    RawReceivePortImpl;
 
 patch class Isolate {
-  patch static Future<Isolate> spawn(void entryPoint(message), var message) {
+  patch static Future<Isolate> spawn(void entryPoint(message), var message,
+                                     { bool paused: false }) {
     try {
-      return IsolateNatives.spawnFunction(entryPoint, message)
+      return IsolateNatives.spawnFunction(entryPoint, message, paused)
           .then((msg) => new Isolate._fromControlPort(msg[1], msg[2]));
     } catch (e, st) {
       return new Future<Isolate>.error(e, st);
@@ -22,7 +23,7 @@
   }
 
   patch static Future<Isolate> spawnUri(
-      Uri uri, List<String> args, var message) {
+      Uri uri, List<String> args, var message, { bool paused: false }) {
     try {
       if (args is List<String>) {
         for (int i = 0; i < args.length; i++) {
@@ -33,7 +34,7 @@
       } else if (args != null) {
         throw new ArgumentError("Args must be a list of Strings $args");
       }
-      return IsolateNatives.spawnUri(uri, args, message)
+      return IsolateNatives.spawnUri(uri, args, message, paused)
           .then((msg) => new Isolate._fromControlPort(msg[1], msg[2]));
     } catch (e, st) {
       return new Future<Isolate>.error(e, st);
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index cef540b..c9134a2 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -366,6 +366,8 @@
   /// type variables).
   final functionType;
 
+  List cachedSortedIndices;
+
   ReflectionInfo.internal(this.jsFunction,
                           this.data,
                           this.isAccessor,
@@ -412,6 +414,53 @@
               FIRST_DEFAULT_ARGUMENT, parameter, requiredParameterCount);
   }
 
+  /// Returns the default value of the [parameter]th entry of the list of
+  /// parameters sorted by name.
+  int defaultValueInOrder(int parameter) {
+    if (parameter < requiredParameterCount) return null;
+
+    if (!areOptionalParametersNamed || optionalParameterCount == 1) {
+      return defaultValue(parameter);
+    }
+
+    int index = sortedIndex(parameter - requiredParameterCount);
+    return defaultValue(index);
+  }
+
+  /// Returns the default value of the [parameter]th entry of the list of
+  /// parameters sorted by name.
+  String parameterNameInOrder(int parameter) {
+    if (parameter < requiredParameterCount) return null;
+
+    if (!areOptionalParametersNamed ||
+        optionalParameterCount == 1) {
+      return parameterName(parameter);
+    }
+
+    int index = sortedIndex(parameter - requiredParameterCount);
+    return parameterName(index);
+  }
+
+  /// Computes the index of the parameter in the list of named parameters sorted
+  /// by their name.
+  int sortedIndex(int unsortedIndex) {
+    if (cachedSortedIndices == null) {
+      // TODO(karlklose): cache this between [ReflectionInfo] instances or cache
+      // [ReflectionInfo] instances by [jsFunction].
+      cachedSortedIndices = new List(optionalParameterCount);
+      Map<String, int> positions = <String, int>{};
+      for (int i = 0; i < optionalParameterCount; i++) {
+        int index = requiredParameterCount + i;
+        positions[parameterName(index)] = index;
+      }
+      int index = 0;
+      (positions.keys.toList()..sort()).forEach((String name) {
+        cachedSortedIndices[index++] = positions[name];
+      });
+    }
+    return cachedSortedIndices[unsortedIndex];
+  }
+
   @NoInline()
   computeFunctionRti(jsConstructor) {
     if (JS('bool', 'typeof # == "number"', functionType)) {
@@ -923,9 +972,10 @@
       }
       var defaultArguments = new Map();
       for (int i = 0; i < info.optionalParameterCount; i++) {
-        var parameterName = info.parameterName(i + info.requiredParameterCount);
-        var defaultValue =
-            getMetadata(info.defaultValue(i + info.requiredParameterCount));
+        int index = i + info.requiredParameterCount;
+        var parameterName = info.parameterNameInOrder(index);
+        var value = info.defaultValueInOrder(index);
+        var defaultValue = getMetadata(value);
         defaultArguments[parameterName] = defaultValue;
       }
       bool bad = false;
diff --git a/sdk/lib/_internal/lib/js_string.dart b/sdk/lib/_internal/lib/js_string.dart
index 6693821..4055647 100644
--- a/sdk/lib/_internal/lib/js_string.dart
+++ b/sdk/lib/_internal/lib/js_string.dart
@@ -180,35 +180,80 @@
   String trim() {
     const int CARRIAGE_RETURN = 0x0D;
     const int SPACE = 0x20;
+    const int NEL = 0x85;
+    const int BOM = 0xFEFF;
 
+    // Start by doing JS trim. Then check if it leaves a NEL or BOM at
+    // either end of the string.
+    String result = JS('String', '#.trim()', this);
+
+    if (result.length == 0) return result;
+    int firstCode = result.codeUnitAt(0);
     int startIndex = 0;
-    while (startIndex < this.length) {
-      int codeUnit = this.codeUnitAt(startIndex);
-      if (codeUnit == SPACE ||
-          codeUnit == CARRIAGE_RETURN ||
-          _isWhitespace(codeUnit)) {
-        startIndex++;
-      } else {
-        break;
+    if (firstCode == NEL || firstCode == BOM) {
+      startIndex++;
+      while (startIndex < result.length) {
+        int codeUnit = result.codeUnitAt(startIndex);
+        if (codeUnit == SPACE ||
+            codeUnit == CARRIAGE_RETURN ||
+            _isWhitespace(codeUnit)) {
+          startIndex++;
+        } else {
+          break;
+        }
       }
+      if (startIndex == result.length) return "";
     }
-    if (startIndex == this.length) return "";
 
-    int endIndex = this.length;
+    int endIndex = result.length;
     // We know that there is at least one character that is non-whitespace.
     // Therefore we don't need to verify that endIndex > startIndex.
-    while (true) {
-      int codeUnit = this.codeUnitAt(endIndex - 1);
-      if (codeUnit == SPACE ||
-          codeUnit == CARRIAGE_RETURN ||
-          _isWhitespace(codeUnit)) {
-        endIndex--;
-      } else {
-        break;
+    int lastCode = result.codeUnitAt(endIndex - 1);
+    if (lastCode == NEL || lastCode == BOM) {
+      endIndex--;
+      while (true) {
+        int codeUnit = result.codeUnitAt(endIndex - 1);
+        if (codeUnit == SPACE ||
+            codeUnit == CARRIAGE_RETURN ||
+            _isWhitespace(codeUnit)) {
+          endIndex--;
+        } else {
+          break;
+        }
       }
     }
-    if (startIndex == 0 && endIndex == this.length) return this;
-    return JS('String', r'#.substring(#, #)', this, startIndex, endIndex);
+    if (startIndex == 0 && endIndex == result.length) return result;
+    return JS('String', r'#.substring(#, #)', result, startIndex, endIndex);
+  }
+
+  String operator*(int times) {
+    if (0 >= times) return '';  // Unnecessary but hoists argument type check.
+    if (times == 1 || this.length == 0) return this;
+    if (times != JS('JSUInt32', '# >>> 0', times)) {
+      // times >= 2^32. We can't create a string that big.
+      throw const OutOfMemoryError();
+    }
+    var result = '';
+    var s = this;
+    while (true) {
+      if (times & 1 == 1) result = s + result;
+      times = JS('JSUInt31', '# >>> 1', times);
+      if (times == 0) break;
+      s += s;
+    }
+    return result;
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return padding * delta + this;
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return this + padding * delta;
   }
 
   List<int> get codeUnits => new _CodeUnits(this);
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index ae69197..ffd301f 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -12,10 +12,10 @@
 import 'utils.dart';
 import 'version.dart';
 
-/// The currently supported version of the Barback package that this version of
+/// The currently supported versions of the Barback package that this version of
 /// pub works with.
 ///
-/// Pub implicitly constrains barback to this version or later patch versions.
+/// Pub implicitly constrains barback to these versions.
 ///
 /// Barback is in a unique position. Pub imports it, so a copy of Barback is
 /// physically included in the SDK. Packages also depend on Barback (from
@@ -31,7 +31,7 @@
 ///
 /// Whenever a new non-patch version of barback is published, this *must* be
 /// incremented to synchronize with that.
-final supportedVersion = new Version(0, 11, 0);
+final supportedVersions = new VersionConstraint.parse(">=0.11.0 <0.13.0");
 
 /// A list of the names of all built-in transformers that pub exposes.
 const _BUILT_IN_TRANSFORMERS = const ['\$dart2js'];
@@ -126,39 +126,55 @@
   return new Uri(scheme: 'package', path: id.path.replaceFirst('lib/', ''));
 }
 
-/// Converts [uri] into an [AssetId] if it has a path containing "packages" or
+/// Converts [uri] into an [AssetId] if its path is within "packages" or
 /// "assets".
 ///
-/// If the URI doesn't contain one of those special directories, returns null.
-/// If it does contain a special directory, but lacks a following package name,
+/// While "packages" can appear anywhere in the path, "assets" is only allowed
+/// as the top-level directory. (This throws a [FormatException] if "assets"
+/// appears anywhere else.)
+///
+/// If the URL contains a special directory, but lacks a following package name,
 /// throws a [FormatException].
+///
+/// If the URI doesn't contain one of those special directories, returns null.
 AssetId specialUrlToId(Uri url) {
   var parts = path.url.split(url.path);
 
-  for (var pair in [["packages", "lib"], ["assets", "asset"]]) {
-    var partName = pair.first;
-    var dirName = pair.last;
+  // Strip the leading "/" from the URL.
+  if (parts.isNotEmpty && parts.first == "/") parts = parts.skip(1).toList();
 
-    // Find the package name and the relative path in the package.
-    var index = parts.indexOf(partName);
-    if (index == -1) continue;
+  if (parts.isEmpty) return null;
 
-    // If we got here, the path *did* contain the special directory, which
-    // means we should not interpret it as a regular path. If it's missing the
-    // package name after the special directory, it's invalid.
-    if (index + 1 >= parts.length) {
+  // Check for "assets" at the beginning of the URL.
+  if (parts.first == "assets") {
+    if (parts.length <= 1) {
       throw new FormatException(
-          'Invalid package path "${path.url.joinAll(parts)}". '
-          'Expected package name after "$partName".');
+          'Invalid URL path "${url.path}". Expected package name after '
+          '"assets".');
     }
 
-    var package = parts[index + 1];
-    var assetPath = path.url.join(dirName,
-        path.url.joinAll(parts.skip(index + 2)));
+    var package = parts[1];
+    var assetPath = path.url.join("asset", path.url.joinAll(parts.skip(2)));
     return new AssetId(package, assetPath);
   }
 
-  return null;
+  // Check for "packages" anywhere in the URL.
+  // TODO(rnystrom): If we rewrite "package:" imports to relative imports that
+  // point to a canonical "packages" directory, we can limit "packages" to the
+  // root of the URL as well. See: #16649.
+  var index = parts.indexOf("packages");
+  if (index == -1) return null;
+
+  // There should be a package name after "packages".
+  if (parts.length <= index + 1) {
+    throw new FormatException(
+        'Invalid URL path "${url.path}". Expected package name '
+        'after "packages".');
+  }
+
+  var package = parts[index + 1];
+  var assetPath = path.url.join("lib", path.url.joinAll(parts.skip(index + 2)));
+  return new AssetId(package, assetPath);
 }
 
 /// Converts [id] to a "servable path" for that asset.
diff --git a/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart b/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
index af2eae8..47c242d 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
@@ -33,10 +33,16 @@
   /// Creates a new build environment for working with the assets used by
   /// [entrypoint] and its dependencies.
   ///
-  /// Spawns an HTTP server on [hostname] and [port]. Loads all used
-  /// transformers using [mode] (including dart2js if [useDart2JS] is true).
+  /// Spawns an HTTP server for each directory in [rootDirectories]. These
+  /// servers will be on [hostname] and have ports based on [basePort].
+  /// [basePort] itself is reserved for "web/" and `basePort + 1` is reserved
+  /// for "test/"; further ports will be allocated for other root directories as
+  /// necessary. If [basePort] is zero, each server will have an ephemeral port.
   ///
-  /// Includes [buildDirectories] in the root package, as well as "lib" and
+  /// Loads all used transformers using [mode] (including dart2js if
+  /// [useDart2JS] is true).
+  ///
+  /// Includes [rootDirectories] in the root package, as well as "lib" and
   /// "asset".
   ///
   /// If [watcherType] is not [WatcherType.NONE], watches source assets for
@@ -45,17 +51,17 @@
   /// Returns a [Future] that completes to the environment once the inputs,
   /// transformers, and server are loaded and ready.
   static Future<BuildEnvironment> create(Entrypoint entrypoint,
-      String hostname, int port, BarbackMode mode, WatcherType watcherType,
-      Set<String> buildDirectories,
+      String hostname, int basePort, BarbackMode mode, WatcherType watcherType,
+      Iterable<String> rootDirectories,
       {bool useDart2JS: true}) {
     return entrypoint.loadPackageGraph().then((graph) {
       var barback = new Barback(new PubPackageProvider(graph));
       barback.log.listen(_log);
 
-      return BarbackServer.bind(hostname, port, barback,
-          graph.entrypoint.root.name).then((server) {
-        var environment = new BuildEnvironment._(graph, server, mode,
-            watcherType, buildDirectories);
+      return _startServers(hostname, basePort, mode, graph, barback,
+          rootDirectories).then((servers) {
+        var environment = new BuildEnvironment._(graph, servers, mode,
+            watcherType, rootDirectories);
 
         // If the entrypoint package manually configures the dart2js
         // transformer, don't include it in the built-in transformer list.
@@ -78,11 +84,43 @@
     });
   }
 
-  /// The server serving this environment's assets.
-  final BarbackServer server;
+  /// Start the [BarbackServer]s that will serve [rootDirectories].
+  static Future<List<BarbackServer>> _startServers(String hostname,
+      int basePort, BarbackMode mode, PackageGraph graph, Barback barback,
+      Iterable<String> rootDirectories) {
+    _bind(port, rootDirectory) {
+      if (basePort == 0) port = 0;
+      return BarbackServer.bind(hostname, port, barback,
+          graph.entrypoint.root.name, rootDirectory);
+    }
+
+    var rootDirectoryList = rootDirectories.toList();
+
+    // For consistency, "web/" should always have the first available port and
+    // "test/" should always have the second. Other directories are assigned
+    // the following ports in alphabetical order.
+    var serverFutures = [];
+    if (rootDirectoryList.remove('web')) {
+      serverFutures.add(_bind(basePort, 'web'));
+    }
+    if (rootDirectoryList.remove('test')) {
+      serverFutures.add(_bind(basePort + 1, 'test'));
+    }
+
+    var i = 0;
+    for (var dir in rootDirectoryList) {
+      serverFutures.add(_bind(basePort + 2 + i, dir));
+      i += 1;
+    }
+
+    return Future.wait(serverFutures);
+  }
+
+  /// The servers serving this environment's assets.
+  final List<BarbackServer> servers;
 
   /// The [Barback] instance used to process assets in this environment.
-  Barback get barback => server.barback;
+  Barback get barback => servers.first.barback;
 
   /// The root package being built.
   Package get rootPackage => graph.entrypoint.root;
@@ -100,12 +138,13 @@
   /// How source files should be watched.
   final WatcherType _watcherType;
 
-  /// The set of top-level directories in the entrypoint package that should be
-  /// built.
-  final Set<String> _buildDirectories;
+  /// The set of top-level directories in the entrypoint package that will be
+  /// exposed.
+  final Set<String> _rootDirectories;
 
-  BuildEnvironment._(this.graph, this.server, this.mode, this._watcherType,
-      this._buildDirectories);
+  BuildEnvironment._(this.graph, this.servers, this.mode, this._watcherType,
+      Iterable<String> rootDirectories)
+      : _rootDirectories = rootDirectories.toSet();
 
   /// Gets the built-in [Transformer]s that should be added to [package].
   ///
@@ -121,7 +160,7 @@
     return _builtInTransformers;
   }
 
-  /// Creates a [BarbackServer] for this environment.
+  /// Loads the assets and transformers for this environment.
   ///
   /// This transforms and serves all library and asset files in all packages in
   /// the environment's package graph. It loads any transformer plugins defined
@@ -134,21 +173,24 @@
     return _provideSources(barback).then((_) {
       var completer = new Completer();
 
-      // If any errors get emitted either by barback or by the server,
+      // If any errors get emitted either by barback or by the primary server,
       // including non-programmatic barback errors, they should take down the
       // whole program.
       var subscriptions = [
-        server.barback.errors.listen((error) {
+        barback.errors.listen((error) {
           if (error is TransformerException) error = error.error;
           if (!completer.isCompleted) {
             completer.completeError(error, new Chain.current());
           }
         }),
-        server.barback.results.listen((_) {}, onError: (error, stackTrace) {
+        barback.results.listen((_) {},
+            onError: (error, stackTrace) {
           if (completer.isCompleted) return;
           completer.completeError(error, stackTrace);
         }),
-        server.results.listen((_) {}, onError: (error, stackTrace) {
+        // We only listen to the first server here because that's the one used
+        // to initialize all the transformers during the initial load.
+        servers.first.results.listen((_) {}, onError: (error, stackTrace) {
           if (completer.isCompleted) return;
           completer.completeError(error, stackTrace);
         })
@@ -296,7 +338,7 @@
     var directories = ["asset", "lib"];
 
     if (package.name == entrypoint.root.name) {
-      directories.addAll(_buildDirectories);
+      directories.addAll(_rootDirectories);
     }
 
     return directories;
@@ -353,6 +395,10 @@
     case LogLevel.INFO:
       log.message("${log.cyan(prefix)}\n$message");
       break;
+
+    case LogLevel.FINE:
+      log.fine("${log.gray(prefix)}\n$message");
+      break;
   }
 }
 
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
index 84ca336..6f23229 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -20,30 +20,29 @@
 import '../barback.dart';
 import '../dart.dart' as dart;
 import '../io.dart';
+import '../pool.dart';
 import '../utils.dart';
 import 'build_environment.dart';
 
 /// The set of all valid configuration options for this transformer.
 final _validOptions = new Set<String>.from([
   'commandLineOptions', 'checked', 'minify', 'verbose', 'environment',
-  'analyzeAll', 'suppressWarnings', 'suppressHints', 'terse'
+  'analyzeAll', 'suppressWarnings', 'suppressHints', 'suppressPackageWarnings',
+  'terse'
 ]);
 
 /// A [Transformer] that uses dart2js's library API to transform Dart
 /// entrypoints in "web" to JavaScript.
 class Dart2JSTransformer extends Transformer implements LazyTransformer {
-  final BuildEnvironment _environment;
-  final BarbackSettings _settings;
-
-  /// If this is non-null, then the transformer is currently being applied, so
-  /// subsequent calls to [apply] will wait for this to finish before
-  /// proceeding.
+  /// We use this to ensure that only one compilation is in progress at a time.
   ///
   /// Dart2js uses lots of memory, so if we try to actually run compiles in
-  /// parallel, it takes down the VM. Instead, the transformer will force
-  /// all applies to be sequential. The tracking bug to do something better
+  /// parallel, it takes down the VM. The tracking bug to do something better
   /// is here: https://code.google.com/p/dart/issues/detail?id=14730.
-  Future _running;
+  static final _pool = new Pool(1);
+
+  final BuildEnvironment _environment;
+  final BarbackSettings _settings;
 
   Dart2JSTransformer.withSettings(this._environment, this._settings) {
     var invalidOptions = _settings.configuration.keys.toSet()
@@ -70,70 +69,62 @@
   }
 
   Future apply(Transform transform) {
-    // Wait for any ongoing apply to finish first.
-    // TODO(rnystrom): If there are multiple simultaneous compiles, this will
-    // resume and pause them repeatedly. It still serializes them correctly,
-    // but it might be cleaner to use a real queue.
-    // TODO(rnystrom): Add a test that this is functionality is helpful.
-    if (_running != null) {
-      return _running.then((_) => apply(transform));
-    }
-
-    var completer = new Completer();
-    _running = completer.future;
-
     var stopwatch = new Stopwatch();
-    stopwatch.start();
 
-    return transform.primaryInput.readAsString().then((code) {
-      try {
-        var id = transform.primaryInput.id;
-        var name = id.path;
-        if (id.package != _environment.rootPackage.name) {
-          name += " in ${id.package}";
+    // Wait for any ongoing apply to finish first.
+    return _pool.withResource(() {
+      transform.logger.info("Compiling ${transform.primaryInput.id}...");
+      stopwatch.start();
+
+      return transform.primaryInput.readAsString().then((code) {
+        try {
+          var id = transform.primaryInput.id;
+          var name = id.path;
+          if (id.package != _environment.rootPackage.name) {
+            name += " in ${id.package}";
+          }
+
+          var parsed = parseCompilationUnit(code, name: name);
+          if (!dart.isEntrypoint(parsed)) return null;
+        } on AnalyzerErrorGroup catch (e) {
+          transform.logger.error(e.message);
+          return null;
         }
 
-        var parsed = parseCompilationUnit(code, name: name);
-        if (!dart.isEntrypoint(parsed)) return null;
-      } on AnalyzerErrorGroup catch (e) {
-        transform.logger.error(e.message);
-        return null;
-      }
+        var provider = new _BarbackCompilerProvider(_environment, transform);
 
-      var provider = new _BarbackCompilerProvider(_environment, transform);
+        // Create a "path" to the entrypoint script. The entrypoint may not
+        // actually be on disk, but this gives dart2js a root to resolve
+        // relative paths against.
+        var id = transform.primaryInput.id;
 
-      // Create a "path" to the entrypoint script. The entrypoint may not
-      // actually be on disk, but this gives dart2js a root to resolve
-      // relative paths against.
-      var id = transform.primaryInput.id;
+        var entrypoint = path.join(_environment.graph.packages[id.package].dir,
+            id.path);
 
-      var entrypoint = path.join(_environment.graph.packages[id.package].dir,
-          id.path);
-
-      // TODO(rnystrom): Should have more sophisticated error-handling here.
-      // Need to report compile errors to the user in an easily visible way.
-      // Need to make sure paths in errors are mapped to the original source
-      // path so they can understand them.
-      return Chain.track(dart.compile(
-          entrypoint, provider,
-          commandLineOptions: _configCommandLineOptions,
-          checked: _configBool('checked'),
-          minify: _configBool(
-              'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE),
-          verbose: _configBool('verbose'),
-          environment: _configEnvironment,
-          packageRoot: path.join(_environment.rootPackage.dir,
-                                 "packages"),
-          analyzeAll: _configBool('analyzeAll'),
-          suppressWarnings: _configBool('suppressWarnings'),
-          suppressHints: _configBool('suppressHints'),
-          terse: _configBool('terse'))).then((_) {
-        stopwatch.stop();
-        transform.logger.info("Took ${stopwatch.elapsed} to compile $id.");
+        // TODO(rnystrom): Should have more sophisticated error-handling here.
+        // Need to report compile errors to the user in an easily visible way.
+        // Need to make sure paths in errors are mapped to the original source
+        // path so they can understand them.
+        return Chain.track(dart.compile(
+            entrypoint, provider,
+            commandLineOptions: _configCommandLineOptions,
+            checked: _configBool('checked'),
+            minify: _configBool(
+                'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE),
+            verbose: _configBool('verbose'),
+            environment: _configEnvironment,
+            packageRoot: path.join(_environment.rootPackage.dir,
+                                   "packages"),
+            analyzeAll: _configBool('analyzeAll'),
+            suppressWarnings: _configBool('suppressWarnings'),
+            suppressHints: _configBool('suppressHints'),
+            suppressPackageWarnings: _configBool(
+                'suppressPackageWarnings', defaultsTo: true),
+            terse: _configBool('terse'))).then((_) {
+          stopwatch.stop();
+          transform.logger.info("Took ${stopwatch.elapsed} to compile $id.");
+        });
       });
-    }).whenComplete(() {
-      completer.complete();
-      _running = null;
     });
   }
 
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index e1ac463..7ff0dc5 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -18,8 +18,9 @@
 
 /// Loads all transformers depended on by packages in [environment].
 ///
-/// This uses [environment]'s server to serve the Dart files from which
-/// transformers are loaded, then adds the transformers to `server.barback`.
+/// This uses [environment]'s primary server to serve the Dart files from which
+/// transformers are loaded, then adds the transformers to
+/// `environment.barback`.
 ///
 /// Any built-in transformers that are provided by the environment will
 /// automatically be added to the end of the root package's cascade.
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
index 30aefde..72768f4 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -366,8 +366,11 @@
   return id.getAssetId(environment.barback).then((assetId) {
     var path = assetId.path.replaceFirst('lib/', '');
     // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
-    var baseUrl = baseUrlForAddress(environment.server.address,
-                                    environment.server.port);
+
+    // We could load the transformers from any server, since they all serve the
+    // packages' library files. We choose the first one arbitrarily.
+    var baseUrl = baseUrlForAddress(environment.servers.first.address,
+                                    environment.servers.first.port);
     var uri = '$baseUrl/packages/${id.package}/$path';
     var code = 'import "$uri";\n' +
         _TRANSFORMER_ISOLATE.replaceAll('<<URL_BASE>>', baseUrl);
@@ -479,6 +482,8 @@
       var method;
       if (message['level'] == 'Info') {
         method = transform.logger.info;
+      } else if (message['level'] == 'Fine') {
+        method = transform.logger.fine;
       } else if (message['level'] == 'Warning') {
         method = transform.logger.warning;
       } else {
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index c783771..a324ecb 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -25,10 +25,14 @@
   /// The underlying HTTP server.
   final HttpServer _server;
 
-  /// The name of the root package, from whose `web` directory root assets will
-  /// be served.
+  /// The name of the root package, from whose [rootDirectory] assets will be
+  /// served.
   final String _rootPackage;
 
+  /// The directory in [_rootPackage] which will serve as the root of this
+  /// server.
+  final String rootDirectory;
+
   /// The barback instance from which this serves assets.
   final Barback barback;
 
@@ -61,12 +65,14 @@
   /// This server will serve assets from [barback], and use [rootPackage] as
   /// the root package.
   static Future<BarbackServer> bind(String host, int port,
-      Barback barback, String rootPackage) {
-    return Chain.track(HttpServer.bind(host, port))
-        .then((server) => new BarbackServer._(server, barback, rootPackage));
+      Barback barback, String rootPackage, String rootDirectory) {
+    return Chain.track(HttpServer.bind(host, port)).then((server) {
+      return new BarbackServer._(server, barback, rootPackage, rootDirectory);
+    });
   }
 
-  BarbackServer._(HttpServer server, this.barback, this._rootPackage)
+  BarbackServer._(HttpServer server, this.barback, this._rootPackage,
+      this.rootDirectory)
       : _server = server,
         port = server.port,
         address = server.address {
@@ -111,42 +117,24 @@
     }
 
     _logRequest(request, "Loading $id");
-    barback.getAssetById(id).then((asset) {
-      return validateStream(asset.read()).then((stream) {
-        _resultsController.add(
-            new BarbackServerResult._success(request.uri, id));
-        var mimeType = lookupMimeType(id.path);
-        if (mimeType != null) {
-          request.response.headers.add('content-type', mimeType);
-        }
-        // TODO(rnystrom): Set content-type based on asset type.
-        return Chain.track(request.response.addStream(stream)).then((_) {
-          // Log successful requests both so we can provide debugging
-          // information and so scheduled_test knows we haven't timed out while
-          // loading transformers.
-          _logRequest(request, "Served $id");
-          request.response.close();
-        });
-      }).catchError((error, trace) {
-        _resultsController.add(
-            new BarbackServerResult._failure(request.uri, id, error));
+    barback.getAssetById(id)
+        .then((asset) => _serveAsset(request, asset))
+        .catchError((error, trace) {
+      if (error is! AssetNotFoundException) throw error;
+      return barback.getAssetById(id.addExtension("/index.html")).then((asset) {
+        if (request.uri.path.endsWith('/')) return _serveAsset(request, asset);
 
-        // If we couldn't read the asset, handle the error gracefully.
-        if (error is FileSystemException) {
-          // Assume this means the asset was a file-backed source asset
-          // and we couldn't read it, so treat it like a missing asset.
-          _notFound(request, error);
-          return;
-        }
-
-        trace = new Chain.forTrace(trace);
-        _logRequest(request, "$error\n$trace");
-
-        // Otherwise, it's some internal error.
-        request.response.statusCode = 500;
-        request.response.reasonPhrase = "Internal Error";
-        request.response.write(error);
+        // We only want to serve index.html if the URL explicitly ends in a
+        // slash. For other URLs, we redirect to one with the slash added to
+        // implicitly support that too. This follows Apache's behavior.
+        _logRequest(request, "302 Redirect to ${request.uri}/");
+        request.response.statusCode = 302;
+        request.response.headers.add('location', '${request.uri}/');
         request.response.close();
+      }).catchError((newError, newTrace) {
+        // If we find neither the original file or the index, we should report
+        // the error about the original to the user.
+        throw newError is AssetNotFoundException ? error : newError;
       });
     }).catchError((error, trace) {
       if (error is! AssetNotFoundException) {
@@ -164,6 +152,49 @@
     });
   }
 
+  /// Serves the body of [asset] on [request]'s response stream.
+  ///
+  /// Returns a future that completes when the response has been succesfully
+  /// written.
+  Future _serveAsset(HttpRequest request, Asset asset) {
+    return validateStream(asset.read()).then((stream) {
+      _resultsController.add(
+          new BarbackServerResult._success(request.uri, asset.id));
+      var mimeType = lookupMimeType(asset.id.path);
+      if (mimeType != null) {
+        request.response.headers.add('content-type', mimeType);
+      }
+      // TODO(rnystrom): Set content-type based on asset type.
+      return Chain.track(request.response.addStream(stream)).then((_) {
+        // Log successful requests both so we can provide debugging
+        // information and so scheduled_test knows we haven't timed out while
+        // loading transformers.
+        _logRequest(request, "Served ${asset.id}");
+        request.response.close();
+      });
+    }).catchError((error, trace) {
+      _resultsController.add(
+          new BarbackServerResult._failure(request.uri, asset.id, error));
+
+      // If we couldn't read the asset, handle the error gracefully.
+      if (error is FileSystemException) {
+        // Assume this means the asset was a file-backed source asset
+        // and we couldn't read it, so treat it like a missing asset.
+        _notFound(request, error);
+        return;
+      }
+
+      trace = new Chain.forTrace(trace);
+      _logRequest(request, "$error\n$trace");
+
+      // Otherwise, it's some internal error.
+      request.response.statusCode = 500;
+      request.response.reasonPhrase = "Internal Error";
+      request.response.write(error);
+      request.response.close();
+    });
+  }
+
   /// Creates a web socket for [request] which should be an upgrade request.
   void _handleWebSocket(HttpRequest request) {
     Chain.track(WebSocketTransformer.upgrade(request)).then((socket) {
@@ -241,13 +272,13 @@
     var id = specialUrlToId(url);
     if (id != null) return id;
 
-    // Otherwise, it's a path in current package's web directory.
+    // Otherwise, it's a path in current package's [rootDirectory].
     var parts = path.url.split(url.path);
 
     // Strip the leading "/" from the URL.
     if (parts.isNotEmpty && parts.first == "/") parts = parts.skip(1);
 
-    var relativePath = path.url.join("web", path.url.joinAll(parts));
+    var relativePath = path.url.join(rootDirectory, path.url.joinAll(parts));
     return new AssetId(_rootPackage, relativePath);
   }
 
diff --git a/sdk/lib/_internal/pub/lib/src/command.dart b/sdk/lib/_internal/pub/lib/src/command.dart
index d5eb6ea..92cafec 100644
--- a/sdk/lib/_internal/pub/lib/src/command.dart
+++ b/sdk/lib/_internal/pub/lib/src/command.dart
@@ -85,7 +85,7 @@
     buffer.writeln('Available ${isSubcommand ? "sub" : ""}commands:');
     for (var name in names) {
       buffer.writeln('  ${padRight(name, length)}   '
-          '${commands[name].description}');
+          '${commands[name].description.split("\n").first}');
     }
 
     return buffer.toString();
diff --git a/sdk/lib/_internal/pub/lib/src/command/build.dart b/sdk/lib/_internal/pub/lib/src/command/build.dart
index eba1a10..aee823a 100644
--- a/sdk/lib/_internal/pub/lib/src/command/build.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/build.dart
@@ -68,12 +68,12 @@
 
       // Show in-progress errors, but not results. Those get handled implicitly
       // by getAllAssets().
-      environment.server.barback.errors.listen((error) {
+      environment.barback.errors.listen((error) {
         log.error(log.red("Build error:\n$error"));
       });
 
       return log.progress("Building ${entrypoint.root.name}",
-          () => environment.server.barback.getAllAssets()).then((assets) {
+          () => environment.barback.getAllAssets()).then((assets) {
         // Find all of the JS entrypoints we built.
         var dart2JSEntrypoints = assets
             .where((asset) => asset.id.path.endsWith(".dart.js"))
diff --git a/sdk/lib/_internal/pub/lib/src/command/serve.dart b/sdk/lib/_internal/pub/lib/src/command/serve.dart
index a03bdd9..eb7c517 100644
--- a/sdk/lib/_internal/pub/lib/src/command/serve.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/serve.dart
@@ -5,8 +5,10 @@
 library pub.command.serve;
 
 import 'dart:async';
+import 'dart:math' as math;
 
 import 'package:barback/barback.dart';
+import 'package:path/path.dart' as p;
 
 import '../barback/build_environment.dart';
 import '../barback/pub_package_provider.dart';
@@ -20,8 +22,12 @@
 
 /// Handles the `serve` pub command.
 class ServeCommand extends PubCommand {
-  String get description => "Run a local web development server.";
-  String get usage => "pub serve";
+  String get description =>
+      'Run a local web development server.\n\n'
+      'By default, this serves "web/" and "test/", but an explicit list of \n'
+      'directories to serve can be provided as well.';
+  String get usage => "pub serve [directories...]";
+  final takesArguments = true;
 
   PubPackageProvider _provider;
 
@@ -35,7 +41,7 @@
 
   ServeCommand() {
     commandParser.addOption('port', defaultsTo: '8080',
-        help: 'The port to listen on.');
+        help: 'The base port to listen on.');
 
     // A hidden option for the tests to work around a bug in some of the OS X
     // bots where "localhost" very rarely resolves to the IPv4 loopback address
@@ -66,24 +72,26 @@
         WatcherType.POLLING : WatcherType.AUTO;
 
     return BuildEnvironment.create(entrypoint, hostname, port, mode,
-        watcherType, ["web"].toSet(),
+        watcherType, _directoriesToServe,
         useDart2JS: useDart2JS).then((environment) {
 
       // In release mode, strip out .dart files since all relevant ones have
       // been compiled to JavaScript already.
       if (mode == BarbackMode.RELEASE) {
-        environment.server.allowAsset = (url) => !url.path.endsWith(".dart");
+        for (var server in environment.servers) {
+          server.allowAsset = (url) => !url.path.endsWith(".dart");
+        }
       }
 
       /// This completer is used to keep pub running (by not completing) and
       /// to pipe fatal errors to pub's top-level error-handling machinery.
       var completer = new Completer();
 
-      environment.server.barback.errors.listen((error) {
+      environment.barback.errors.listen((error) {
         log.error(log.red("Build error:\n$error"));
       });
 
-      environment.server.barback.results.listen((result) {
+      environment.barback.results.listen((result) {
         if (result.succeeded) {
           // TODO(rnystrom): Report using growl/inotify-send where available.
           log.message("Build completed ${log.green('successfully')}");
@@ -95,28 +103,83 @@
         if (!completer.isCompleted) completer.completeError(error, stackTrace);
       });
 
-      environment.server.results.listen((result) {
-        if (result.isSuccess) {
-          log.message("${log.green('GET')} ${result.url.path} $_arrow "
-              "${result.id}");
-          return;
-        }
+      var directoryLength = environment.servers
+          .map((server) => server.rootDirectory.length)
+          .reduce(math.max);
+      for (var server in environment.servers) {
+        // Add two characters to account for "[" and "]".
+        var directoryPrefix = log.gray(
+            padRight("[${server.rootDirectory}]", directoryLength + 2));
+        server.results.listen((result) {
+          if (result.isSuccess) {
+            log.message("$directoryPrefix ${log.green('GET')} "
+                "${result.url.path} $_arrow ${result.id}");
+            return;
+          }
 
-        var msg = "${log.red('GET')} ${result.url.path} $_arrow";
-        var error = result.error.toString();
-        if (error.contains("\n")) {
-          log.message("$msg\n${prefixLines(error)}");
-        } else {
-          log.message("$msg $error");
-        }
-      }, onError: (error, [stackTrace]) {
-        if (!completer.isCompleted) completer.completeError(error, stackTrace);
-      });
+          var msg = "$directoryPrefix ${log.red('GET')} ${result.url.path} "
+              "$_arrow";
+          var error = result.error.toString();
+          if (error.contains("\n")) {
+            log.message("$msg\n${prefixLines(error)}");
+          } else {
+            log.message("$msg $error");
+          }
+        }, onError: (error, [stackTrace]) {
+          if (completer.isCompleted) return;
+          completer.completeError(error, stackTrace);
+        });
 
-      log.message("Serving ${entrypoint.root.name} "
-          "on http://$hostname:${environment.server.port}");
+        log.message("Serving ${entrypoint.root.name} "
+            "${padRight(server.rootDirectory, directoryLength)} "
+            "on ${log.bold('http://$hostname:${server.port}')}");
+      }
 
       return completer.future;
     });
   }
+
+  /// Returns the set of directories that will be served from servers exposed to
+  /// the user.
+  ///
+  /// Throws a [UsageException] if the command-line arguments are invalid.
+  List<String> get _directoriesToServe {
+    if (commandOptions.rest.isEmpty) {
+      var directories = ['web', 'test'].where(dirExists).toList();
+      if (directories.isNotEmpty) return directories;
+      usageError(
+          'Your package must have "web" and/or "test" directories to serve,\n'
+          'or you must pass in directories to serve explicitly.');
+    }
+
+    var directories = commandOptions.rest.map(p.normalize).toList();
+    var invalid = directories.where((dir) => !isBeneath(dir, '.'));
+    if (invalid.isNotEmpty) {
+      usageError("${_directorySentence(invalid, "isn't", "aren't")} in this "
+          "package.");
+    }
+
+    var nonExistent = directories.where((dir) => !dirExists(dir));
+    if (nonExistent.isNotEmpty) {
+      usageError("${_directorySentence(nonExistent, "doesn't", "don't")} "
+          "exist.");
+    }
+
+    return directories;
+  }
+
+  /// Converts a list of [directoryNames] to a sentence.
+  ///
+  /// After the list of directories, [singularVerb] will be used if there is
+  /// only one directory and [pluralVerb] will be used if there are more than
+  /// one.
+  String _directorySentence(Iterable<String> directoryNames,
+      String singularVerb, String pluralVerb) {
+    var directories = pluralize('Directory', directoryNames.length,
+        plural: 'Directories');
+    var names = toSentence(ordered(directoryNames).map((dir) => '"$dir"'));
+    var verb = pluralize(singularVerb, directoryNames.length,
+        plural: pluralVerb);
+    return "$directories $names $verb";
+  }
 }
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index e160572..612e267 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -59,6 +59,7 @@
     bool analyzeAll: false,
     bool suppressWarnings: false,
     bool suppressHints: false,
+    bool suppressPackageWarnings: true,
     bool terse: false,
     bool toDart: false}) {
   return syncFuture(() {
@@ -69,6 +70,7 @@
     if (analyzeAll) options.add('--analyze-all');
     if (suppressWarnings) options.add('--suppress-warnings');
     if (suppressHints) options.add('--suppress-hints');
+    if (suppressPackageWarnings) options.add('--hide-package-warnings');
     if (terse) options.add('--terse');
     if (toDart) options.add('--output-type=dart');
 
diff --git a/sdk/lib/_internal/pub/lib/src/log.dart b/sdk/lib/_internal/pub/lib/src/log.dart
index 0dcf088..fd1166d 100644
--- a/sdk/lib/_internal/pub/lib/src/log.dart
+++ b/sdk/lib/_internal/pub/lib/src/log.dart
@@ -41,6 +41,7 @@
 final _magenta = getSpecial('\u001b[35m');
 final _red = getSpecial('\u001b[31m');
 final _yellow = getSpecial('\u001b[33m');
+final _gray = getSpecial('\u001b[1;30m');
 final _none = getSpecial('\u001b[0m');
 final _bold = getSpecial('\u001b[1m');
 
@@ -237,6 +238,12 @@
 /// Use this to highlight the most important piece of a long chunk of text.
 String bold(text) => "$_bold$text$_none";
 
+/// Wraps [text] in the ANSI escape codes to make it gray when on a platform
+/// that supports that.
+///
+/// Use this for text that's less important than the text around it.
+String gray(text) => "$_gray$text$_none";
+
 /// Wraps [text] in the ANSI escape codes to color it cyan when on a platform
 /// that supports that.
 ///
diff --git a/sdk/lib/_internal/pub/lib/src/pubspec.dart b/sdk/lib/_internal/pub/lib/src/pubspec.dart
index df9359a..b44bb55 100644
--- a/sdk/lib/_internal/pub/lib/src/pubspec.dart
+++ b/sdk/lib/_internal/pub/lib/src/pubspec.dart
@@ -177,15 +177,19 @@
             "$field.$library",
             () => new TransformerId.parse(library, configuration));
 
-        if (id.package != name && !id.isBuiltInTransformer &&
-            !dependencies.any((ref) => ref.name == id.package)) {
-          _error('"$field.$library" refers to a package that\'s not listed in '
-              '"dependencies".');
+        if (id.package != name &&
+            !id.isBuiltInTransformer &&
+            !dependencies.any((ref) => ref.name == id.package) &&
+            !devDependencies.any((ref) => ref.name == id.package) &&
+            !dependencyOverrides.any((ref) => ref.name == id.package)) {
+          _error('"$field.$library" refers to a package that\'s not a '
+              'dependency.');
         }
 
         return id;
       }).toSet();
     }).toList();
+
     return _transformers;
   }
   List<Set<TransformerId>> _transformers;
diff --git a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
index 6229c6e..186ac8e 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
@@ -402,14 +402,12 @@
       }
     } else {
       // Otherwise, indent it under the current selected package.
-      message = "| $message";
+      message = prefixLines(message);
     }
 
     // Indent for the previous selections.
-    var buffer = new StringBuffer();
-    buffer.writeAll(_selected.skip(1).map((_) => '| '));
-    buffer.write(message);
-    log.solver(buffer);
+    var prefix = _selected.skip(1).map((_) => '| ').join();
+    log.solver(prefixLines(message, prefix: prefix));
   }
 }
 
@@ -527,17 +525,15 @@
         // The length check here is to ensure we only add the barback
         // dependency once.
         if (dep.name == "barback" && dependencies.length == 1) {
-          var range = new VersionRange(
-              min: barback.supportedVersion, includeMin: true,
-              max: barback.supportedVersion.nextMinor, includeMax: false);
-          _solver.logSolve('add implicit $range pub dependency on barback');
+          _solver.logSolve('add implicit ${barback.supportedVersions} pub '
+              'dependency on barback');
 
           // Use the same source and description as the explicit dependency.
           // That way, this doesn't fail with a source/desc conflict if users
           // (like Dart team members) use things like a path dependency to
           // find barback.
-          var barbackDep = new PackageDep(dep.name, dep.source, range,
-              dep.description);
+          var barbackDep = new PackageDep(dep.name, dep.source,
+              barback.supportedVersions, dep.description);
           dependencies.add(new Dependency("pub itself", barbackDep));
         }
 
@@ -545,7 +541,11 @@
 
         // See if it's possible for a package to match that constraint.
         if (constraint.isEmpty) {
-          _solver.logSolve('disjoint constraints on ${dep.name}');
+          var constraints = _getDependencies(dep.name)
+              .map((dep) => "  ${dep.dep.constraint} from ${dep.depender}")
+              .join('\n');
+          _solver.logSolve(
+              'disjoint constraints on ${dep.name}:\n$constraints');
           throw new DisjointConstraintException(dep.name, dependencies);
         }
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/dependency.dart b/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
index 1715240..0f06d3f 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 
 import '../entrypoint.dart';
+import '../log.dart' as log;
 import '../package.dart';
 import '../validator.dart';
 import '../version.dart';
@@ -22,7 +23,17 @@
         return _warnAboutSource(dependency);
       }
 
-      if (dependency.constraint.isAny) _warnAboutConstraint(dependency);
+      if (dependency.constraint.isAny) {
+        _warnAboutNoConstraint(dependency);
+      } else if (dependency.constraint is Version) {
+        _warnAboutSingleVersionConstraint(dependency);
+      } else if (dependency.constraint is VersionRange) {
+        if (dependency.constraint.min == null) {
+          _warnAboutNoConstraintLowerBound(dependency);
+        } else if (dependency.constraint.max == null) {
+          _warnAboutNoConstraintUpperBound(dependency);
+        }
+      }
 
       return new Future.value();
     });
@@ -63,7 +74,7 @@
   }
 
   /// Warn that dependencies should have version constraints.
-  void _warnAboutConstraint(PackageDep dep) {
+  void _warnAboutNoConstraint(PackageDep dep) {
     var lockFile = entrypoint.loadLockFile();
     var message = 'Your dependency on "${dep.name}" should have a version '
         'constraint.';
@@ -75,15 +86,69 @@
         '  ${dep.name}: ${_constraintForVersion(locked.version)}\n';
     }
     warnings.add("$message\n"
-        "Without a constraint, you're promising to support all future "
-        "versions of ${dep.name}.");
+        'Without a constraint, you\'re promising to support ${log.bold("all")} '
+            'future versions of "${dep.name}".');
+  }
+
+  // Warn that dependencies should allow more than a single version.
+  void _warnAboutSingleVersionConstraint(PackageDep dep) {
+    warnings.add(
+        'Your dependency on "${dep.name}" should allow more than one version. '
+            'For example:\n'
+        '\n'
+        'dependencies:\n'
+        '  ${dep.name}: ${_constraintForVersion(dep.constraint)}\n'
+        '\n'
+        'Constraints that are too tight will make it difficult for people to '
+            'use your package\n'
+        'along with other packages that also depend on "${dep.name}".');
+  }
+
+  // Warn that dependencies should have lower bounds on their constraints.
+  void _warnAboutNoConstraintLowerBound(PackageDep dep) {
+    var message = 'Your dependency on "${dep.name}" should have a lower bound.';
+    var locked = entrypoint.loadLockFile().packages[dep.name];
+    if (locked != null) {
+      var constraint;
+      if (locked.version == (dep.constraint as VersionRange).max) {
+        constraint = _constraintForVersion(locked.version);
+      } else {
+        constraint = '">=${locked.version} ${dep.constraint}"';
+      }
+
+      message = '$message For example:\n'
+        '\n'
+        'dependencies:\n'
+        '  ${dep.name}: $constraint\n';
+    }
+    warnings.add("$message\n"
+        'Without a constraint, you\'re promising to support ${log.bold("all")} '
+            'previous versions of "${dep.name}".');
+  }
+
+  // Warn that dependencies should have upper bounds on their constraints.
+  void _warnAboutNoConstraintUpperBound(PackageDep dep) {
+    warnings.add(
+        'Your dependency on "${dep.name}" should have an upper bound. For '
+            'example:\n'
+        '\n'
+        'dependencies:\n'
+        '  ${dep.name}: "${dep.constraint} '
+            '${_upperBoundForVersion((dep.constraint as VersionRange).min)}"\n'
+        '\n'
+        'Without an upper bound, you\'re promising to support '
+            '${log.bold("all")} future versions of ${dep.name}.');
   }
 
   /// Returns the suggested version constraint for a dependency that was tested
   /// against [version].
-  String _constraintForVersion(Version version) {
-    if (version.major != 0) return '">=$version <${version.major + 1}.0.0"';
-    return '">=$version <${version.major}.${version.minor}.'
-        '${version.patch + 1}"';
+  String _constraintForVersion(Version version) =>
+      '">=$version ${_upperBoundForVersion(version)}"';
+
+  /// Returns the suggested upper bound for a dependency that was tested against
+  /// [version].
+  String _upperBoundForVersion(Version version) {
+    if (version.major != 0) return '<${version.major + 1}.0.0';
+    return '<${version.major}.${version.minor + 1}.0';
   }
 }
diff --git a/sdk/lib/_internal/pub/lib/src/version.dart b/sdk/lib/_internal/pub/lib/src/version.dart
index 1e92a3b..7577f9f 100644
--- a/sdk/lib/_internal/pub/lib/src/version.dart
+++ b/sdk/lib/_internal/pub/lib/src/version.dart
@@ -449,7 +449,7 @@
 
   bool get isEmpty => false;
 
-  bool get isAny => !includeMin && !includeMax;
+  bool get isAny => min == null && max == null;
 
   /// Tests if [other] matches falls within this version range.
   bool allows(Version other) {
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 66c996f..35bb8c3 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -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/hosted/version_negotiation_test: Timeout # Issue 14346
+test/hosted/version_negotiation_test: Pass, Timeout # Issue 14346
 
 [ $runtime == vm && $system == windows ]
 test/serve/warns_on_assets_paths_test: Pass, Fail # Issue 15741
diff --git a/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart b/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
index 64247ea..4be7a4a 100644
--- a/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
+++ b/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
@@ -62,9 +62,9 @@
 
       pub.shouldExit(1);
 
-      expect(pub.remainingStderr(), completion(equals(
+      pub.stderr.expect(emitsLines(
           "Pub 0.1.2+3 is incompatible with the current version of 127.0.0.1.\n"
-          "Upgrade pub to the latest version and try again.")));
+          "Upgrade pub to the latest version and try again."));
     });
   });
 }
diff --git a/sdk/lib/_internal/pub/test/implicit_barback_dependency_test.dart b/sdk/lib/_internal/pub/test/implicit_barback_dependency_test.dart
index 894cf51..3bc488a 100644
--- a/sdk/lib/_internal/pub/test/implicit_barback_dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/implicit_barback_dependency_test.dart
@@ -10,11 +10,11 @@
 main() {
   initConfig();
 
-  var current = barback.supportedVersion.toString();
-  var previous = new Version(barback.supportedVersion.major,
-      barback.supportedVersion.minor - 1, 0).toString();
-  var nextPatch = barback.supportedVersion.nextPatch.toString();
-  var max = barback.supportedVersion.nextMinor.toString();
+  var current = barback.supportedVersions.min.toString();
+  var previous = new Version(barback.supportedVersions.min.major,
+      barback.supportedVersions.min.minor - 1, 0).toString();
+  var nextPatch = barback.supportedVersions.min.nextPatch.toString();
+  var max = barback.supportedVersions.max.toString();
 
   forBothPubGetAndUpgrade((command) {
     integration("implicitly constrains barback to versions pub supports", () {
@@ -32,7 +32,7 @@
       pubCommand(command);
 
       d.packagesDir({
-        "barback": barback.supportedVersion.nextPatch.toString()
+        "barback": barback.supportedVersions.min.nextPatch.toString()
       }).validate();
     });
 
diff --git a/sdk/lib/_internal/pub/test/lish/archives_and_uploads_a_package_test.dart b/sdk/lib/_internal/pub/test/lish/archives_and_uploads_a_package_test.dart
index def2c85..e549750 100644
--- a/sdk/lib/_internal/pub/test/lish/archives_and_uploads_a_package_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/archives_and_uploads_a_package_test.dart
@@ -32,10 +32,8 @@
       request.response.close();
     });
 
-    expect(pub.nextLine(), completion(matches(r'Uploading\.\.\.+')));
-
-    expect(pub.nextLine(),
-        completion(equals('Package test_pkg 1.0.0 uploaded!')));
+    pub.stdout.expect(matches(r'Uploading\.\.\.+'));
+    pub.stdout.expect('Package test_pkg 1.0.0 uploaded!');
     pub.shouldExit(exit_codes.SUCCESS);
   });
 
diff --git a/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_doesnt_redirect_test.dart b/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
index dc8d4110..5bcc120 100644
--- a/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
@@ -29,8 +29,7 @@
       });
     });
 
-    expect(pub.nextErrLine(),
-        completion(equals('Failed to upload the package.')));
+    pub.stderr.expect('Failed to upload the package.');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_provides_an_error_test.dart b/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_provides_an_error_test.dart
index d574d74..496abcf 100644
--- a/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_provides_an_error_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/cloud_storage_upload_provides_an_error_test.dart
@@ -37,8 +37,7 @@
 
     // TODO(nweiz): This should use the server's error message once the client
     // can parse the XML.
-    expect(pub.nextErrLine(),
-        completion(equals('Failed to upload the package.')));
+    pub.stderr.expect('Failed to upload the package.');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/force_does_not_publish_if_there_are_errors_test.dart b/sdk/lib/_internal/pub/test/lish/force_does_not_publish_if_there_are_errors_test.dart
index ab7ef6e..4805cd5 100644
--- a/sdk/lib/_internal/pub/test/lish/force_does_not_publish_if_there_are_errors_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/force_does_not_publish_if_there_are_errors_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -22,8 +23,7 @@
     var pub = startPublish(server, args: ['--force']);
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(), completion(contains(
-        "Sorry, your package is missing a requirement and can't be "
-        "published yet.")));
+    pub.stderr.expect(consumeThrough("Sorry, your package is missing a "
+        "requirement and can't be published yet."));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart b/sdk/lib/_internal/pub/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
index 0d8d842..9ccccf4 100644
--- a/sdk/lib/_internal/pub/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
@@ -4,8 +4,9 @@
 
 import 'dart:convert';
 
-import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -32,7 +33,6 @@
     });
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStdout(), completion(contains(
-        'Package test_pkg 1.0.0 uploaded!')));
+    pub.stdout.expect(consumeThrough('Package test_pkg 1.0.0 uploaded!'));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/force_publishes_if_there_are_warnings_test.dart b/sdk/lib/_internal/pub/test/lish/force_publishes_if_there_are_warnings_test.dart
index d097e72..85ce297 100644
--- a/sdk/lib/_internal/pub/test/lish/force_publishes_if_there_are_warnings_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/force_publishes_if_there_are_warnings_test.dart
@@ -4,8 +4,9 @@
 
 import 'dart:convert';
 
-import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -36,11 +37,11 @@
     });
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(), completion(contains(
-        'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml'
-        ' should have an email address\n'
-        '  (e.g. "name <email>").')));
-    expect(pub.remainingStdout(), completion(contains(
-        'Package test_pkg 1.0.0 uploaded!')));
+    pub.stderr.expect(consumeThrough('Suggestions:'));
+    pub.stderr.expect(emitsLines(
+        '* Author "Nathan Weizenbaum" in pubspec.yaml should have an email '
+            'address\n'
+        '  (e.g. "name <email>").'));
+    pub.stdout.expect(consumeThrough('Package test_pkg 1.0.0 uploaded!'));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_error_test.dart b/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_error_test.dart
index 0730bcd..90432da 100644
--- a/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_error_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_error_test.dart
@@ -31,8 +31,8 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_success_test.dart b/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_success_test.dart
index f6ce3b7..16c34470 100644
--- a/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_success_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_creation_provides_a_malformed_success_test.dart
@@ -30,8 +30,8 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_creation_provides_an_error_test.dart b/sdk/lib/_internal/pub/test/lish/package_creation_provides_an_error_test.dart
index a1c134d..33a5e08 100644
--- a/sdk/lib/_internal/pub/test/lish/package_creation_provides_an_error_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_creation_provides_an_error_test.dart
@@ -32,8 +32,7 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(),
-        completion(equals('Your package was too boring.')));
+    pub.stderr.expect('Your package was too boring.');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_creation_provides_invalid_json_test.dart b/sdk/lib/_internal/pub/test/lish/package_creation_provides_invalid_json_test.dart
index 43af294..25d187f 100644
--- a/sdk/lib/_internal/pub/test/lish/package_creation_provides_invalid_json_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_creation_provides_invalid_json_test.dart
@@ -27,8 +27,9 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals('{not json')));
+    pub.stderr.expect(emitsLines(
+        'Invalid server response:\n'
+        '{not json'));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_continues_test.dart b/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_continues_test.dart
index f068b67..6d4972f 100644
--- a/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_continues_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_continues_test.dart
@@ -4,8 +4,9 @@
 
 import 'dart:convert';
 
-import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -36,7 +37,6 @@
     });
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStdout(),
-        completion(contains('Package test_pkg 1.0.0 uploaded!')));
+    pub.stdout.expect(consumeThrough('Package test_pkg 1.0.0 uploaded!'));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart b/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart
index 9c115bc..65ed4a6 100644
--- a/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -23,7 +24,6 @@
 
     pub.writeLine("n");
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(),
-        completion(contains("Package upload canceled.")));
+    pub.stderr.expect(consumeThrough("Package upload canceled."));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/package_validation_has_an_error_test.dart b/sdk/lib/_internal/pub/test/lish/package_validation_has_an_error_test.dart
index 5072213..9eeae1a 100644
--- a/sdk/lib/_internal/pub/test/lish/package_validation_has_an_error_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/package_validation_has_an_error_test.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -22,8 +23,7 @@
     var pub = startPublish(server);
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(), completion(contains(
-        "Sorry, your package is missing a requirement and can't be published "
-        "yet.")));
+    pub.stderr.expect(consumeThrough("Sorry, your package is missing a "
+        "requirement and can't be published yet."));
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_a_warning_test.dart b/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_a_warning_test.dart
index 8bf1251..c7925f4 100644
--- a/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_a_warning_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_a_warning_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -22,10 +23,12 @@
     var pub = startPublish(server, args: ['--dry-run']);
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(), completion(contains(
-        'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml should '
-            'have an email address\n'
-        '  (e.g. "name <email>").\n\n'
-        'Package has 1 warning.')));
+    pub.stderr.expect(consumeThrough('Suggestions:'));
+    pub.stderr.expect(emitsLines(
+        '* Author "Nathan Weizenbaum" in pubspec.yaml should have an email '
+            'address\n'
+        '  (e.g. "name <email>").\n'
+        '\n'
+        'Package has 1 warning.'));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_no_warnings_test.dart b/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_no_warnings_test.dart
index e83c7e8..37dac6b 100644
--- a/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_no_warnings_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/preview_package_validation_has_no_warnings_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 
 import '../../lib/src/exit_codes.dart' as exit_codes;
 import '../descriptor.dart' as d;
@@ -22,7 +23,6 @@
     var pub = startPublish(server, args: ['--dry-run']);
 
     pub.shouldExit(exit_codes.SUCCESS);
-    expect(pub.remainingStderr(),
-        completion(contains('Package has 0 warnings.')));
+    pub.stderr.expect(consumeThrough('Package has 0 warnings.'));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_fields_has_a_non_string_value_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_fields_has_a_non_string_value_test.dart
index 9e24715..b241a16 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_fields_has_a_non_string_value_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_fields_has_a_non_string_value_test.dart
@@ -27,8 +27,8 @@
       'fields': {'field': 12}
     };
     handleUploadForm(server, body);
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_fields_is_not_a_map_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_fields_is_not_a_map_test.dart
index 2f75460..260f1f3 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_fields_is_not_a_map_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_fields_is_not_a_map_test.dart
@@ -24,8 +24,8 @@
 
     var body = {'url': 'http://example.com/upload', 'fields': 12};
     handleUploadForm(server, body);
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_fields_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_fields_test.dart
index dd4fd51..3513df5 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_fields_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_fields_test.dart
@@ -24,8 +24,8 @@
 
     var body = {'url': 'http://example.com/upload'};
     handleUploadForm(server, body);
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_url_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_url_test.dart
index 0f27503..a08b581 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_url_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_is_missing_url_test.dart
@@ -30,8 +30,8 @@
     };
 
     handleUploadForm(server, body);
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_provides_an_error_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_provides_an_error_test.dart
index 2a415e4..c4f69a0 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_provides_an_error_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_provides_an_error_test.dart
@@ -29,7 +29,7 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('your request sucked')));
+    pub.stderr.expect('your request sucked');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_provides_invalid_json_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_provides_invalid_json_test.dart
index 21ca53a..4a993e7 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_provides_invalid_json_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_provides_invalid_json_test.dart
@@ -24,8 +24,9 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals('{not json')));
+    pub.stderr.expect(emitsLines(
+        'Invalid server response:\n'
+        '{not json'));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/lish/upload_form_url_is_not_a_string_test.dart b/sdk/lib/_internal/pub/test/lish/upload_form_url_is_not_a_string_test.dart
index 7f0164a..2f32df4 100644
--- a/sdk/lib/_internal/pub/test/lish/upload_form_url_is_not_a_string_test.dart
+++ b/sdk/lib/_internal/pub/test/lish/upload_form_url_is_not_a_string_test.dart
@@ -31,8 +31,8 @@
     };
 
     handleUploadForm(server, body);
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals(JSON.encode(body))));
+    pub.stderr.expect('Invalid server response:');
+    pub.stderr.expect(JSON.encode(body));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/oauth2/utils.dart b/sdk/lib/_internal/pub/test/oauth2/utils.dart
index 27280b0..5144dad 100644
--- a/sdk/lib/_internal/pub/test/oauth2/utils.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/utils.dart
@@ -17,22 +17,24 @@
 
 void authorizePub(ScheduledProcess pub, ScheduledServer server,
     [String accessToken="access token"]) {
-  expect(pub.nextLine(), completion(equals('Pub needs your authorization to '
-      'upload packages on your behalf.')));
+  pub.stdout.expect('Pub needs your authorization to upload packages on your '
+      'behalf.');
 
-  expect(pub.nextLine().then((line) {
-    var match = new RegExp(r'[?&]redirect_uri=([0-9a-zA-Z.%+-]+)[$&]')
-        .firstMatch(line);
-    expect(match, isNotNull);
+  schedule(() {
+    return pub.stdout.next().then((line) {
+      var match = new RegExp(r'[?&]redirect_uri=([0-9a-zA-Z.%+-]+)[$&]')
+          .firstMatch(line);
+      expect(match, isNotNull);
 
-    var redirectUrl = Uri.parse(Uri.decodeComponent(match.group(1)));
-    redirectUrl = addQueryParameters(redirectUrl, {'code': 'access code'});
-    return (new http.Request('GET', redirectUrl)..followRedirects = false)
-      .send();
-  }).then((response) {
-    expect(response.headers['location'],
-        equals('http://pub.dartlang.org/authorized'));
-  }), completes);
+      var redirectUrl = Uri.parse(Uri.decodeComponent(match.group(1)));
+      redirectUrl = addQueryParameters(redirectUrl, {'code': 'access code'});
+      return (new http.Request('GET', redirectUrl)..followRedirects = false)
+        .send();
+    }).then((response) {
+      expect(response.headers['location'],
+          equals('http://pub.dartlang.org/authorized'));
+    });
+  });
 
   handleAccessTokenRequest(server, accessToken);
 }
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
index 8c78a34..d4a81d4 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
@@ -41,7 +41,7 @@
       });
     });
 
-    expect(pub.nextLine(), completion(matches(r'Uploading\.\.\.+')));
+    pub.stdout.expect(startsWith('Uploading...'));
     authorizePub(pub, server, 'new access token');
 
     server.handle('GET', '/api/packages/versions/new', (request) {
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
index 496e42c..d35b87f 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
@@ -23,8 +23,8 @@
     var pub = startPublish(server);
     confirmPublish(pub);
 
-    expect(pub.nextErrLine(), completion(equals("Pub's authorization to upload "
-          "packages has expired and can't be automatically refreshed.")));
+    pub.stderr.expect("Pub's authorization to upload packages has expired and "
+        "can't be automatically refreshed.");
     authorizePub(pub, server, "new access token");
 
     server.handle('GET', '/api/packages/versions/new', (request) {
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
index 8f9fd0d..8f092d1 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
@@ -32,12 +32,8 @@
       response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('OAuth2 authorization failed '
-        '(your token sucks).')));
-    // TODO(rnystrom): The confirm line is run together with this one because
-    // in normal usage, the user will have entered a newline on stdin which
-    // gets echoed to the terminal. Do something better here?
-    expect(pub.nextLine(), completion(equals('Uploading...')));
+    pub.stderr.expect('OAuth2 authorization failed (your token sucks).');
+    pub.stdout.expect('Uploading...');
     pub.kill();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/pub_test.dart b/sdk/lib/_internal/pub/test/pub_test.dart
index cc41e47..3fc4c13 100644
--- a/sdk/lib/_internal/pub/test/pub_test.dart
+++ b/sdk/lib/_internal/pub/test/pub_test.dart
@@ -209,6 +209,28 @@
             ''');
     });
 
+    integration('shows non-truncated help', () {
+      schedulePub(args: ['help', 'serve'],
+          output: '''
+            Run a local web development server.
+
+            By default, this serves "web/" and "test/", but an explicit list of 
+            directories to serve can be provided as well.
+
+            Usage: pub serve [directories...]
+            -h, --help               Print usage information for this command.
+                --port               The base port to listen on.
+                                     (defaults to "8080")
+
+                --[no-]dart2js       Compile Dart to JavaScript.
+                                     (defaults to on)
+
+                --[no-]force-poll    Force the use of a polling filesystem watcher.
+                --mode               Mode to run transformers in.
+                                     (defaults to "debug")
+            ''');
+    });
+
     integration('shows help for a subcommand', () {
       schedulePub(args: ['help', 'cache', 'list'],
           output: '''
diff --git a/sdk/lib/_internal/pub/test/pub_uploader_test.dart b/sdk/lib/_internal/pub/test/pub_uploader_test.dart
index 7f0bde9..7898a63 100644
--- a/sdk/lib/_internal/pub/test/pub_uploader_test.dart
+++ b/sdk/lib/_internal/pub/test/pub_uploader_test.dart
@@ -73,7 +73,7 @@
       }), completes);
     });
 
-    expect(pub.nextLine(), completion(equals('Good job!')));
+    pub.stdout.expect('Good job!');
     pub.shouldExit(exit_codes.SUCCESS);
   });
 
@@ -91,7 +91,7 @@
       request.response.close();
     });
 
-    expect(pub.nextLine(), completion(equals('Good job!')));
+    pub.stdout.expect('Good job!');
     pub.shouldExit(exit_codes.SUCCESS);
   });
 
@@ -111,7 +111,7 @@
       request.response.close();
     });
 
-    expect(pub.nextLine(), completion(equals('Good job!')));
+    pub.stdout.expect('Good job!');
     pub.shouldExit(exit_codes.SUCCESS);
   });
 
@@ -130,7 +130,7 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Bad job!')));
+    pub.stderr.expect('Bad job!');
     pub.shouldExit(1);
   });
 
@@ -150,7 +150,7 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Bad job!')));
+    pub.stderr.expect('Bad job!');
     pub.shouldExit(1);
   });
 
@@ -164,8 +164,9 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals('{not json')));
+    pub.stderr.expect(emitsLines(
+        'Invalid server response:\n'
+        '{not json'));
     pub.shouldExit(1);
   });
 
@@ -179,8 +180,9 @@
       request.response.close();
     });
 
-    expect(pub.nextErrLine(), completion(equals('Invalid server response:')));
-    expect(pub.nextErrLine(), completion(equals('{not json')));
+    pub.stderr.expect(emitsLines(
+        'Invalid server response:\n'
+        '{not json'));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/pubspec_test.dart b/sdk/lib/_internal/pub/test/pubspec_test.dart
index 70eba93..f451f1f 100644
--- a/sdk/lib/_internal/pub/test/pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/pubspec_test.dart
@@ -32,9 +32,17 @@
     var throwsPubspecException =
       throwsA(new isInstanceOf<PubspecException>('PubspecException'));
 
-    expectPubspecException(String contents, fn(Pubspec pubspec)) {
+    expectPubspecException(String contents, fn(Pubspec pubspec),
+        [String expectedContains]) {
+      var expectation = throwsPubspecException;
+      if (expectedContains != null) {
+        expectation = throwsA(allOf(
+            new isInstanceOf<PubspecException>('PubspecException'),
+            predicate((error) => error.message.contains(expectedContains))));
+      }
+
       var pubspec = new Pubspec.parse(contents, sources);
-      expect(() => fn(pubspec), throwsPubspecException);
+      expect(() => fn(pubspec), expectation);
     }
 
     test("doesn't eagerly throw an error for an invalid field", () {
@@ -215,28 +223,88 @@
           (pubspec) => pubspec.version);
     });
 
+    test("throws if transformers isn't a list", () {
+      expectPubspecException('transformers: "not list"',
+          (pubspec) => pubspec.transformers,
+          '"transformers" field must be a list');
+    });
+
     test("throws if a transformer isn't a string or map", () {
-      expectPubspecException('transformers: 12',
-          (pubspec) => pubspec.transformers);
       expectPubspecException('transformers: [12]',
-          (pubspec) => pubspec.transformers);
+          (pubspec) => pubspec.transformers,
+          '"transformers" field must be a string or map');
     });
 
     test("throws if a transformer's configuration isn't a map", () {
-      expectPubspecException('transformers: {pkg: 12}',
-          (pubspec) => pubspec.transformers);
+      expectPubspecException('transformers: [{pkg: 12}]',
+          (pubspec) => pubspec.transformers,
+          '"transformers.pkg" field must be a map');
     });
 
     test("throws if a transformer's configuration contains a top-level key "
         "beginning with a dollar sign", () {
-      expectPubspecException('transformers: {pkg: {\$key: value}}',
-          (pubspec) => pubspec.transformers);
+      expectPubspecException('''
+name: pkg
+transformers: [{pkg: {\$key: "value"}}]''',
+          (pubspec) => pubspec.transformers,
+          '"transformers.pkg" field cannot contain reserved field "\$key"');
     });
 
     test("doesn't throw if a transformer's configuration contains a "
         "non-top-level key beginning with a dollar sign", () {
-      expectPubspecException('transformers: {pkg: {\$key: value}}',
-          (pubspec) => pubspec.transformers);
+      var pubspec = new Pubspec.parse('''
+name: pkg
+transformers:
+- pkg: {outer: {\$inner: value}}
+''', sources);
+
+      var pkg = pubspec.transformers[0].single;
+      expect(pkg.configuration["outer"]["\$inner"], equals("value"));
+    });
+
+    test("throws if a transformer is not from a dependency", () {
+      expectPubspecException('''
+name: pkg
+transformers: [foo]
+''',
+          (pubspec) => pubspec.transformers,
+          '"transformers.foo" refers to a package that\'s not a dependency.');
+    });
+
+    test("allows a transformer from a normal dependency", () {
+      var pubspec = new Pubspec.parse('''
+name: pkg
+dependencies:
+  foo:
+    mock: ok
+transformers:
+- foo''', sources);
+
+      expect(pubspec.transformers[0].single.package, equals("foo"));
+    });
+
+    test("allows a transformer from a dev dependency", () {
+      var pubspec = new Pubspec.parse('''
+name: pkg
+dev_dependencies:
+  foo:
+    mock: ok
+transformers:
+- foo''', sources);
+
+      expect(pubspec.transformers[0].single.package, equals("foo"));
+    });
+
+    test("allows a transformer from a dependency override", () {
+      var pubspec = new Pubspec.parse('''
+name: pkg
+dependency_overrides:
+  foo:
+    mock: ok
+transformers:
+- foo''', sources);
+
+      expect(pubspec.transformers[0].single.package, equals("foo"));
     });
 
     test("allows comment-only files", () {
diff --git a/sdk/lib/_internal/pub/test/real_version_test.dart b/sdk/lib/_internal/pub/test/real_version_test.dart
index 75f1a22..9713808 100644
--- a/sdk/lib/_internal/pub/test/real_version_test.dart
+++ b/sdk/lib/_internal/pub/test/real_version_test.dart
@@ -33,7 +33,7 @@
         Platform.operatingSystem == "windows" ? "pub.bat" : "pub");
 
     var pub = new ScheduledProcess.start(pubPath, ['version']);
-    expect(pub.nextLine(), completion(startsWith("Pub")));
+    pub.stdout.expect(startsWith("Pub"));
     pub.shouldExit(exit_codes.SUCCESS);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/serve/gets_first_if_dependency_is_not_installed_test.dart b/sdk/lib/_internal/pub/test/serve/gets_first_if_dependency_is_not_installed_test.dart
index 8926faf..eac41fe 100644
--- a/sdk/lib/_internal/pub/test/serve/gets_first_if_dependency_is_not_installed_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/gets_first_if_dependency_is_not_installed_test.dart
@@ -25,7 +25,7 @@
     // Delete the system cache so it isn't installed any more.
     schedule(() => deleteEntry(path.join(sandboxDir, cachePath)));
 
-    pubServe(shouldGetFirst: true, numDownloads: 1);
+    pubServe(shouldGetFirst: true);
     requestShouldSucceed("packages/foo/foo.dart", 'main() => "foo 1.2.3";');
     endPubServe();
   });
diff --git a/sdk/lib/_internal/pub/test/serve/gets_first_if_transitive_dependency_is_not_installed_test.dart b/sdk/lib/_internal/pub/test/serve/gets_first_if_transitive_dependency_is_not_installed_test.dart
index 963eb09..76f9039 100644
--- a/sdk/lib/_internal/pub/test/serve/gets_first_if_transitive_dependency_is_not_installed_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/gets_first_if_transitive_dependency_is_not_installed_test.dart
@@ -34,7 +34,7 @@
     // Delete the system cache so bar isn't installed any more.
     schedule(() => deleteEntry(path.join(sandboxDir, cachePath)));
 
-    pubServe(shouldGetFirst: true, numDownloads: 1);
+    pubServe(shouldGetFirst: true);
     requestShouldSucceed("packages/bar/bar.dart", 'main() => "bar 1.2.3";');
     endPubServe();
   });
diff --git a/sdk/lib/_internal/pub/test/serve/roots/serves_urls_from_custom_roots_test.dart b/sdk/lib/_internal/pub/test/serve/roots/serves_urls_from_custom_roots_test.dart
new file mode 100644
index 0000000..221b53a
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/roots/serves_urls_from_custom_roots_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:path/path.dart' as p;
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../utils.dart';
+
+main() {
+  initConfig();
+  integration("serves URLs from custom roots", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("example", [
+        d.dir("foo", [d.file("bar", "contents")])
+      ]),
+      d.dir("dir", [d.file("baz", "contents")]),
+      d.dir("web", [d.file("bang", "contents")])
+    ]).create();
+
+    pubServe(args: [p.join("example", "foo"), "dir"]);
+    requestShouldSucceed("bar", "contents", root: p.join("example", "foo"));
+    requestShouldSucceed("baz", "contents", root: "dir");
+    requestShould404("bang", root: "dir");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/roots/serves_web_and_test_dirs_by_default_test.dart b/sdk/lib/_internal/pub/test/serve/roots/serves_web_and_test_dirs_by_default_test.dart
new file mode 100644
index 0000000..c53e8ba
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/roots/serves_web_and_test_dirs_by_default_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../utils.dart';
+
+main() {
+  initConfig();
+  integration("serves web/ and test/ dirs by default", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [d.file("foo", "contents")]),
+      d.dir("test", [d.file("bar", "contents")]),
+      d.dir("example", [d.file("baz", "contents")])
+    ]).create();
+
+    pubServe();
+    requestShouldSucceed("foo", "contents", root: "web");
+    requestShouldSucceed("bar", "contents", root: "test");
+    requestShould404("baz", root: "web");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_by_default_if_web_and_test_dont_exist_test.dart b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_by_default_if_web_and_test_dont_exist_test.dart
new file mode 100644
index 0000000..11de9cd
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_by_default_if_web_and_test_dont_exist_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../utils.dart';
+
+main() {
+  initConfig();
+  integration("throws an error by default if web and test don't exist", () {
+    d.dir(appPath, [
+      d.appPubspec()
+    ]).create();
+
+    var server = startPubServe(createWebDir: false);
+    server.stderr.expect(emitsLines(
+        'Your package must have "web" and/or "test" directories to serve,\n'
+        'or you must pass in directories to serve explicitly.'));
+    server.shouldExit(exit_codes.USAGE);
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_are_outside_package_test.dart b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_are_outside_package_test.dart
new file mode 100644
index 0000000..37dd269
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_are_outside_package_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../utils.dart';
+
+main() {
+  initConfig();
+  integration("throws an error if custom roots are outside the package", () {
+    d.dir(appPath, [
+      d.appPubspec()
+    ]).create();
+
+    var server = startPubServe(args: [".."]);
+    server.stderr.expect('Directory ".." isn\'t in this package.');
+    server.shouldExit(exit_codes.USAGE);
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_dont_exist_test.dart b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_dont_exist_test.dart
new file mode 100644
index 0000000..c2275bb
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/roots/throws_an_error_if_custom_roots_dont_exist_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../../lib/src/exit_codes.dart' as exit_codes;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../utils.dart';
+
+main() {
+  initConfig();
+  integration("throws an error if custom roots don't exist", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("baz")
+    ]).create();
+
+    var server = startPubServe(args: ["foo", "bar", "baz"]);
+    server.stderr.expect('Directories "bar" and "foo" don\'t exist.');
+    server.shouldExit(exit_codes.USAGE);
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/serve_from_app_asset_test.dart b/sdk/lib/_internal/pub/test/serve/serve_from_app_asset_test.dart
index 63d324b..c4913d5 100644
--- a/sdk/lib/_internal/pub/test/serve/serve_from_app_asset_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/serve_from_app_asset_test.dart
@@ -25,9 +25,9 @@
     requestShouldSucceed("assets/myapp/foo.txt", "foo");
     requestShouldSucceed("assets/myapp/sub/bar.txt", "bar");
 
-    // "assets" can be in a subpath of the URL:
-    requestShouldSucceed("foo/assets/myapp/foo.txt", "foo");
-    requestShouldSucceed("a/b/assets/myapp/sub/bar.txt", "bar");
+    // "assets" cannot be in a subpath of the URL:
+    requestShould404("foo/assets/myapp/foo.txt");
+    requestShould404("a/b/assets/myapp/sub/bar.txt");
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/serve/serve_from_dependency_asset_test.dart b/sdk/lib/_internal/pub/test/serve/serve_from_dependency_asset_test.dart
index 08c76e0..f026d8a 100644
--- a/sdk/lib/_internal/pub/test/serve/serve_from_dependency_asset_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/serve_from_dependency_asset_test.dart
@@ -31,9 +31,9 @@
     requestShouldSucceed("assets/foo/foo.txt", "foo");
     requestShouldSucceed("assets/foo/sub/bar.txt", "bar");
 
-    // "assets" can be in a subpath of the URL:
-    requestShouldSucceed("foo/assets/foo/foo.txt", "foo");
-    requestShouldSucceed("a/b/assets/foo/sub/bar.txt", "bar");
+    // "assets" cannot be in a subpath of the URL:
+    requestShould404("foo/assets/foo/foo.txt");
+    requestShould404("a/b/assets/foo/sub/bar.txt");
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/serve/serves_index_html_for_directories_test.dart b/sdk/lib/_internal/pub/test/serve/serves_index_html_for_directories_test.dart
new file mode 100644
index 0000000..10f8afc
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/serves_index_html_for_directories_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'utils.dart';
+
+main() {
+  initConfig();
+  integration("serves index.html for directories", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [
+        d.file("index.html", "<body>super"),
+        d.dir("sub", [
+          d.file("index.html", "<body>sub")
+        ])
+      ])
+    ]).create();
+
+    pubServe();
+    requestShouldSucceed("", "<body>super");
+    requestShouldSucceed("sub/", "<body>sub");
+    requestShouldRedirect("sub", "/sub/");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/utils.dart b/sdk/lib/_internal/pub/test/serve/utils.dart
index 6ae1e1f..0f04f3f 100644
--- a/sdk/lib/_internal/pub/test/serve/utils.dart
+++ b/sdk/lib/_internal/pub/test/serve/utils.dart
@@ -9,16 +9,20 @@
 import 'dart:io';
 
 import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as p;
 import 'package:scheduled_test/scheduled_process.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
+import '../descriptor.dart' as d;
 import '../test_pub.dart';
 
 /// The pub process running "pub serve".
 ScheduledProcess _pubServer;
 
-/// The ephemeral port assigned to the running server.
-int _port;
+/// The ephemeral ports assigned to the running servers, associated with the
+/// directories they're serving.
+final _ports = new Map<String, int>();
 
 /// The web socket connection to the running pub process, or `null` if no
 /// connection has been made.
@@ -98,7 +102,8 @@
 /// so may be used to test for errors in the initialization process.
 ///
 /// Returns the `pub serve` process.
-ScheduledProcess startPubServe([Iterable<String> args]) {
+ScheduledProcess startPubServe({Iterable<String> args,
+    bool createWebDir: true}) {
   // Use port 0 to get an ephemeral port.
   var pubArgs = ["serve", "--port=0", "--hostname=127.0.0.1", "--force-poll"];
 
@@ -108,22 +113,26 @@
   // timeout to cope with that.
   currentSchedule.timeout *= 1.5;
 
+  if (createWebDir) d.dir(appPath, [d.dir("web")]).create();
   return startPub(args: pubArgs);
 }
 
 /// Schedules starting the "pub serve" process and records its port number for
 /// future requests.
 ///
-/// If [shouldGetFirst] is `true`, validates that pub get is run first. In that
-/// case, you can also pass [numDownloads] to specify how many packages should
-/// be downloaded during the get.
+/// If [shouldGetFirst] is `true`, validates that pub get is run first.
+///
+/// If [createWebDir] is `true`, creates a `web/` directory if one doesn't exist
+/// so pub doesn't complain about having nothing to serve.
 ///
 /// Returns the `pub serve` process.
-ScheduledProcess pubServe({bool shouldGetFirst: false,
-    Iterable<String> args, int numDownloads: 0}) {
-  _pubServer = startPubServe(args);
+ScheduledProcess pubServe({bool shouldGetFirst: false, bool createWebDir: true,
+    Iterable<String> args}) {
+  _pubServer = startPubServe(args: args, createWebDir: createWebDir);
 
   currentSchedule.onComplete.schedule(() {
+    _ports.clear();
+
     if (_webSocket != null) {
       _webSocket.close();
       _webSocket = null;
@@ -132,33 +141,28 @@
   });
 
   if (shouldGetFirst) {
-    expect(_pubServer.nextLine(),
-        completion(anyOf(
-             startsWith("Your pubspec has changed"),
-             startsWith("You don't have a lockfile"),
-             startsWith("You are missing some dependencies"))));
-    expect(_pubServer.nextLine(),
-        completion(startsWith("Resolving dependencies...")));
-
-    for (var i = 0; i < numDownloads; i++) {
-      expect(_pubServer.nextLine(),
-          completion(startsWith("Downloading")));
-    }
-
-    expect(_pubServer.nextLine(),
-        completion(equals("Got dependencies!")));
+    _pubServer.stdout.expect(consumeThrough("Got dependencies!"));
   }
 
-  expect(_pubServer.nextLine().then(_parsePort), completes);
+  // The server should emit one or more ports.
+  _pubServer.stdout.expect(
+      consumeWhile(predicate(_parsePort, 'emits server url')));
+  schedule(() => expect(_ports, isNot(isEmpty)));
+
   return _pubServer;
 }
 
+/// The regular expression for parsing pub's output line describing the URL for
+/// the server.
+final _parsePortRegExp = new RegExp(r"([^ ]+) +on http://127\.0\.0\.1:(\d+)");
+
 /// Parses the port number from the "Serving blah on 127.0.0.1:1234" line
 /// printed by pub serve.
-void _parsePort(String line) {
-  var match = new RegExp(r"127\.0\.0\.1:(\d+)").firstMatch(line);
-  assert(match != null);
-  _port = int.parse(match[1]);
+bool _parsePort(String line) {
+  var match = _parsePortRegExp.firstMatch(line);
+  if (match == null) return false;
+  _ports[match[1]] = int.parse(match[2]);
+  return true;
 }
 
 void endPubServe() {
@@ -169,10 +173,11 @@
 /// verifies that it responds with a body that matches [expectation].
 ///
 /// [expectation] may either be a [Matcher] or a string to match an exact body.
+/// [root] indicates which server should be accessed, and defaults to "web".
 /// [headers] may be either a [Matcher] or a map to match an exact headers map.
-void requestShouldSucceed(String urlPath, expectation, {headers}) {
+void requestShouldSucceed(String urlPath, expectation, {String root, headers}) {
   schedule(() {
-    return http.get("http://127.0.0.1:$_port/$urlPath").then((response) {
+    return http.get("${_serverUrl(root)}/$urlPath").then((response) {
       if (expectation != null) expect(response.body, expectation);
       if (headers != null) expect(response.headers, headers);
     });
@@ -181,19 +186,42 @@
 
 /// Schedules an HTTP request to the running pub server with [urlPath] and
 /// verifies that it responds with a 404.
-void requestShould404(String urlPath) {
+///
+/// [root] indicates which server should be accessed, and defaults to "web".
+void requestShould404(String urlPath, {String root}) {
   schedule(() {
-    return http.get("http://127.0.0.1:$_port/$urlPath").then((response) {
+    return http.get("${_serverUrl(root)}/$urlPath").then((response) {
       expect(response.statusCode, equals(404));
     });
   }, "request $urlPath");
 }
 
+/// Schedules an HTTP request to the running pub server with [urlPath] and
+/// verifies that it responds with a redirect to the given [redirectTarget].
+///
+/// [redirectTarget] may be either a [Matcher] or a string to match an exact
+/// URL. [root] indicates which server should be accessed, and defaults to
+/// "web".
+void requestShouldRedirect(String urlPath, redirectTarget, {String root}) {
+  schedule(() {
+    var request = new http.Request("GET",
+        Uri.parse("${_serverUrl(root)}/$urlPath"));
+    request.followRedirects = false;
+    return request.send().then((response) {
+      expect(response.statusCode ~/ 100, equals(3));
+
+      expect(response.headers, containsPair('location', redirectTarget));
+    });
+  }, "request $urlPath");
+}
+
 /// Schedules an HTTP POST to the running pub server with [urlPath] and verifies
 /// that it responds with a 405.
-void postShould405(String urlPath) {
+///
+/// [root] indicates which server should be accessed, and defaults to "web".
+void postShould405(String urlPath, {String root}) {
   schedule(() {
-    return http.post("http://127.0.0.1:$_port/$urlPath").then((response) {
+    return http.post("${_serverUrl(root)}/$urlPath").then((response) {
       expect(response.statusCode, equals(405));
     });
   }, "request $urlPath");
@@ -204,18 +232,8 @@
 ///
 /// The schedule will not proceed until the output is found. If not found, it
 /// will eventually time out.
-void waitForBuildSuccess() {
-  nextLine() {
-    return _pubServer.nextLine().then((line) {
-      if (line.contains("successfully")) return null;
-
-      // This line wasn't it, so ignore it and keep trying.
-      return nextLine();
-    });
-  }
-
-  schedule(nextLine);
-}
+void waitForBuildSuccess() =>
+  _pubServer.stdout.expect(consumeThrough(contains("successfully")));
 
 /// Schedules opening a web socket connection to the currently running pub
 /// serve.
@@ -224,10 +242,13 @@
   if (_webSocket != null) return new Future.value();
 
   // Server should already be running.
-  assert(_pubServer != null);
-  assert(_port != null);
+  expect(_pubServer, isNotNull);
+  expect(_ports, isNot(isEmpty));
 
-  return WebSocket.connect("ws://127.0.0.1:$_port").then((socket) {
+  // TODO(nweiz): once we have a separate port for a web interface into the
+  // server, use that port for the websocket interface.
+  var port = _ports.values.first;
+  return WebSocket.connect("ws://127.0.0.1:$port").then((socket) {
     _webSocket = socket;
     // TODO(rnystrom): Works around #13913.
     _webSocketBroadcastStream = _webSocket.asBroadcastStream();
@@ -248,4 +269,11 @@
       expect(JSON.decode(value), expectation);
     });
   }), "send $request to web socket and expect reply that $expectation");
+}
+
+/// Returns the URL for the server serving from [root].
+String _serverUrl([String root]) {
+  if (root == null) root = 'web';
+  expect(_ports, contains(root));
+  return "http://127.0.0.1:${_ports[root]}";
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart b/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
index e77af93..05f9933 100644
--- a/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
@@ -5,6 +5,7 @@
 library pub_tests;
 
 import 'package:path/path.dart' as path;
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../../lib/src/utils.dart';
@@ -16,7 +17,7 @@
   // Escape backslashes since they are metacharacters in a regex.
   assetsPath = quoteRegExp(assetsPath);
   return new RegExp(
-      '^Warning: Pub reserves paths containing "assets" for using assets from '
+      r'^Warning: Pub reserves paths containing "assets" for using assets from '
       'packages\\. Please rename the path "$assetsPath"\\.\$');
 }
 
@@ -34,11 +35,10 @@
 
     var pub = pubServe();
     waitForBuildSuccess();
-    endPubServe();
 
     var assetsPath = path.join('web', 'assets');
-    expect(pub.remainingStderr(), completion(
-        matches(getWarningRegExp(assetsPath))));
+    pub.stderr.expect(consumeThrough(matches(getWarningRegExp(assetsPath))));
+    endPubServe();
   });
 
   integration('warns user about assets dir nested anywhere in "web"', () {
@@ -54,11 +54,10 @@
 
     var pub = pubServe();
     waitForBuildSuccess();
-    endPubServe();
 
     var assetsPath = path.join('web', 'foo', 'assets');
-    expect(pub.remainingStderr(), completion(
-        matches(getWarningRegExp(assetsPath))));
+    pub.stderr.expect(consumeThrough(matches(getWarningRegExp(assetsPath))));
+    endPubServe();
   });
 
   integration('warns user about assets file in the root of "web"', () {
@@ -72,11 +71,10 @@
 
     var pub = pubServe();
     waitForBuildSuccess();
-    endPubServe();
 
     var assetsPath = path.join('web', 'assets');
-    expect(pub.remainingStderr(), completion(
-        matches(getWarningRegExp(assetsPath))));
+    pub.stderr.expect(consumeThrough(matches(getWarningRegExp(assetsPath))));
+    endPubServe();
   });
 
   integration('warns user about assets file nested anywhere in "web"', () {
@@ -92,11 +90,10 @@
 
     var pub = pubServe();
     waitForBuildSuccess();
-    endPubServe();
 
     var assetsPath = path.join('web', 'foo', 'assets');
-    expect(pub.remainingStderr(), completion(
-        matches(getWarningRegExp(assetsPath))));
+    pub.stderr.expect(consumeThrough(matches(getWarningRegExp(assetsPath))));
+    endPubServe();
   });
 
   integration('does not warn if no assets dir or file anywhere in "web"', () {
@@ -112,7 +109,7 @@
     waitForBuildSuccess();
     endPubServe();
 
-    expect(pub.remainingStderr(), completion(
-        matches(r'^(?!Warning: Pub reserves paths containing "assets").*$')));
+    pub.stderr.expect(never(startsWith('Warning: Pub reserves paths containing '
+        '"assets"')));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index bd8fc11..0dcbb49 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -17,6 +17,7 @@
 import 'package:path/path.dart' as path;
 import 'package:scheduled_test/scheduled_process.dart';
 import 'package:scheduled_test/scheduled_server.dart';
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:unittest/compact_vm_config.dart';
 import 'package:yaml/yaml.dart';
@@ -394,19 +395,20 @@
   var stderr;
 
   expect(Future.wait([
-    pub.remainingStdout(),
-    pub.remainingStderr()
+    pub.stdoutStream().toList(),
+    pub.stderrStream().toList()
   ]).then((results) {
-    stderr = results[1];
+    var stdout = results[0].join("\n");
+    stderr = results[1].join("\n");
 
     if (outputJson == null) {
-      _validateOutput(failures, 'stdout', output, results[0]);
+      _validateOutput(failures, 'stdout', output, stdout);
       return null;
     }
 
     // Allow the expected JSON to contain futures.
     return awaitObject(outputJson).then((resolved) {
-      _validateOutputJson(failures, 'stdout', resolved, results[0]);
+      _validateOutputJson(failures, 'stdout', resolved, stdout);
     });
   }).then((_) {
     _validateOutput(failures, 'stderr', error, stderr);
@@ -434,16 +436,14 @@
 void confirmPublish(ScheduledProcess pub) {
   // TODO(rnystrom): This is overly specific and inflexible regarding different
   // test packages. Should validate this a little more loosely.
-  expect(pub.nextLine(), completion(startsWith(
-      'Publishing test_pkg 1.0.0 to ')));
-  expect(pub.nextLine(), completion(equals("|-- LICENSE")));
-  expect(pub.nextLine(), completion(equals("|-- lib")));
-  expect(pub.nextLine(), completion(equals("|   '-- test_pkg.dart")));
-  expect(pub.nextLine(), completion(equals("'-- pubspec.yaml")));
-  expect(pub.nextLine(), completion(equals("")));
-  expect(pub.nextLine(), completion(equals('Looks great! Are you ready to '
-      'upload your package (y/n)?')));
-
+  pub.stdout.expect(startsWith('Publishing test_pkg 1.0.0 to '));
+  pub.stdout.expect(emitsLines(
+      "|-- LICENSE\n"
+      "|-- lib\n"
+      "|   '-- test_pkg.dart\n"
+      "'-- pubspec.yaml\n"
+      "\n"
+      "Looks great! Are you ready to upload your package (y/n)?"));
   pub.writeLine("y");
 }
 
@@ -507,8 +507,8 @@
 }
 
 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output
-/// and makes [nextLine], [nextErrLine], [remainingStdout], and
-/// [remainingStderr] work as though pub weren't running in verbose mode.
+/// and makes [stdout] and [stderr] work as though pub weren't running in
+/// verbose mode.
 class PubProcess extends ScheduledProcess {
   Stream<Pair<log.Level, String>> _log;
   Stream<String> _stdout;
@@ -574,7 +574,8 @@
   Stream<String> stderrStream() {
     if (_stderr == null) {
       _stderr = _logStream().expand((entry) {
-        if (entry.first != log.Level.ERROR && entry.first != log.Level.WARNING) {
+        if (entry.first != log.Level.ERROR &&
+            entry.first != log.Level.WARNING) {
           return [];
         }
         return [entry.last];
@@ -866,3 +867,6 @@
     description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
   }
 }
+
+/// A [StreamMatcher] that matches multiple lines of output.
+StreamMatcher emitsLines(String output) => inOrder(output.split("\n"));
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_compile_until_its_output_is_requested_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_compile_until_its_output_is_requested_test.dart
index e71c925..e25a368 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_compile_until_its_output_is_requested_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_compile_until_its_output_is_requested_test.dart
@@ -26,13 +26,14 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var server = pubServe();
-    expect(server.nextLine(),
-        completion(equals("Build completed successfully")));
+    server.stdout.expect("Build completed successfully");
 
     // Once we request the output, it should start compiling and fail.
     requestShould404("syntax-error.dart.js");
-    expect(server.nextLine(),
-        completion(equals("Build completed with 1 errors.")));
+    server.stdout.expect(emitsLines(
+        "[Info from Dart2JS]:\n"
+        "Compiling myapp|web/syntax-error.dart...\n"
+        "Build completed with 1 errors."));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart
index 66ee703..d8e56aa 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart
@@ -34,11 +34,11 @@
     var server = pubServe();
     // Make a request first to trigger compilation.
     requestShould404("main.dart.js");
-    expect(server.nextErrLine(), completion(equals('Build error:')));
-    expect(server.nextErrLine(), completion(equals(
+    server.stderr.expect(emitsLines(
+        'Build error:\n'
         'Transform Dart2JS on myapp|web/main.dart threw error: '
             'FormatException: Invalid value for \$dart2js.commandLineOptions: '
-            '"foo" (expected list of strings).')));
+            '"foo" (expected list of strings).'));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart
index a9bb942..586c290 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart
@@ -34,11 +34,11 @@
     var server = pubServe();
     // Make a request first to trigger compilation.
     requestShould404("main.dart.js");
-    expect(server.nextErrLine(), completion(equals('Build error:')));
-    expect(server.nextErrLine(), completion(equals(
+    server.stderr.expect(emitsLines(
+        'Build error:\n'
         'Transform Dart2JS on myapp|web/main.dart threw error: '
             'FormatException: Invalid value for \$dart2js.environment: "foo" '
-            '(expected map from strings to strings).')));
+            '(expected map from strings to strings).'));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart
index b683978..a29489e 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart
@@ -31,8 +31,7 @@
     // TODO(nweiz): This should provide more context about how the option got
     // passed to dart2js. See issue 16008.
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(
-        equals('Unrecognized dart2js option "invalidOption".')));
+    pub.stderr.expect('Unrecognized dart2js option "invalidOption".');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart
index 4560fcb..c9bd7bc 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart
@@ -33,11 +33,11 @@
 
     var server = pubServe();
     requestShould404("main.dart.js");
-    expect(server.nextErrLine(), completion(equals('Build error:')));
-    expect(server.nextErrLine(), completion(equals(
+    server.stderr.expect(emitsLines(
+        'Build error:\n'
         'Transform Dart2JS on myapp|web/main.dart threw error: '
             'FormatException: Invalid value for \$dart2js.checked: "foo" '
-            '(expected true or false).')));
+            '(expected true or false).'));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart
index ffdda13..9bac1fb 100644
--- a/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart
@@ -27,6 +27,7 @@
             "analyzeAll": true,
             "suppressWarnings": true,
             "suppressHints": true,
+            "suppressPackageWarnings": false,
             "terse": true
           }
         }]
diff --git a/sdk/lib/_internal/pub/test/transformer/detects_a_transformer_cycle_test.dart b/sdk/lib/_internal/pub/test/transformer/detects_a_transformer_cycle_test.dart
index dd98149..5b89cf8 100644
--- a/sdk/lib/_internal/pub/test/transformer/detects_a_transformer_cycle_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/detects_a_transformer_cycle_test.dart
@@ -40,9 +40,9 @@
 
     var process = startPubServe();
     process.shouldExit(1);
-    expect(process.remainingStderr(), completion(equals(
+    process.stderr.expect(emitsLines(
         "Transformer cycle detected:\n"
         "  foo is transformed by myapp/transformer\n"
-        "  myapp is transformed by foo/transformer")));
+        "  myapp is transformed by foo/transformer"));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/detects_an_ordering_dependency_cycle_test.dart b/sdk/lib/_internal/pub/test/transformer/detects_an_ordering_dependency_cycle_test.dart
index b9bf8bc..0a3f056 100644
--- a/sdk/lib/_internal/pub/test/transformer/detects_an_ordering_dependency_cycle_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/detects_an_ordering_dependency_cycle_test.dart
@@ -56,11 +56,11 @@
 
     var process = startPubServe();
     process.shouldExit(1);
-    expect(process.remainingStderr(), completion(equals(
+    process.stderr.expect(emitsLines(
         "Transformer cycle detected:\n"
         "  bar depends on foo\n"
         "  foo is transformed by myapp/transformer\n"
         "  myapp depends on baz\n"
-        "  baz is transformed by bar/transformer")));
+        "  baz is transformed by bar/transformer"));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_file_that_defines_no_transforms_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_file_that_defines_no_transforms_test.dart
index aae47da..c412b5c 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_file_that_defines_no_transforms_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_file_that_defines_no_transforms_test.dart
@@ -4,6 +4,7 @@
 
 library pub_tests;
 
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../descriptor.dart' as d;
@@ -27,11 +28,9 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(startsWith('No transformers were '
-       'defined in ')));
-    expect(pub.nextErrLine(), completion(startsWith('required by myapp.')));
+    pub.stderr.expect(startsWith('No transformers were defined in '));
+    pub.stderr.expect(startsWith('required by myapp.'));
     pub.shouldExit(1);
-    expect(pub.remainingStderr(),
-        completion(isNot(contains('This is an unexpected error'))));
+    pub.stderr.expect(never(contains('This is an unexpected error')));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_non_existent_transform_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_non_existent_transform_test.dart
index f961bae..44dd846 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_non_existent_transform_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_non_existent_transform_test.dart
@@ -21,8 +21,8 @@
     ]).create();
 
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(equals(
-        'Transformer library "package:myapp/transform.dart" not found.')));
+    pub.stderr.expect(
+        'Transformer library "package:myapp/transform.dart" not found.');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
index 8eed7c4..f004b23 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
@@ -27,11 +27,10 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(equals('Error in pubspec for package '
-        '"myapp" loaded from pubspec.yaml:')));
-    expect(pub.nextErrLine(), completion(equals('Invalid transformer '
-       'identifier for "transformers.\$nonexistent": Unsupported built-in '
-       'transformer \$nonexistent.')));
+    pub.stderr.expect(emitsLines(
+        'Error in pubspec for package "myapp" loaded from pubspec.yaml:\n'
+        'Invalid transformer identifier for "transformers.\$nonexistent": '
+            'Unsupported built-in transformer \$nonexistent.'));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_from_a_non_dependency_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_from_a_non_dependency_test.dart
index 04b80e2..276d325 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_from_a_non_dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_from_a_non_dependency_test.dart
@@ -22,9 +22,9 @@
 
     var pub = startPubServe();
     // Ignore the line containing the path to the pubspec.
-    expect(pub.nextErrLine(), completes);
-    expect(pub.nextErrLine(), completion(equals('"transformers.foo" refers to '
-        'a package that\'s not listed in "dependencies".')));
+    pub.stderr.expect(anything);
+    pub.stderr.expect('"transformers.foo" refers to a package that\'s not a '
+        'dependency.');
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_a_syntax_error_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_a_syntax_error_test.dart
index 911ef39..4a617ef 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_a_syntax_error_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_a_syntax_error_test.dart
@@ -4,6 +4,7 @@
 
 library pub_tests;
 
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../descriptor.dart' as d;
@@ -29,9 +30,8 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(startsWith('Error on line')));
+    pub.stderr.expect(startsWith('Error on line'));
     pub.shouldExit(1);
-    expect(pub.remainingStderr(),
-        completion(isNot(contains('This is an unexpected error'))));
+    pub.stderr.expect(never(contains('This is an unexpected error')));
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
index 78632a2..5e68175 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
@@ -28,8 +28,7 @@
 
     createLockFile('myapp', pkg: ['barback']);
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(matches(new RegExp(
-        r"error: line 1 pos 1: library handler failed$"))));
+    pub.stderr.expect(endsWith("error: line 1 pos 1: library handler failed"));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
index 46db4cd..8033f5c 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
@@ -28,8 +28,8 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var pub = startPubServe();
-    expect(pub.nextErrLine(), completion(startsWith('No transformers that '
-        'accept configuration were defined in ')));
+    pub.stderr.expect(startsWith('No transformers that accept configuration '
+        'were defined in '));
     pub.shouldExit(1);
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/transformer/prints_a_transform_error_in_apply_test.dart b/sdk/lib/_internal/pub/test/transformer/prints_a_transform_error_in_apply_test.dart
index ba20fa9..0222067 100644
--- a/sdk/lib/_internal/pub/test/transformer/prints_a_transform_error_in_apply_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/prints_a_transform_error_in_apply_test.dart
@@ -43,10 +43,9 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var server = pubServe();
-    expect(server.nextErrLine(),
-        completion(equals('Build error:')));
-    expect(server.nextErrLine(), completion(equals('Transform Rewrite on '
-        'myapp|web/foo.txt threw error: oh no!')));
+    server.stderr.expect(emitsLines(
+        'Build error:\n'
+        'Transform Rewrite on myapp|web/foo.txt threw error: oh no!'));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/prints_a_transform_interface_error_test.dart b/sdk/lib/_internal/pub/test/transformer/prints_a_transform_interface_error_test.dart
index 07abb4f..bdfa67f 100644
--- a/sdk/lib/_internal/pub/test/transformer/prints_a_transform_interface_error_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/prints_a_transform_interface_error_test.dart
@@ -41,10 +41,10 @@
     createLockFile('myapp', pkg: ['barback']);
 
     var server = pubServe();
-    expect(server.nextErrLine(), completion(equals('Build error:')));
-    expect(server.nextErrLine(), completion(equals("Transform Rewrite on "
-        "myapp|web/foo.txt threw error: Class 'RewriteTransformer' has no "
-        "instance method 'apply'.")));
+    server.stderr.expect(emitsLines(
+        "Build error:\n"
+        "Transform Rewrite on myapp|web/foo.txt threw error: Class "
+            "'RewriteTransformer' has no instance method 'apply'."));
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/validator/dependency_test.dart b/sdk/lib/_internal/pub/test/validator/dependency_test.dart
index 53dfff9..8c53c74 100644
--- a/sdk/lib/_internal/pub/test/validator/dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/validator/dependency_test.dart
@@ -84,7 +84,7 @@
                     "pre-1.0.0", () {
           setUpDependency({'git': 'git://github.com/dart-lang/foo'},
               hostedVersions: ["0.0.1", "0.0.2"]);
-          expectDependencyValidationWarning('  foo: ">=0.0.2 <0.0.3"');
+          expectDependencyValidationWarning('  foo: ">=0.0.2 <0.1.0"');
         });
       });
 
@@ -127,7 +127,7 @@
                     "pre-1.0.0", () {
           setUpDependency({'path': path.join(sandboxDir, 'foo')},
               hostedVersions: ["0.0.1", "0.0.2"]);
-          expectDependencyValidationError('  foo: ">=0.0.2 <0.0.3"');
+          expectDependencyValidationError('  foo: ">=0.0.2 <0.1.0"');
         });
       });
 
@@ -233,9 +233,152 @@
             }))
           ]).create();
 
-          expectDependencyValidationWarning('  foo: ">=0.1.2 <0.1.3"');
+          expectDependencyValidationWarning('  foo: ">=0.1.2 <0.2.0"');
         });
       });
     });
+
+    integration('with a single-version dependency and it should suggest a '
+        'constraint based on the version', () {
+      d.dir(appPath, [
+        d.libPubspec("test_pkg", "1.0.0", deps: {
+          "foo": "1.2.3"
+        })
+      ]).create();
+
+      expectDependencyValidationWarning('  foo: ">=1.2.3 <2.0.0"');
+    });
+
+    group('has a dependency without a lower bound', () {
+      group('and it should not suggest a version', () {
+        integration("if there's no lockfile", () {
+          d.dir(appPath, [
+            d.libPubspec("test_pkg", "1.0.0", deps: {
+              "foo": "<3.0.0"
+            })
+          ]).create();
+
+          expect(schedulePackageValidation(dependency), completion(
+              pairOf(isEmpty, everyElement(isNot(contains("\n  foo:"))))));
+        });
+
+        integration("if the lockfile doesn't have an entry for the "
+            "dependency", () {
+          d.dir(appPath, [
+            d.libPubspec("test_pkg", "1.0.0", deps: {
+              "foo": "<3.0.0"
+            }),
+            d.file("pubspec.lock", JSON.encode({
+              'packages': {
+                'bar': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'bar',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).create();
+
+          expect(schedulePackageValidation(dependency), completion(
+              pairOf(isEmpty, everyElement(isNot(contains("\n  foo:"))))));
+        });
+      });
+
+      group('with a lockfile', () {
+        integration('and it should suggest a constraint based on the locked '
+            'version', () {
+          d.dir(appPath, [
+            d.libPubspec("test_pkg", "1.0.0", deps: {
+              "foo": "<3.0.0"
+            }),
+            d.file("pubspec.lock", JSON.encode({
+              'packages': {
+                'foo': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'foo',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).create();
+
+          expectDependencyValidationWarning('  foo: ">=1.2.3 <3.0.0"');
+        });
+
+        integration('and it should preserve the upper-bound operator', () {
+          d.dir(appPath, [
+            d.libPubspec("test_pkg", "1.0.0", deps: {
+              "foo": "<=3.0.0"
+            }),
+            d.file("pubspec.lock", JSON.encode({
+              'packages': {
+                'foo': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'foo',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).create();
+
+          expectDependencyValidationWarning('  foo: ">=1.2.3 <=3.0.0"');
+        });
+
+        integration('and it should expand the suggested constraint if the '
+            'locked version matches the upper bound', () {
+          d.dir(appPath, [
+            d.libPubspec("test_pkg", "1.0.0", deps: {
+              "foo": "<=1.2.3"
+            }),
+            d.file("pubspec.lock", JSON.encode({
+              'packages': {
+                'foo': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'foo',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).create();
+
+          expectDependencyValidationWarning('  foo: ">=1.2.3 <2.0.0"');
+        });
+      });
+    });
+
+    group('with a dependency without an upper bound', () {
+      integration('and it should suggest a constraint based on the lower bound',
+          () {
+        d.dir(appPath, [
+          d.libPubspec("test_pkg", "1.0.0", deps: {
+            "foo": ">=1.2.3"
+          })
+        ]).create();
+
+        expectDependencyValidationWarning('  foo: ">=1.2.3 <2.0.0"');
+      });
+
+      integration('and it should preserve the lower-bound operator', () {
+        d.dir(appPath, [
+          d.libPubspec("test_pkg", "1.0.0", deps: {
+            "foo": ">1.2.3"
+          })
+        ]).create();
+
+        expectDependencyValidationWarning('  foo: ">1.2.3 <2.0.0"');
+      });
+    });
   });
 }
diff --git a/sdk/lib/_internal/pub/test/version_test.dart b/sdk/lib/_internal/pub/test/version_test.dart
index 0e7452a..8e6a825 100644
--- a/sdk/lib/_internal/pub/test/version_test.dart
+++ b/sdk/lib/_internal/pub/test/version_test.dart
@@ -207,18 +207,21 @@
     group('constructor', () {
       test('takes a min and max', () {
         var range = new VersionRange(min: v123, max: v124);
+        expect(range.isAny, isFalse);
         expect(range.min, equals(v123));
         expect(range.max, equals(v124));
       });
 
       test('allows omitting max', () {
         var range = new VersionRange(min: v123);
+        expect(range.isAny, isFalse);
         expect(range.min, equals(v123));
         expect(range.max, isNull);
       });
 
       test('allows omitting min and max', () {
         var range = new VersionRange();
+        expect(range.isAny, isTrue);
         expect(range.min, isNull);
         expect(range.max, isNull);
       });
@@ -367,6 +370,7 @@
 
     test('empty', () {
       expect(VersionConstraint.empty.isEmpty, isTrue);
+      expect(VersionConstraint.empty.isAny, isFalse);
       expect(VersionConstraint.empty, doesNotAllow([
         new Version.parse('0.0.0-blah'),
         new Version.parse('1.2.3'),
diff --git a/sdk/lib/async/deferred_load.dart b/sdk/lib/async/deferred_load.dart
index 35ff034..43982ce 100644
--- a/sdk/lib/async/deferred_load.dart
+++ b/sdk/lib/async/deferred_load.dart
@@ -36,6 +36,18 @@
    *
    * The value of the returned future is true if this invocation of
    * [load] caused the library to be loaded.
+   *
+   * If the library fails to load, the Future will complete with a
+   * DeferredLoadException.
    */
   external Future<bool> load();
 }
+
+/**
+ * Thrown when a deferred library fails to load.
+ */
+class DeferredLoadException implements Exception {
+  DeferredLoadException(String this._s);
+  String toString() => "DeferredLoadException: '$_s'";
+  final String _s;
+}
\ No newline at end of file
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 219ab39..e04fcce 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -411,144 +411,156 @@
         _propagateMultipleListeners(source, listeners);
         return;
       }
-      Zone zone = listener._zone;
-      if (hasError && !source._zone.inSameErrorZone(zone)) {
-        // Don't cross zone boundaries with errors.
-        _AsyncError asyncError = source._error;
-        source._zone.handleUncaughtError(
-            asyncError.error, asyncError.stackTrace);
-        return;
-      }
-      Zone oldZone;
-      if (!identical(Zone.current, zone)) {
-        // Change zone if it's not current.
-        oldZone = Zone._enter(zone);
-      }
       // Do the actual propagation.
-      bool listenerHasValue;
-      var listenerValueOrError;
+      // Set initial state of listenerHasValue and listenerValueOrError. These
+      // variables are updated, with the outcome of potential callbacks.
+      bool listenerHasValue = true;
+      final sourceValue = source._hasValue ? source._value : null;
+      var listenerValueOrError = sourceValue;
       // Set to true if a whenComplete needs to wait for a future.
       // The whenComplete action will resume the propagation by itself.
       bool isPropagationAborted = false;
       // TODO(floitsch): mark the listener as pending completion. Currently
       // we can't do this, since the markPendingCompletion verifies that
       // the future is not already marked (or chained).
-
-      bool handleValueCallback() {
-        try {
-          listenerValueOrError = zone.runUnary(listener._onValue,
-                                               source._value);
-          return true;
-        } catch (e, s) {
-          listenerValueOrError = new _AsyncError(e, s);
-          return false;
+      // Only if we either have an error or callbacks, go into this, somewhat
+      // expensive, branch. Here we'll enter/leave the zone. Many futures
+      // doesn't have callbacks, so this is a significant optimization.
+      if (hasError ||
+          listener._onValue != null ||
+          listener._whenCompleteAction != null) {
+        Zone zone = listener._zone;
+        if (hasError && !source._zone.inSameErrorZone(zone)) {
+          // Don't cross zone boundaries with errors.
+          _AsyncError asyncError = source._error;
+          source._zone.handleUncaughtError(
+              asyncError.error, asyncError.stackTrace);
+          return;
         }
-      }
 
-      void handleError() {
-        _AsyncError asyncError = source._error;
-        _FutureErrorTest test = listener._errorTest;
-        bool matchesTest = true;
-        if (test != null) {
+        Zone oldZone;
+        if (!identical(Zone.current, zone)) {
+          // Change zone if it's not current.
+          oldZone = Zone._enter(zone);
+        }
+
+        bool handleValueCallback() {
           try {
-            matchesTest = zone.runUnary(test, asyncError.error);
+            listenerValueOrError = zone.runUnary(listener._onValue,
+                                                 sourceValue);
+            return true;
           } catch (e, s) {
-            // TODO(ajohnsen): Should we suport rethrow for test throws?
-            listenerValueOrError = identical(asyncError.error, e) ?
-                asyncError : new _AsyncError(e, s);
-            listenerHasValue = false;
-            return;
-          }
-        }
-        Function errorCallback = listener._onError;
-        if (matchesTest && errorCallback != null) {
-          try {
-            if (errorCallback is ZoneBinaryCallback) {
-              listenerValueOrError = zone.runBinary(errorCallback,
-                                                    asyncError.error,
-                                                    asyncError.stackTrace);
-            } else {
-              listenerValueOrError = zone.runUnary(errorCallback,
-                                                   asyncError.error);
-            }
-          } catch (e, s) {
-            listenerValueOrError = identical(asyncError.error, e) ?
-                asyncError : new _AsyncError(e, s);
-            listenerHasValue = false;
-            return;
-          }
-          listenerHasValue = true;
-        } else {
-          // Copy over the error from the source.
-          listenerValueOrError = asyncError;
-          listenerHasValue = false;
-        }
-      }
-
-      void handleWhenCompleteCallback() {
-        var completeResult;
-        try {
-          completeResult = zone.run(listener._whenCompleteAction);
-        } catch (e, s) {
-          if (hasError && identical(source._error.error, e)) {
-            listenerValueOrError = source._error;
-          } else {
             listenerValueOrError = new _AsyncError(e, s);
+            return false;
           }
-          listenerHasValue = false;
         }
-        if (completeResult is Future) {
-          listener._isChained = true;
-          isPropagationAborted = true;
-          completeResult.then((ignored) {
-            // Try again. Since the future is marked as chained it won't run
-            // the whenComplete again.
-            _propagateToListeners(source, listener);
-          }, onError: (error, [stackTrace]) {
-            // When there is an error, we have to make the error the new
-            // result of the current listener.
-            if (completeResult is! _Future) {
-              // This should be a rare case.
-              completeResult = new _Future();
-              completeResult._setError(error, stackTrace);
+
+        void handleError() {
+          _AsyncError asyncError = source._error;
+          _FutureErrorTest test = listener._errorTest;
+          bool matchesTest = true;
+          if (test != null) {
+            try {
+              matchesTest = zone.runUnary(test, asyncError.error);
+            } catch (e, s) {
+              // TODO(ajohnsen): Should we suport rethrow for test throws?
+              listenerValueOrError = identical(asyncError.error, e) ?
+                  asyncError : new _AsyncError(e, s);
+              listenerHasValue = false;
+              return;
             }
-            _propagateToListeners(completeResult, listener);
-          });
+          }
+          Function errorCallback = listener._onError;
+          if (matchesTest && errorCallback != null) {
+            try {
+              if (errorCallback is ZoneBinaryCallback) {
+                listenerValueOrError = zone.runBinary(errorCallback,
+                                                      asyncError.error,
+                                                      asyncError.stackTrace);
+              } else {
+                listenerValueOrError = zone.runUnary(errorCallback,
+                                                     asyncError.error);
+              }
+            } catch (e, s) {
+              listenerValueOrError = identical(asyncError.error, e) ?
+                  asyncError : new _AsyncError(e, s);
+              listenerHasValue = false;
+              return;
+            }
+            listenerHasValue = true;
+          } else {
+            // Copy over the error from the source.
+            listenerValueOrError = asyncError;
+            listenerHasValue = false;
+          }
         }
-      }
 
-      if (!hasError) {
-        if (listener._onValue != null) {
-          listenerHasValue = handleValueCallback();
+        void handleWhenCompleteCallback() {
+          var completeResult;
+          try {
+            completeResult = zone.run(listener._whenCompleteAction);
+          } catch (e, s) {
+            if (hasError && identical(source._error.error, e)) {
+              listenerValueOrError = source._error;
+            } else {
+              listenerValueOrError = new _AsyncError(e, s);
+            }
+            listenerHasValue = false;
+          }
+          if (completeResult is Future) {
+            listener._isChained = true;
+            isPropagationAborted = true;
+            completeResult.then((ignored) {
+              // Try again. Since the future is marked as chained it won't run
+              // the whenComplete again.
+              _propagateToListeners(source, listener);
+            }, onError: (error, [stackTrace]) {
+              // When there is an error, we have to make the error the new
+              // result of the current listener.
+              if (completeResult is! _Future) {
+                // This should be a rare case.
+                completeResult = new _Future();
+                completeResult._setError(error, stackTrace);
+              }
+              _propagateToListeners(completeResult, listener);
+            });
+          }
+        }
+
+        if (!hasError) {
+          if (listener._onValue != null) {
+            listenerHasValue = handleValueCallback();
+          }
         } else {
-          listenerValueOrError = source._value;
-          listenerHasValue = true;
+          handleError();
         }
-      } else {
-        handleError();
-      }
-      if (listener._whenCompleteAction != null) {
-        handleWhenCompleteCallback();
-      }
-      // If we changed zone, oldZone will not be null.
-      if (oldZone != null) Zone._leave(oldZone);
-      if (isPropagationAborted) return;
-      // If the listener's value is a future we need to chain it.
-      if (listenerHasValue && listenerValueOrError is Future) {
-        Future chainSource = listenerValueOrError;
-        // Shortcut if the chain-source is already completed. Just continue the
-        // loop.
-        if (chainSource is _Future && chainSource._isComplete) {
-          // propagate the value (simulating a tail call).
-          listener._isChained = true;
-          source = chainSource;
-          listeners = listener;
-          continue;
+        if (listener._whenCompleteAction != null) {
+          handleWhenCompleteCallback();
         }
-        _chainFutures(chainSource, listener);
-        return;
-      }
+        // If we changed zone, oldZone will not be null.
+        if (oldZone != null) Zone._leave(oldZone);
 
+        if (isPropagationAborted) return;
+        // If the listener's value is a future we need to chain it. Note that
+        // this can only happen if there is a callback. Since 'is' checks
+        // can be expensive, we're trying to avoid it.
+        if (listenerHasValue &&
+            !identical(sourceValue, listenerValueOrError) &&
+            listenerValueOrError is Future) {
+          Future chainSource = listenerValueOrError;
+          // Shortcut if the chain-source is already completed. Just continue
+          // the loop.
+          if (chainSource is _Future && chainSource._isComplete) {
+            // propagate the value (simulating a tail call).
+            listener._isChained = true;
+            source = chainSource;
+            listeners = listener;
+            continue;
+          }
+          _chainFutures(chainSource, listener);
+          return;
+        }
+      }
       if (listenerHasValue) {
         listeners = listener._removeListeners();
         listener._setValue(listenerValueOrError);
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index aca62a9..8b380e2 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -279,6 +279,91 @@
   }
 
   /**
+   * Creates a new stream with each data event of this stream asynchronously
+   * mapped to a new event.
+   *
+   * This acts like [map], except that [convert] may return a [Future],
+   * and in that case, the stream waits for that future to complete before
+   * continuing with its result.
+   */
+  Stream asyncMap(convert(T event)) {
+    StreamController controller;
+    StreamSubscription subscription;
+    controller = new StreamController(sync: true,
+      onListen: () {
+        var add = controller.add;
+        var addError = controller.addError;
+        subscription = this.listen(
+            (T event) {
+              var newValue;
+              try {
+                newValue = convert(event);
+              } catch (e, s) {
+                controller.addError(e, s);
+                return;
+              }
+              if (newValue is Future) {
+                subscription.pause();
+                newValue.then(add, onError: addError)
+                        .whenComplete(subscription.resume);
+              } else {
+                controller.add(newValue);
+              }
+            },
+            onError: addError,
+            onDone: controller.close
+        );
+      },
+      onPause: () { subscription.pause(); },
+      onResume: () { subscription.resume(); },
+      onCancel: () { subscription.cancel(); }
+    );
+    return controller.stream;
+  }
+
+  /**
+   * Creates a new stream with the events of a stream per original event.
+   *
+   * This acts like [expand], except that [convert] returns a [Stream]
+   * instead of an [Iterable].
+   * The events of the returned stream becomes the events of the returned
+   * stream, in the order they are produced.
+   *
+   * If [convert] returns `null`, no value is put on the output stream,
+   * just as if it returned an empty stream.
+   */
+  Stream asyncExpand(Stream convert(T event)) {
+    StreamController controller;
+    StreamSubscription subscription;
+    controller = new StreamController(sync: true,
+      onListen: () {
+        subscription = this.listen(
+            (T event) {
+              Stream newStream;
+              try {
+                newStream = convert(event);
+              } catch (e, s) {
+                controller.addError(e, s);
+                return;
+              }
+              if (newStream != null) {
+                subscription.pause();
+                controller.addStream(newStream)
+                          .whenComplete(subscription.resume);
+              }
+            },
+            onError: controller.addError,
+            onDone: controller.close
+        );
+      },
+      onPause: () { subscription.pause(); },
+      onResume: () { subscription.resume(); },
+      onCancel: () { subscription.cancel(); }
+    );
+    return controller.stream;
+  }
+
+  /**
    * Creates a wrapper Stream that intercepts some errors from this stream.
    *
    * If this stream sends an error that matches [test], then it is intercepted
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index aa06e6f..8a9c936 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -345,22 +345,21 @@
   static const int CHAR_t          = 0x74;
   static const int CHAR_u          = 0x75;
 
-  final Function toEncodable;
-  final StringSink sink;
-  final Set<Object> seen;
+  final Function _toEncodable;
+  final StringSink _sink;
+  final Set<Object> _seen;
 
-  _JsonStringifier(this.sink, this.toEncodable)
-      : this.seen = new HashSet.identity();
+  _JsonStringifier(this._sink, this._toEncodable)
+      : this._seen = new HashSet.identity();
 
-  static String stringify(final object, toEncodable(object)) {
+  static String stringify(object, toEncodable(object)) {
     if (toEncodable == null) toEncodable = _defaultToEncodable;
     StringBuffer output = new StringBuffer();
-    _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
-    stringifier.stringifyValue(object);
+    printOn(object, output, toEncodable);
     return output.toString();
   }
 
-  static void printOn(final object, StringSink output, toEncodable(object)) {
+  static void printOn(object, StringSink output, toEncodable(object)) {
     _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
     stringifier.stringifyValue(object);
   }
@@ -372,7 +371,7 @@
   // ('0' + x) or ('a' + x - 10)
   static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
 
-  static void escape(StringSink sb, String s) {
+  void escape(String s) {
     final int length = s.length;
     bool needsEscape = false;
     final charCodes = new List<int>();
@@ -413,28 +412,28 @@
         charCodes.add(charCode);
       }
     }
-    sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
+    _sink.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
   }
 
-  void checkCycle(final object) {
-    if (seen.contains(object)) {
+  void checkCycle(object) {
+    if (_seen.contains(object)) {
       throw new JsonCyclicError(object);
     }
-    seen.add(object);
+    _seen.add(object);
   }
 
-  void stringifyValue(final object) {
+  void stringifyValue(object) {
     // Tries stringifying object directly. If it's not a simple value, List or
     // Map, call toJson() to get a custom representation and try serializing
     // that.
     if (!stringifyJsonValue(object)) {
       checkCycle(object);
       try {
-        var customJson = toEncodable(object);
+        var customJson = _toEncodable(object);
         if (!stringifyJsonValue(customJson)) {
           throw new JsonUnsupportedObjectError(object);
         }
-        seen.remove(object);
+        _seen.remove(object);
       } catch (e) {
         throw new JsonUnsupportedObjectError(object, cause: e);
       }
@@ -447,57 +446,57 @@
    * Returns true if the value is one of these types, and false if not.
    * If a value is both a [List] and a [Map], it's serialized as a [List].
    */
-  bool stringifyJsonValue(final object) {
+  bool stringifyJsonValue(object) {
     if (object is num) {
       if (!object.isFinite) return false;
-      sink.write(numberToString(object));
+      _sink.write(numberToString(object));
       return true;
     } else if (identical(object, true)) {
-      sink.write('true');
+      _sink.write('true');
       return true;
     } else if (identical(object, false)) {
-      sink.write('false');
+      _sink.write('false');
        return true;
     } else if (object == null) {
-      sink.write('null');
+      _sink.write('null');
       return true;
     } else if (object is String) {
-      sink.write('"');
-      escape(sink, object);
-      sink.write('"');
+      _sink.write('"');
+      escape(object);
+      _sink.write('"');
       return true;
     } else if (object is List) {
       checkCycle(object);
       List a = object;
-      sink.write('[');
+      _sink.write('[');
       if (a.length > 0) {
         stringifyValue(a[0]);
         for (int i = 1; i < a.length; i++) {
-          sink.write(',');
+          _sink.write(',');
           stringifyValue(a[i]);
         }
       }
-      sink.write(']');
-      seen.remove(object);
+      _sink.write(']');
+      _seen.remove(object);
       return true;
     } else if (object is Map) {
       checkCycle(object);
       Map<String, Object> m = object;
-      sink.write('{');
+      _sink.write('{');
       bool first = true;
       m.forEach((String key, Object value) {
         if (!first) {
-          sink.write(',"');
+          _sink.write(',"');
         } else {
-          sink.write('"');
+          _sink.write('"');
         }
-        escape(sink, key);
-        sink.write('":');
+        escape(key);
+        _sink.write('":');
         stringifyValue(value);
         first = false;
       });
-      sink.write('}');
-      seen.remove(object);
+      _sink.write('}');
+      _seen.remove(object);
       return true;
     } else {
       return false;
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index b9a4547..2e93ad1 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -82,6 +82,16 @@
  *     Duration difference = berlinWallFell.difference(moonLanding)
  *     assert(difference.inDays == 7416);
  *
+ * The difference between two dates in different time zones
+ * is just the number of nanoseconds between the two points in time.
+ * It doesn't take calendar days into account.
+ * That means that the difference between two midnights in local time may be
+ * less than 24 hours times the number of days between them,
+ * if there is a daylight saving change in between.
+ * If the difference above is calculated using Australian local time, the
+ * difference is 7415 days and 23 hours, which is only 7415 whole days as
+ * reported by `inDays`.
+ *
  * ## Other resources
  *
  * See [Duration] to represent a span of time.
@@ -148,34 +158,30 @@
    *
    *     DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4);
    */
-  // TODO(8042): This should be a redirecting constructor and not a factory.
-  factory DateTime(int year,
+  DateTime(int year,
            [int month = 1,
             int day = 1,
             int hour = 0,
             int minute = 0,
             int second = 0,
-            int millisecond = 0]) {
-    return new DateTime._internal(
-          year, month, day, hour, minute, second, millisecond, false);
-  }
+            int millisecond = 0])
+      : this._internal(
+            year, month, day, hour, minute, second, millisecond, false);
 
   /**
    * Constructs a [DateTime] instance specified in the UTC time zone.
    *
    *     DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
    */
-  // TODO(8042): This should be a redirecting constructor and not a factory.
-  factory DateTime.utc(int year,
-                       [int month = 1,
-                        int day = 1,
-                        int hour = 0,
-                        int minute = 0,
-                        int second = 0,
-                        int millisecond = 0]) {
-    return new DateTime._internal(
+  DateTime.utc(int year,
+               [int month = 1,
+                int day = 1,
+                int hour = 0,
+                int minute = 0,
+                int second = 0,
+                int millisecond = 0])
+    : this._internal(
           year, month, day, hour, minute, second, millisecond, true);
-  }
 
   /**
    * Constructs a [DateTime] instance with current date and time in the
@@ -184,15 +190,21 @@
    *     DateTime thisInstant = new DateTime.now();
    *
    */
-  // TODO(8042): This should be a redirecting constructor and not a factory.
-  factory DateTime.now() { return new DateTime._now(); }
+  DateTime.now() : this._now();
 
   /**
    * Constructs a new [DateTime] instance based on [formattedString].
    *
    * Throws a [FormatException] if the input cannot be parsed.
    *
-   * The function parses a subset of ISO 8601. Examples of accepted strings:
+   * The function parses a subset of ISO 8601
+   * which includes the subset accepted by RFC 3339.
+   *
+   * The result is always in either local time or UTC.
+   * If a time zone offset other than UTC is specified,
+   * the time is converted to the equivalent UTC time.
+   *
+   * Examples of accepted strings:
    *
    * * `"2012-02-27 13:27:00"`
    * * `"2012-02-27 13:27:00.123456z"`
@@ -203,15 +215,18 @@
    * * `"2012-02-27T14Z"`
    * * `"2012-02-27T14+00:00"`
    * * `"-123450101 00:00:00 Z"`: in the year -12345.
+   * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"`
    */
   // TODO(floitsch): specify grammar.
+  // TODO(lrn): restrict incorrect values like  2003-02-29T50:70:80.
   static DateTime parse(String formattedString) {
     /*
      * date ::= yeardate time_opt timezone_opt
      * yeardate ::= year colon_opt month colon_opt day
      * year ::= sign_opt digit{4,5}
      * colon_opt :: <empty> | ':'
-     * sign_opt ::=  <empty> | '+' | '-'
+     * sign ::= '+' | '-'
+     * sign_opt ::=  <empty> | sign
      * month ::= digit{2}
      * day ::= digit{2}
      * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
@@ -220,13 +235,13 @@
      * millis_opt ::= <empty> | '.' digit{1,6}
      * timezone_opt ::= <empty> | space_opt timezone
      * space_opt :: ' ' | <empty>
-     * timezone ::= 'z' | 'Z' | '+' '0' '0' timezonemins_opt
-     * timezonemins_opt ::= <empty> | colon_opt '0' '0'
+     * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
+     * timezonemins_opt ::= <empty> | colon_opt digit{2}
      */
     final RegExp re = new RegExp(
-        r'^([+-]?\d?\d\d\d\d)-?(\d\d)-?(\d\d)'  // The day part.
+        r'^([+-]?\d{4,5})-?(\d\d)-?(\d\d)'  // The day part.
         r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part
-        r'( ?[zZ]| ?\+00(?::?00)?)?)?$'); // The timezone part
+        r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part
 
     Match match = re.firstMatch(formattedString);
     if (match != null) {
@@ -252,7 +267,18 @@
         addOneMillisecond = true;
         millisecond = 999;
       }
-      bool isUtc = (match[8] != null);
+      bool isUtc = false;
+      if (match[8] != null) {  // timezone part
+        isUtc = true;
+        if (match[9] != null) {
+          // timezone other than 'Z' and 'z'.
+          int sign = (match[9] == '-') ? -1 : 1;
+          int hourDifference = int.parse(match[10]);
+          int minuteDifference = parseIntOrZero(match[11]);
+          minuteDifference += 60 * hourDifference;
+          minute -= sign * minuteDifference;
+        }
+      }
       int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
           years, month, day, hour, minute, second, millisecond, isUtc);
       if (millisecondsSinceEpoch == null) {
@@ -397,6 +423,26 @@
                                                    isUtc: true);
   }
 
+  static String _fourDigits(int n) {
+    int absN = n.abs();
+    String sign = n < 0 ? "-" : "";
+    if (absN >= 1000) return "$n";
+    if (absN >= 100) return "${sign}0$absN";
+    if (absN >= 10) return "${sign}00$absN";
+    return "${sign}000$absN";
+  }
+
+  static String _threeDigits(int n) {
+    if (n >= 100) return "${n}";
+    if (n >= 10) return "0${n}";
+    return "00${n}";
+  }
+
+  static String _twoDigits(int n) {
+    if (n >= 10) return "${n}";
+    return "0${n}";
+  }
+
   /**
    * Returns a human-readable string for this instance.
    *
@@ -407,33 +453,13 @@
    * at the pub shared packages repo.
    */
   String toString() {
-    String fourDigits(int n) {
-      int absN = n.abs();
-      String sign = n < 0 ? "-" : "";
-      if (absN >= 1000) return "$n";
-      if (absN >= 100) return "${sign}0$absN";
-      if (absN >= 10) return "${sign}00$absN";
-      return "${sign}000$absN";
-    }
-
-    String threeDigits(int n) {
-      if (n >= 100) return "${n}";
-      if (n >= 10) return "0${n}";
-      return "00${n}";
-    }
-
-    String twoDigits(int n) {
-      if (n >= 10) return "${n}";
-      return "0${n}";
-    }
-
-    String y = fourDigits(year);
-    String m = twoDigits(month);
-    String d = twoDigits(day);
-    String h = twoDigits(hour);
-    String min = twoDigits(minute);
-    String sec = twoDigits(second);
-    String ms = threeDigits(millisecond);
+    String y = _fourDigits(year);
+    String m = _twoDigits(month);
+    String d = _twoDigits(day);
+    String h = _twoDigits(hour);
+    String min = _twoDigits(minute);
+    String sec = _twoDigits(second);
+    String ms = _threeDigits(millisecond);
     if (isUtc) {
       return "$y-$m-$d $h:$min:$sec.${ms}Z";
     } else {
@@ -442,12 +468,32 @@
   }
 
   /**
+   * Returns an ISO-8601 full-precision extended format representation.
+   *
+   * The format is "YYYY-MM-DDTHH:mm:ss.sssZ" for UTC time, and
+   * "YYYY-MM-DDTHH:mm:ss.sss" (no trailing "Z") for local/non-UTC time.
+   */
+  String toIso8601String() {
+    String y = _fourDigits(year);
+    String m = _twoDigits(month);
+    String d = _twoDigits(day);
+    String h = _twoDigits(hour);
+    String min = _twoDigits(minute);
+    String sec = _twoDigits(second);
+    String ms = _threeDigits(millisecond);
+    if (isUtc) {
+      return "$y-$m-${d}T$h:$min:$sec.${ms}Z";
+    } else {
+      return "$y-$m-${d}T$h:$min:$sec.$ms";
+    }
+  }
+
+  /**
    * Returns a new [DateTime] instance with [duration] added to [this].
    *
    *     DateTime today = new DateTime.now();
    *     DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
    */
-
   DateTime add(Duration duration) {
     int ms = millisecondsSinceEpoch;
     return new DateTime.fromMillisecondsSinceEpoch(
@@ -505,7 +551,7 @@
    * The time zone offset, which
    * is the difference between local time and UTC.
    *
-   * The offset is positive for time zones west of UTC.
+   * The offset is positive for time zones east of UTC.
    *
    * Note, that JavaScript, Python and C return the difference between UTC and
    * local time. Java, C# and Ruby return the difference between local time and
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 578b4c6..0b55b8e 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -96,12 +96,7 @@
       list.add(e);
     }
     if (growable) return list;
-    int length = list.length;
-    List<E> fixedList = new List<E>(length);
-    for (int i = 0; i < length; i++) {
-      fixedList[i] = list[i];
-    }
-    return fixedList;
+    return makeListFixedLength(list);
   }
 
   /**
diff --git a/sdk/lib/core/stopwatch.dart b/sdk/lib/core/stopwatch.dart
index c47c6d2..9650a57 100644
--- a/sdk/lib/core/stopwatch.dart
+++ b/sdk/lib/core/stopwatch.dart
@@ -8,6 +8,11 @@
  * A simple stopwatch interface to measure elapsed time.
  */
 class Stopwatch {
+  /**
+   * Frequency of the elapsed counter in Hz.
+   */
+  final int frequency = _frequency();
+
   // The _start and _stop fields capture the time when [start] and [stop]
   // are called respectively.
   // If _start is null, then the [Stopwatch] has not been started yet.
@@ -24,7 +29,7 @@
    *
    *     Stopwatch stopwatch = new Stopwatch()..start();
    */
-  Stopwatch() : _start = null, _stop = null {}
+  Stopwatch();
 
   /**
    * Starts the [Stopwatch].
@@ -116,10 +121,6 @@
     return (elapsedTicks * 1000) ~/ frequency;
   }
 
-  /**
-   * Returns the frequency of the elapsed counter in Hz.
-   */
-  int get frequency => _frequency();
 
   /**
    * Returns wether the [StopWatch] is currently running.
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 799a2a9..fce1249 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -326,6 +326,53 @@
   String trim();
 
   /**
+   * Creates a new string by concatenating this string with itself a number
+   * of times.
+   *
+   * The result of `str * n` is equivalent to
+   * `str + str + ...`(n times)`... + str`.
+   *
+   * Returns an empty string if [times] is zero or negative.
+   */
+  String operator *(int times);
+
+  /**
+   * Pads this string on the left if it is shorther than [width].
+   *
+   * Return a new string that prepends [padding] onto this string
+   * one time for each position the length is less than [width].
+   *
+   * If [width] is already smaller than or equal to `this.length`,
+   * no padding is added. A negative `width` is treated as zero.
+   *
+   * If [padding] has length different from 1, the result will not
+   * have length `width`. This may be useful for cases where the
+   * padding is a longer string representing a single character, like
+   * `"&nbsp;"` or `"\u{10002}`".
+   * In that case, the user should make sure that `this.length` is
+   * the correct measure of the strings length.
+   */
+  String padLeft(int width, [String padding = ' ']);
+
+  /**
+   * Pads this string on the right if it is shorther than [width].
+   *
+   * Return a new string that appends [padding] after this string
+   * one time for each position the length is less than [width].
+   *
+   * If [width] is already smaller than or equal to `this.length`,
+   * no padding is added. A negative `width` is treated as zero.
+   *
+   * If [padding] has length different from 1, the result will not
+   * have length `width`. This may be useful for cases where the
+   * padding is a longer string representing a single character, like
+   * `"&nbsp;"` or `"\u{10002}`".
+   * In that case, the user should make sure that `this.length` is
+   * the correct measure of the strings length.
+   */
+  String padRight(int width, [String padding = ' ']);
+
+  /**
    * Returns true if this string contains a match of [other]:
    *
    *     var string = 'Dart strings';
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index c92001a..9f33e3a 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -9,10 +9,24 @@
   /**
    * Constructs a new Symbol.
    *
-   * An [ArgumentError] is thrown if [name] starts with an underscore, or if
-   * [name] is not a [String].  An [ArgumentError] is thrown if [name] is not
-   * an empty string and is not a valid qualified identifier optionally
-   * followed by [:'=':].
+   * The name must be a valid public Dart member name,
+   * public constructor name, or library name, optionally qualified.
+   *
+   * A qualified name is a valid name preceded by a public identifier name
+   * and a '`.`', e.g., `foo.bar.baz=` is a qualified version of `baz=`.
+   * That means that the content of the [name] String must be either
+   *
+   * * a valid public Dart identifier
+   *   (that is, an identifier not starting with "`_`"),
+   * * such an identifier followed by "=" (a setter name),
+   * * the name of a declarable operator
+   *   (one of "`+`", "`-`", "`*`", "`/`", "`%`", "`~/`", "`&`", "`|`",
+   *   "`^`", "`~`", "`<<`", "`>>`", "`<`", "`<=`", "`>`", "`>=`", "`==`",
+   *   "`[]`", "`[]=`", or "`unary-`"),
+   * * any of the above preceeded by any number of qualifiers,
+   *   where a qualifier is a non-private identifier followed by '`.`',
+   * * or the empty string (the default name of a library with not library
+   *   name declaration).
    *
    * The following text is non-normative:
    *
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 41130ad..2b26b6d 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -118,17 +118,227 @@
   /**
    * Creates a new URI object by parsing a URI string.
    */
-  static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri));
+  static Uri parse(String uri) {
+    // This parsing will not validate percent-encoding, IPv6, etc. When done
+    // it will call `new Uri(...)` which will perform these validations.
+    // This is purely splitting up the URI string into components.
+    //
+    // Important parts of the RFC 3986 used here:
+    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+    //
+    // hier-part     = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-rootless
+    //               / path-empty
+    //
+    // URI-reference = URI / relative-ref
+    //
+    // absolute-URI  = scheme ":" hier-part [ "?" query ]
+    //
+    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
+    //
+    // relative-part = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-noscheme
+    //               / path-empty
+    //
+    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+    //
+    // authority     = [ userinfo "@" ] host [ ":" port ]
+    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
+    // host          = IP-literal / IPv4address / reg-name
+    // port          = *DIGIT
+    // reg-name      = *( unreserved / pct-encoded / sub-delims )
+    //
+    // path          = path-abempty    ; begins with "/" or is empty
+    //               / path-absolute   ; begins with "/" but not "//"
+    //               / path-noscheme   ; begins with a non-colon segment
+    //               / path-rootless   ; begins with a segment
+    //               / path-empty      ; zero characters
+    //
+    // path-abempty  = *( "/" segment )
+    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
+    // path-noscheme = segment-nz-nc *( "/" segment )
+    // path-rootless = segment-nz *( "/" segment )
+    // path-empty    = 0<pchar>
+    //
+    // segment       = *pchar
+    // segment-nz    = 1*pchar
+    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+    //               ; non-zero-length segment without any colon ":"
+    //
+    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+    //
+    // query         = *( pchar / "/" / "?" )
+    //
+    // fragment      = *( pchar / "/" / "?" )
+    bool isRegName(int ch) {
+      return ch < 128 && ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
+    }
 
-  Uri._fromMatch(Match m) :
-    this(scheme: _makeScheme(_emptyIfNull(m[_COMPONENT_SCHEME])),
-         userInfo: _emptyIfNull(m[_COMPONENT_USER_INFO]),
-         host: _eitherOf(
-         m[_COMPONENT_HOST], m[_COMPONENT_HOST_IPV6]),
-         port: _parseIntOrZero(m[_COMPONENT_PORT]),
-         path: _emptyIfNull(m[_COMPONENT_PATH]),
-         query: _emptyIfNull(m[_COMPONENT_QUERY_DATA]),
-         fragment: _emptyIfNull(m[_COMPONENT_FRAGMENT]));
+    int ipV6Address(int index) {
+      // IPv6. Skip to ']'.
+      index = uri.indexOf(']', index);
+      if (index == -1) {
+        throw new FormatException("Bad end of IPv6 host");
+      }
+      return index + 1;
+    }
+
+    int length = uri.length;
+    int index = 0;
+
+    int schemeEndIndex = 0;
+
+    if (length == 0) {
+      return new Uri();
+    }
+
+    if (uri.codeUnitAt(0) != _SLASH) {
+      // Can be scheme.
+      while (index < length) {
+        // Look for ':'. If found, continue from the post of ':'. If not (end
+        // reached or invalid scheme char found) back up one char, and continue
+        // to path.
+        // Note that scheme-chars is contained in path-chars.
+        int codeUnit = uri.codeUnitAt(index++);
+        if (!_isSchemeCharacter(codeUnit)) {
+          if (codeUnit == _COLON) {
+            schemeEndIndex = index;
+          } else {
+            // Back up one char, since we met an invalid scheme char.
+            index--;
+          }
+          break;
+        }
+      }
+    }
+
+    int userInfoEndIndex = -1;
+    int portIndex = -1;
+    int authorityEndIndex = schemeEndIndex;
+    // If we see '//', there must be an authority.
+    if (authorityEndIndex == index &&
+        authorityEndIndex + 1 < length &&
+        uri.codeUnitAt(authorityEndIndex) == _SLASH &&
+        uri.codeUnitAt(authorityEndIndex + 1) == _SLASH) {
+      // Skip '//'.
+      authorityEndIndex += 2;
+      // It can both be host and userInfo.
+      while (authorityEndIndex < length) {
+        int codeUnit = uri.codeUnitAt(authorityEndIndex++);
+        if (!isRegName(codeUnit)) {
+          if (codeUnit == _LEFT_BRACKET) {
+            authorityEndIndex = ipV6Address(authorityEndIndex);
+          } else if (portIndex == -1 && codeUnit == _COLON) {
+            // First time ':'.
+            portIndex = authorityEndIndex;
+          } else if (codeUnit == _AT_SIGN || codeUnit == _COLON) {
+            // Second time ':' or first '@'. Must be userInfo.
+            userInfoEndIndex = uri.indexOf('@', authorityEndIndex - 1);
+            // Not found. Must be path then.
+            if (userInfoEndIndex == -1) {
+              authorityEndIndex = index;
+              break;
+            }
+            portIndex = -1;
+            authorityEndIndex = userInfoEndIndex + 1;
+            // Now it can only be host:port.
+            while (authorityEndIndex < length) {
+              int codeUnit = uri.codeUnitAt(authorityEndIndex++);
+              if (!isRegName(codeUnit)) {
+                if (codeUnit == _LEFT_BRACKET) {
+                  authorityEndIndex = ipV6Address(authorityEndIndex);
+                } else if (codeUnit == _COLON) {
+                  if (portIndex != -1) {
+                    throw new FormatException("Double port in host");
+                  }
+                  portIndex = authorityEndIndex;
+                } else {
+                  authorityEndIndex--;
+                  break;
+                }
+              }
+            }
+            break;
+          } else {
+            authorityEndIndex--;
+            break;
+          }
+        }
+      }
+    } else {
+      authorityEndIndex = schemeEndIndex;
+    }
+
+    // At path now.
+    int pathEndIndex = authorityEndIndex;
+    while (pathEndIndex < length) {
+      int codeUnit = uri.codeUnitAt(pathEndIndex++);
+      if (codeUnit == _QUESTION || codeUnit == _NUMBER_SIGN) {
+        pathEndIndex--;
+        break;
+      }
+    }
+
+    // Maybe query.
+    int queryEndIndex = pathEndIndex;
+    if (queryEndIndex < length && uri.codeUnitAt(queryEndIndex) == _QUESTION) {
+      while (queryEndIndex < length) {
+        int codeUnit = uri.codeUnitAt(queryEndIndex++);
+        if (codeUnit == _NUMBER_SIGN) {
+          queryEndIndex--;
+          break;
+        }
+      }
+    }
+
+    var scheme = null;
+    if (schemeEndIndex > 0) {
+      scheme = uri.substring(0, schemeEndIndex - 1);
+    }
+
+    var host = "";
+    var userInfo = "";
+    var port = 0;
+    if (schemeEndIndex != authorityEndIndex) {
+      int startIndex = schemeEndIndex + 2;
+      if (userInfoEndIndex > 0) {
+        userInfo = uri.substring(startIndex, userInfoEndIndex);
+        startIndex = userInfoEndIndex + 1;
+      }
+      if (portIndex > 0) {
+        var portStr = uri.substring(portIndex, authorityEndIndex);
+        try {
+          port = int.parse(portStr);
+        } catch (_) {
+          throw new FormatException("Invalid port: '$portStr'");
+        }
+        host = uri.substring(startIndex, portIndex - 1);
+      } else {
+        host = uri.substring(startIndex, authorityEndIndex);
+      }
+    }
+
+    var path = uri.substring(authorityEndIndex, pathEndIndex);
+    var query = "";
+    if (pathEndIndex < queryEndIndex) {
+      query = uri.substring(pathEndIndex + 1, queryEndIndex);
+    }
+    var fragment = "";
+    // If queryEndIndex is not at end (length), there is a fragment.
+    if (queryEndIndex < length) {
+      fragment = uri.substring(queryEndIndex + 1, length);
+    }
+
+    return new Uri(scheme: scheme,
+                   userInfo: userInfo,
+                   host: host,
+                   port: port,
+                   path: path,
+                   query: query,
+                   fragment: fragment);
+  }
 
   /**
    * Creates a new URI from its components.
@@ -545,10 +755,6 @@
              ((_schemeLowerTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
     }
 
-    bool isSchemeCharacter(int ch) {
-      return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
-    }
-
     if (scheme == null) return "";
     bool allLowercase = true;
     int length = scheme.length;
@@ -559,7 +765,7 @@
         throw new ArgumentError('Illegal scheme: $scheme');
       }
       if (!isSchemeLowerCharacter(codeUnit)) {
-        if (isSchemeCharacter(codeUnit)) {
+        if (_isSchemeCharacter(codeUnit)) {
           allLowercase = false;
         } else {
           throw new ArgumentError('Illegal scheme: $scheme');
@@ -617,6 +823,9 @@
   }
 
   static String _normalize(String component) {
+    int index = component.indexOf('%');
+    if (index < 0) return component;
+
     bool isNormalizedHexDigit(int digit) {
       return (_ZERO <= digit && digit <= _NINE) ||
           (_UPPER_CASE_A <= digit && digit <= _UPPER_CASE_F);
@@ -666,7 +875,6 @@
     // Start building the normalized component string.
     StringBuffer result;
     int length = component.length;
-    int index = 0;
     int prevIndex = 0;
 
     // Copy a part of the component string to the result.
@@ -680,96 +888,52 @@
     }
 
     while (index < length) {
-
       // Normalize percent-encoding to uppercase and don't encode
       // unreserved characters.
-      if (component.codeUnitAt(index) == _PERCENT) {
-        if (length < index + 2) {
-            throw new ArgumentError(
-                "Invalid percent-encoding in URI component: $component");
-        }
+      assert(component.codeUnitAt(index) == _PERCENT);
+      if (length < index + 2) {
+          throw new ArgumentError(
+              "Invalid percent-encoding in URI component: $component");
+      }
 
-        var codeUnit1 = component.codeUnitAt(index + 1);
-        var codeUnit2 = component.codeUnitAt(index + 2);
-        var decodedCodeUnit = decodeHexDigitPair(index + 1);
-        if (isNormalizedHexDigit(codeUnit1) &&
-            isNormalizedHexDigit(codeUnit2) &&
-            !isUnreserved(decodedCodeUnit)) {
-          index += 3;
-        } else {
-          fillResult();
-          if (isUnreserved(decodedCodeUnit)) {
-            result.writeCharCode(decodedCodeUnit);
-          } else {
-            result.write("%");
-            result.writeCharCode(normalizeHexDigit(index + 1));
-            result.writeCharCode(normalizeHexDigit(index + 2));
-          }
-          index += 3;
-          prevIndex = index;
-        }
+      var codeUnit1 = component.codeUnitAt(index + 1);
+      var codeUnit2 = component.codeUnitAt(index + 2);
+      var decodedCodeUnit = decodeHexDigitPair(index + 1);
+      if (isNormalizedHexDigit(codeUnit1) &&
+          isNormalizedHexDigit(codeUnit2) &&
+          !isUnreserved(decodedCodeUnit)) {
+        index += 3;
       } else {
-        index++;
+        fillResult();
+        if (isUnreserved(decodedCodeUnit)) {
+          result.writeCharCode(decodedCodeUnit);
+        } else {
+          result.write("%");
+          result.writeCharCode(normalizeHexDigit(index + 1));
+          result.writeCharCode(normalizeHexDigit(index + 2));
+        }
+        index += 3;
+        prevIndex = index;
+      }
+      int next = component.indexOf('%', index);
+      if (next >= index) {
+        index = next;
+      } else {
+        index = length;
       }
     }
+    if (result == null) return component;
+
     if (result != null && prevIndex != index) fillResult();
     assert(index == length);
 
-    if (result == null) return component;
     return result.toString();
   }
 
-  static String _emptyIfNull(String val) => val != null ? val : '';
-
-  static int _parseIntOrZero(String val) {
-    if (val != null && val != '') {
-      return int.parse(val);
-    } else {
-      return 0;
-    }
+  static bool _isSchemeCharacter(int ch) {
+    return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
   }
 
-  static String _eitherOf(String val1, String val2) {
-    if (val1 != null) return val1;
-    if (val2 != null) return val2;
-    return '';
-  }
-
-  // NOTE: This code was ported from: closure-library/closure/goog/uri/utils.js
-  static final RegExp _splitRe = new RegExp(
-      '^'
-      '(?:'
-        '([^:/?#]+)'                    // scheme - ignore special characters
-                                        // used by other URL parts such as :,
-                                        // ?, /, #, and .
-      ':)?'
-      '(?://'
-        '(?:([^/?#]*)@)?'               // userInfo
-        '(?:'
-          r'([\w\d\-\u0100-\uffff.%]*)'
-                                        // host - restrict to letters,
-                                        // digits, dashes, dots, percent
-                                        // escapes, and unicode characters.
-          '|'
-          // TODO(ajohnsen): Only allow a max number of parts?
-          r'\[([A-Fa-f0-9:.]*)\])'
-                                        // IPv6 host - restrict to hex,
-                                        // dot and colon.
-        '(?::([0-9]+))?'                // port
-      ')?'
-      r'([^?#[]+)?'                     // path
-      r'(?:\?([^#]*))?'                 // query
-      '(?:#(.*))?'                      // fragment
-      r'$');
-
-  static const _COMPONENT_SCHEME = 1;
-  static const _COMPONENT_USER_INFO = 2;
-  static const _COMPONENT_HOST = 3;
-  static const _COMPONENT_HOST_IPV6 = 4;
-  static const _COMPONENT_PORT = 5;
-  static const _COMPONENT_PATH = 6;
-  static const _COMPONENT_QUERY_DATA = 7;
-  static const _COMPONENT_FRAGMENT = 8;
 
   /**
    * Returns whether the URI is absolute.
@@ -1369,6 +1533,7 @@
   // Frequently used character codes.
   static const int _SPACE = 0x20;
   static const int _DOUBLE_QUOTE = 0x22;
+  static const int _NUMBER_SIGN = 0x23;
   static const int _PERCENT = 0x25;
   static const int _ASTERISK = 0x2A;
   static const int _PLUS = 0x2B;
@@ -1625,6 +1790,27 @@
                 //              pqrstuvwxyz   ~
       0x47ff];  // 0x70 - 0x7f  1111111111100010
 
+  // Characters allowed in the reg-name as of RFC 3986.
+  // RFC 3986 Apendix A
+  // reg-name = *( unreserved / pct-encoded / sub-delims )
+  static const _regNameTable = const [
+                //             LSB            MSB
+                //              |              |
+      0x0000,   // 0x00 - 0x0f  0000000000000000
+      0x0000,   // 0x10 - 0x1f  0000000000000000
+                //               !  $%&'()*+,-.
+      0x7ff2,   // 0x20 - 0x2f  0100111111111110
+                //              0123456789 ; =
+      0x2bff,   // 0x30 - 0x3f  1111111111010100
+                //               ABCDEFGHIJKLMNO
+      0xfffe,   // 0x40 - 0x4f  0111111111111111
+                //              PQRSTUVWXYZ    _
+      0x87ff,   // 0x50 - 0x5f  1111111111100001
+                //               abcdefghijklmno
+      0xfffe,   // 0x60 - 0x6f  0111111111111111
+                //              pqrstuvwxyz   ~
+      0x47ff];  // 0x70 - 0x7f  1111111111100010
+
   // Characters allowed in the path as of RFC 3986.
   // RFC 3986 section 3.3.
   // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 187a24b..15967d9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -12729,7 +12729,7 @@
   @DocsEditable()
   File item(int index) native;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -12737,6 +12737,17 @@
 @DocsEditable()
 @DomName('FileReader')
 class FileReader extends EventTarget native "FileReader" {
+
+  @DomName('FileReader.result')
+  @DocsEditable()
+  Object get result {
+    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
+    if (res is ByteBuffer) {
+      return new Uint8List.view(res);
+    }
+    return res;
+  }
+
   // To suppress missing implicit constructor warnings.
   factory FileReader._() { throw new UnsupportedError("Not supported"); }
 
@@ -12827,11 +12838,6 @@
   @DocsEditable()
   final int readyState;
 
-  @DomName('FileReader.result')
-  @DocsEditable()
-  @Creates('String|NativeByteBuffer|Null')
-  final Object result;
-
   @DomName('FileReader.abort')
   @DocsEditable()
   void abort() native;
@@ -12878,6 +12884,7 @@
   @DomName('FileReader.onprogress')
   @DocsEditable()
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
+
 }
 // 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
@@ -14590,6 +14597,17 @@
    * This is similar to [request] but specialized for HTTP GET requests which
    * return text content.
    *
+   * To add query parameters, append them to the [url] following a `?`,
+   * joining each key to its value with `=` and separating key-value pairs with
+   * `&`.
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.getString('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -14607,6 +14625,20 @@
    * to sending a FormData object with broader browser support but limited to
    * String values.
    *
+   * If [data] is supplied, the key/value pairs are URI encoded with
+   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
+   *
+   * Unless otherwise specified, this method appends the following header:
+   *
+   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
+   *
+   * Here's an example of using this method:
+   *
+   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
+   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
+   *       // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -14658,6 +14690,24 @@
    * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
    * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    *
+   * The following is equivalent to the [getString] sample above:
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.request('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * Here's an example of submitting an entire form with [FormData].
+   *
+   *     var myForm = querySelector('form#myForm');
+   *     var data = new FormData(myForm);
+   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * Note that requests for file:// URIs are only supported by Chrome extensions
    * with appropriate permissions in their manifest. Requests to file:// URIs
    * will also never fail- the Future will always complete successfully, even
@@ -16757,7 +16807,7 @@
   @DocsEditable()
   final FormElement form;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -16815,6 +16865,12 @@
   @DomName('HTMLLinkElement.type')
   @DocsEditable()
   String type;
+
+
+    /// Checks if HTML imports are supported on the current platform.
+  bool get supportsImport {
+    return JS('bool', '("import" in #)', this);
+  }
 }
 // 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
@@ -32027,7 +32083,7 @@
  * animation frame is discouraged. See also:
  * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
  */
-abstract class CssRect extends MutableRectangle<num> implements Rectangle<num> {
+abstract class CssRect extends MutableRectangle<num> {
   Element _element;
 
   CssRect(this._element) : super(0, 0, 0, 0);
@@ -35422,6 +35478,21 @@
  * KeyEvent tries to provide a higher level, more polished keyboard event
  * information on top of the "raw" [KeyboardEvent].
  *
+ * The mechanics of using KeyEvents is a little different from the underlying
+ * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
+ * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
+ * Here's an example usage:
+ *
+ *     // Initialize a stream for the KeyEvents:
+ *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
+ *     // Start listening to the stream of KeyEvents.
+ *     stream.listen((keyEvent) =>
+ *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
+ *     ...
+ *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
+ *     // listeners can know a KeyEvent happened.
+ *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
+ *
  * This class is very much a work in progress, and we'd love to get information
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 60c8271..3cc7cd5 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -13044,16 +13044,16 @@
   File item(int index) native "FileList_item_Callback";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
-
 
 @DocsEditable()
 @DomName('FileReader')
 class FileReader extends EventTarget {
+
+
   // To suppress missing implicit constructor warnings.
   factory FileReader._() { throw new UnsupportedError("Not supported"); }
 
@@ -15694,6 +15694,17 @@
    * This is similar to [request] but specialized for HTTP GET requests which
    * return text content.
    *
+   * To add query parameters, append them to the [url] following a `?`,
+   * joining each key to its value with `=` and separating key-value pairs with
+   * `&`.
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.getString('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -15711,6 +15722,20 @@
    * to sending a FormData object with broader browser support but limited to
    * String values.
    *
+   * If [data] is supplied, the key/value pairs are URI encoded with
+   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
+   *
+   * Unless otherwise specified, this method appends the following header:
+   *
+   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
+   *
+   * Here's an example of using this method:
+   *
+   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
+   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
+   *       // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -15762,6 +15787,24 @@
    * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
    * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    *
+   * The following is equivalent to the [getString] sample above:
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.request('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * Here's an example of submitting an entire form with [FormData].
+   *
+   *     var myForm = querySelector('form#myForm');
+   *     var data = new FormData(myForm);
+   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * Note that requests for file:// URIs are only supported by Chrome extensions
    * with appropriate permissions in their manifest. Requests to file:// URIs
    * will also never fail- the Future will always complete successfully, even
@@ -18168,12 +18211,10 @@
   FormElement get form native "HTMLLegendElement_form_Getter";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
-
 
 @DocsEditable()
 @DomName('HTMLLinkElement')
@@ -18253,6 +18294,11 @@
   @DocsEditable()
   void set type(String value) native "HTMLLinkElement_type_Setter";
 
+
+    /// Checks if HTML imports are supported on the current platform.
+  bool get supportsImport {
+    return true;
+  }
 }
 // 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
@@ -34786,7 +34832,7 @@
  * animation frame is discouraged. See also:
  * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
  */
-abstract class CssRect extends MutableRectangle<num> implements Rectangle<num> {
+abstract class CssRect extends MutableRectangle<num> {
   Element _element;
 
   CssRect(this._element) : super(0, 0, 0, 0);
@@ -38012,6 +38058,21 @@
  * KeyEvent tries to provide a higher level, more polished keyboard event
  * information on top of the "raw" [KeyboardEvent].
  *
+ * The mechanics of using KeyEvents is a little different from the underlying
+ * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
+ * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
+ * Here's an example usage:
+ *
+ *     // Initialize a stream for the KeyEvents:
+ *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
+ *     // Start listening to the stream of KeyEvents.
+ *     stream.listen((keyEvent) =>
+ *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
+ *     ...
+ *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
+ *     // listeners can know a KeyEvent happened.
+ *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
+ *
  * This class is very much a work in progress, and we'd love to get information
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
diff --git a/sdk/lib/internal/list.dart b/sdk/lib/internal/list.dart
index 14eeb13..f40c39b 100644
--- a/sdk/lib/internal/list.dart
+++ b/sdk/lib/internal/list.dart
@@ -305,3 +305,29 @@
 
   E elementAt(int index) => _source.elementAt(_source.length - 1 - index);
 }
+
+/**
+ * Converts a growable list to a fixed length list with the same elements.
+ *
+ * For internal use only.
+ * Only works on growable lists as created by `[]` or `new List()`.
+ * May throw on any other list.
+ *
+ * The operation is efficient. It doesn't copy the elements, but converts
+ * the existing list directly to a fixed length list.
+ * That means that it is a destructive conversion.
+ * The original list should not be used afterwards.
+ *
+ * The returned list may be the same list as the orginal,
+ * or it may be a different list (according to [identical]).
+ * The original list may have changed type to be a fixed list,
+ * or become empty or been otherwise modified.
+ * It will still be a valid object, so references to it will not, e.g., crash
+ * the runtime if accessed, but no promises are made wrt. its contents.
+ *
+ * This unspecified behavior is the reason the function is not exposed to
+ * users. We allow the underlying implementation to make the most efficient
+ * conversion, at the cost of leaving the original list in an unspecified
+ * state.
+ */
+external List makeListFixedLength(List growableList);
diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart
index 7a0369a..338b06b 100644
--- a/sdk/lib/internal/symbol.dart
+++ b/sdk/lib/internal/symbol.dart
@@ -15,29 +15,44 @@
 class Symbol implements core.Symbol {
   final String _name;
 
-  static final RegExp validationPattern =
-      new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
-                 r'-|'
-                 r'unary-|'
-                 r'\[\]=|'
-                 r'~|'
-                 r'==|'
-                 r'\[\]|'
-                 r'\*|'
-                 r'/|'
-                 r'%|'
-                 r'~/|'
-                 r'\+|'
-                 r'<<|'
-                 r'>>|'
-                 r'>=|'
-                 r'>|'
-                 r'<=|'
-                 r'<|'
-                 r'&|'
-                 r'\^|'
-                 r'\|'
-                 r')$');
+  // Reserved words are not allowed as identifiers.
+  static const String reservedWordRE =
+      r'(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|'
+      r'e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|'
+      r'ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|'
+      r'v(?:ar|oid)|w(?:hile|ith))';
+  // Mathces a public identifier (identifier not starting with '_').
+  static const String publicIdentifierRE =
+      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$][\w$]*';
+  // Matches the names of declarable operators.
+  static const String operatorRE =
+      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>[>=]?|unary-)';
+
+  // Grammar:
+  //    symbol ::= qualifiedName | <empty>
+  //    qualifiedName ::= publicIdentifier '.' qualifiedName | name
+  //    name ::= publicIdentifier
+  //           | publicIdentifier '='
+  //           | operator
+  // where publicIdentifier is any valid identifier (not a reserved word)
+  // that isn't private (doesn't start with '_').
+  //
+  // Railroad diagram of the accepted grammar:
+  //
+  //    /----------------\
+  //    |                |
+  //    |          /-[.]-/     /-[=]-\
+  //    \         /           /       \
+  //  -------[id]------------------------->
+  //       \                     /
+  //        \------[operator]---/
+  //            \              /
+  //             \------------/
+  //
+
+  // Validates non-empty symbol (empty symbol is handled before using this).
+  static final RegExp validationPattern = new RegExp(
+      '^(?:$operatorRE\$|$publicIdentifierRE(?:=?\$|[.](?!\$)))+?\$');
 
   external const Symbol(String name);
 
@@ -64,14 +79,14 @@
   static String getName(Symbol symbol) => symbol._name;
 
   static String validate(String name) {
-    if (name.isEmpty) return name;
+    if (name.isEmpty || validationPattern.hasMatch(name)) return name;
     if (name.startsWith('_')) {
+      // There may be other private parts in a qualified name than the first
+      // one, but this is a common case that deserves a specific error
+      // message.
       throw new ArgumentError('"$name" is a private identifier');
     }
-    if (!validationPattern.hasMatch(name)) {
-      throw new ArgumentError(
-          '"$name" is not an identifier or an empty String');
-    }
-    return name;
+    throw new ArgumentError(
+        '"$name" is not a valid (qualified) symbol name');
   }
 }
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index c23307f..e977d2f 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -6,6 +6,110 @@
 
 /**
  * A reference to a directory (or _folder_) on the file system.
+ *
+ * A Directory instance is an object holding a [path] on which operations can
+ * be performed. The path to the directory can be [absolute] or [relative].
+ * You can get the parent directory using the getter [parent],
+ * a property inherited from [FileSystemEntity].
+ *
+ * In addition to being used as an instance to access the file system,
+ * Directory has a number of static properties, such as [systemTemp],
+ * which gets the system's temporary directory, and the getter and setter
+ * [current], which you can use to access or change the current directory.
+ *
+ * Create a new Directory object with a pathname to access the specified
+ * directory on the file system from your program.
+ *
+ *     var myDir = new Directory('myDir');
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [create] and [createSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * ## Create a directory
+ *
+ * The following code sample creates a directory using the [create] method.
+ * By setting the `recursive` parameter to true, you can create the
+ * named directory and all its necessary parent directories,
+ * if they do not already exist.
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       // Creates dir/ and dir/subdir/.
+ *       new Directory('dir/subdir').create(recursive: true)
+ *         // The created directory is returned as a Future.
+ *         .then((Directory directory) {
+ *           print(directory.path);
+ *       });
+ *     }
+ * 
+ * ## List a directory
+ *
+ * Use the [list] or [listSync] methods to get the files and directories
+ * contained by a directory.
+ * Set `recursive` to true to recursively list all subdirectories.
+ * Set `followLinks` to true to follow symbolic links.
+ * The list method returns a [Stream] that provides FileSystemEntity
+ * objects. Use the listen callback function to process each object
+ * as it become available.
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       // Get the system temp directory.
+ *       var systemTempDir = Directory.systemTemp;
+ *
+ *       // List directory contents, recursing into sub-directories,
+ *       // but not following symbolic links.
+ *       systemTempDir.list(recursive: true, followLinks: false)
+ *         .listen((FileSystemEntity entity) {
+ *           print(entity.path);
+ *         });
+ *     }
+ *
+ * ## The use of Futures
+ *
+ * I/O operations can block a program for some period of time while it waits for
+ * the operation to complete. To avoid this, all
+ * methods involving I/O have an asynchronous variant which returns a [Future].
+ * This future completes when the I/O operation finishes. While the I/O
+ * operation is in progress, the Dart program is not blocked,
+ * and can perform other operations.
+ *
+ * For example,
+ * the [exists] method, which determines whether the directory exists,
+ * returns a boolean value using a Future.
+ * Use `then` to register a callback function, which is called when
+ * the value is ready.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       final myDir = new Directory('dir');
+ *       myDir.exists().then((isThere) {
+ *         isThere ? print('exists') : print('non-existent');
+ *       });
+ *     }
+ *
+ *
+ * In addition to exists, the [stat], [rename], and
+ * other methods, return Futures.
+ *
+ * ## 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.
+ *
+ * * [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.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ * a tutorial about writing command-line apps, includes information
+ * about files and directories.
  */
 abstract class Directory extends FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 9bf6632..b8df149 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -5,45 +5,173 @@
 part of dart.io;
 
 /**
- * FileMode describes the modes in which a file can be opened.
+ * The modes in which a File can be opened.
  */
 class FileMode {
-  /// The [FileMode] for opening a file only for reading.
+  /// The mode for opening a file only for reading.
   static const READ = const FileMode._internal(0);
-  /// The [FileMode] for opening a file for reading and writing. The file will
-  /// be overwritten. If the file does not exist, it will be created.
+  /// The mode for opening a file for reading and writing. The file is
+  /// overwritten if it already exists. The file is created if it does not
+  /// already exist.
   static const WRITE = const FileMode._internal(1);
-  /// The [FileMode] for opening a file for reading a file and writing to the
-  /// end of it. If the file does not exist, it will be created.
+  /// The mode for opening a file for reading and writing to the
+  /// end of it. The file is created if it does not already exist.
   static const APPEND = const FileMode._internal(2);
   final int _mode;
 
   const FileMode._internal(this._mode);
 }
 
-/// The [FileMode] for opening a file only for reading.
+/// The mode for opening a file only for reading.
 const READ = FileMode.READ;
-/// The [FileMode] for opening a file for reading and writing. The file will be
-/// overwritten. If the file does not exist, it will be created.
+/// The mode for opening a file for reading and writing. The file is
+/// overwritten if it already exists. The file is created if it does not
+/// already exist.
 const WRITE = FileMode.WRITE;
-/// The [FileMode] for opening a file for reading a file and writing to the end
-/// of it. If the file does not exist, it will be created.
+/// The mode for opening a file for reading and writing to the
+/// end of it. The file is created if it does not already exist.
 const APPEND = FileMode.APPEND;
 
 /**
  * A reference to a file on the file system.
  *
- * If [path] is a symbolic link, rather than a file, then
- * the methods of [File] operate on the ultimate target of the
- * link, except for File.delete and File.deleteSync, which operate on
+ * A File instance is an object that holds a [path] on which operations can
+ * be performed.
+ * You can get the parent directory of the file using the getter [parent],
+ * a property inherited from [FileSystemEntity].
+ *
+ * Create a new File object with a pathname to access the specified file on the
+ * file system from your program.
+ *
+ *     var myFile = new File('file.txt');
+ *
+ * The File class contains methods for manipulating files and their contents.
+ * Using methods in this class, you can open and close files, read to and write
+ * from them, create and delete them, and check for their existence.
+ *
+ * When reading or writing a file, you can use streams (with [openRead]),
+ * random access operations (with [open]),
+ * or convenience methods such as [readAsString],
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [readAsString] and [readAsStringSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * ## If path is a link
+ *
+ * If [path] is a symbolic link, rather than a file,
+ * then the methods of File operate on the ultimate target of the
+ * link, except for [delete] and [deleteSync], which operate on
  * the link.
  *
- * To operate on the underlying file data there are two options:
+ * ## Read from a file
  *
- *  * Use streaming: read the contents of the file from the [Stream]
- *    this.[openRead]() and write to the file by writing to the [IOSink]
- *    this.[openWrite]().
- *  * Open the file for random access operations using [open].
+ * The following code sample reads the entire contents from a file as a string
+ * using the asynchronous [readAsString] method:
+ *
+ *     import 'dart:async';
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       new File('file.txt').readAsString().then((String contents) {
+ *         print(contents);
+ *       });
+ *     }
+ *
+ * A more flexible and useful way to read a file is with a [Stream].
+ * Open the file with [openRead], which returns a stream that
+ * provides the data in the file as chunks of bytes.
+ * Listen to the stream for data and process as needed.
+ * You can use various transformers in succession to manipulate the
+ * data into the required format or to prepare it for output.
+ *
+ * You might want to use a stream to read large files,
+ * to manipulate the data with tranformers,
+ * or for compatibility with another API, such as [WebSocket]s.
+ * 
+ *     import 'dart:io';
+ *     import 'dart:convert';
+ *     import 'dart:async';
+ *
+ *     main() {
+ *       final file = new File('file.txt');
+ *       Stream<List<int>> inputStream = file.openRead();
+ *
+ *       inputStream
+ *         .transform(UTF8.decoder)       // Decode bytes to UTF8.
+ *         .transform(new LineSplitter()) // Convert stream to individual lines.
+ *         .listen((String line) {        // Process results.
+ *             print('$line: ${line.length} bytes');
+ *           },
+ *           onDone: () { print('File is now closed.'); },
+ *           onError: (e) { print(e.toString()); });
+ *     }
+ *
+ * ## Write to a file
+ *
+ * To write a string to a file, use the [writeAsString] method:
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       final filename = 'file.txt';
+ *       new File(filename).writeAsString('some content')
+ *         .then((File file) {
+ *           // Do something with the file.
+ *         });
+ *     }
+ *
+ * You can also write to a file using a [Stream]. Open the file with
+ * [openWrite], which returns a stream to which you can write data.
+ * Be sure to close the file with the [close] method.
+ *
+ *     import 'dart:io';
+ *    
+ *     void main() {
+ *       var file = new File('file.txt');
+ *       var sink = file.openWrite();
+ *       sink.write('FILE ACCESSED ${new DateTime.now()}\n');
+ *
+ *       // Close the IOSink to free system resources.
+ *       sink.close();
+ *     }
+ *
+ * ## The use of Futures
+ *
+ * To avoid unintentional blocking of the program,
+ * several methods use a [Future] to return a value. For example,
+ * the [length] method, which gets the length of a file, returns a Future.
+ * Use `then` to register a callback function, which is called when
+ * the value is ready.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       final file = new File('file.txt');
+ *     
+ *       file.length().then((len) {
+ *         print(len);
+ *       });
+ *     }
+ *
+ * In addition to length, the [exists], [lastModified], [stat], and
+ * other methods, return Futures.
+ *
+ * ## 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.
+ *
+ * * [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.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ * a tutorial about writing command-line apps, includes information
+ * about files and directories.
+
  */
 abstract class File extends FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index c30d8ae..dfa75f6 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -190,23 +190,26 @@
     Completer<File> completer = new Completer<File>();
     _openFuture
       .then((openedFile) {
+        void error(e, [StackTrace stackTrace]) {
+          _subscription.cancel();
+          openedFile.close();
+          completer.completeError(e, stackTrace);
+        }
         _subscription = stream.listen(
           (d) {
             _subscription.pause();
-            openedFile.writeFrom(d, 0, d.length)
-              .then((_) => _subscription.resume())
-              .catchError((e) {
-                openedFile.close();
-                completer.completeError(e);
-              });
+            try {
+              openedFile.writeFrom(d, 0, d.length)
+                .then((_) => _subscription.resume(),
+                      onError: error);
+            } catch (e, stackTrace) {
+              error(e, stackTrace);
+            }
           },
           onDone: () {
             completer.complete(_file);
           },
-          onError: (e, [StackTrace stackTrace]) {
-            openedFile.close();
-            completer.completeError(e, stackTrace);
-          },
+          onError: error,
           cancelOnError: true);
       })
       .catchError((e) {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 9a657a1..4b8950f 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -4,6 +4,14 @@
 
 part of dart.io;
 
+/**
+ * The type of an entity on the file system, such as a file, directory, or link.
+ *
+ * These constants are used by the [FileSystemEntity] class
+ * to indicate the object's type.
+ *
+ */
+
 class FileSystemEntityType {
   static const FILE = const FileSystemEntityType._internal(0);
   static const DIRECTORY = const FileSystemEntityType._internal(1);
@@ -164,14 +172,44 @@
 
 
 /**
- * A [FileSystemEntity] is a common super class for [File] and
- * [Directory] objects.
+ * The common super class for [File], [Directory], and [Link] objects.
  *
  * [FileSystemEntity] objects are returned from directory listing
- * operations. To determine if a FileSystemEntity is a [File] or a
- * [Directory], perform a type check:
+ * operations. To determine if a FileSystemEntity is a [File], a
+ * [Directory], or a [Link] perform a type check:
  *
  *     if (entity is File) (entity as File).readAsStringSync();
+ *
+ * You can also use the [type] or [typeSync] methods to determine
+ * the type of a file system object.
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [exists] and [existsSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * Here's the exists method in action:
+ *
+ *     entity.exists().then((isThere) {
+ *       isThere ? print('exists') : print('non-existent');
+ *     });
+ *
+ *
+ * ## 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.
+ *
+ * * [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.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ * 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 6ba35c7..818a37a 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -84,8 +84,7 @@
 abstract class HttpServer implements Stream<HttpRequest> {
   /**
    * Set and get the default value of the `Server` header for all responses
-   * generated by this [HttpServer]. The default value is
-   * `Dart/<version> (dart:io)`.
+   * generated by this [HttpServer]. By default, it's disabled.
    *
    * If the serverHeader is set to `null`, no default `Server` header will be
    * added to each response.
@@ -99,6 +98,9 @@
    *
    * Default is 120 seconds.
    *
+   * Note that it may take up to `2 * idleTimeout` before a idle connection is
+   * aborted.
+   *
    * To disable, set [idleTimeout] to `null`.
    */
   Duration idleTimeout;
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 0be5c08..85706d1 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -396,25 +396,31 @@
     }
 
     // Format headers.
-    _headers.forEach((String name, List<String> values) {
+    for (String name in _headers.keys) {
+      List<String> values = _headers[name];
       bool fold = _foldHeader(name);
       var nameData = name.codeUnits;
       write(nameData);
-      write(const [_CharCode.COLON, _CharCode.SP]);
+      buffer[offset++] = _CharCode.COLON;
+      buffer[offset++] = _CharCode.SP;
       for (int i = 0; i < values.length; i++) {
         if (i > 0) {
           if (fold) {
-            write(const [_CharCode.COMMA, _CharCode.SP]);
+            buffer[offset++] = _CharCode.COMMA;
+            buffer[offset++] = _CharCode.SP;
           } else {
-            write(const [_CharCode.CR, _CharCode.LF]);
+            buffer[offset++] = _CharCode.CR;
+            buffer[offset++] = _CharCode.LF;
             write(nameData);
-            write(const [_CharCode.COLON, _CharCode.SP]);
+            buffer[offset++] = _CharCode.COLON;
+            buffer[offset++] = _CharCode.SP;
           }
         }
         write(values[i].codeUnits);
       }
-      write(const [_CharCode.CR, _CharCode.LF]);
-    });
+      buffer[offset++] = _CharCode.CR;
+      buffer[offset++] = _CharCode.LF;
+    }
     return offset;
   }
 
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 2f852dc..5bc5b97 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1246,7 +1246,7 @@
   _HttpClientConnection(this.key, this._socket, this._httpClient,
                         [this._proxyTunnel = false])
       : _httpParser = new _HttpParser.responseParser() {
-    _socket.pipe(_httpParser);
+    _httpParser.listenToStream(_socket);
 
     // Set up handlers on the parser here, so we are sure to get 'onDone' from
     // the parser.
@@ -1333,7 +1333,7 @@
     }
     // Start sending the request (lazy, delayed until the user provides
     // data).
-    _httpParser.responseToMethod = method;
+    _httpParser.isHead = method == "HEAD";
     _streamFuture = outgoing.done
         .then((s) {
           // Request sent, set up response completer.
@@ -1343,8 +1343,9 @@
           _nextResponseCompleter.future
               .then((incoming) {
                 _currentUri = null;
-                incoming.dataDone.then((_) {
-                  if (!_dispose &&
+                incoming.dataDone.then((closing) {
+                  if (!closing &&
+                      !_dispose &&
                       incoming.headers.persistentConnection &&
                       request.persistentConnection) {
                     // Return connection, now we are done.
@@ -1894,24 +1895,22 @@
   static const _CLOSING = 2;
   static const _DETACHED = 3;
 
-  int _state = _IDLE;
-
   final Socket _socket;
   final _HttpServer _httpServer;
   final _HttpParser _httpParser;
+  int _state = _IDLE;
   StreamSubscription _subscription;
   Timer _idleTimer;
   final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE);
-
+  bool _idleMark = false;
   Future _streamFuture;
 
   _HttpConnection(this._socket, this._httpServer)
       : _httpParser = new _HttpParser.requestParser() {
-    _startTimeout();
-    _socket.pipe(_httpParser);
+    _httpParser.listenToStream(_socket);
     _subscription = _httpParser.listen(
         (incoming) {
-          _stopTimeout();
+          _httpServer._markActive(this);
           // If the incoming was closed, close the connection.
           incoming.dataDone.then((closing) {
             if (closing) destroy();
@@ -1936,7 +1935,8 @@
                     !_httpParser.upgrade &&
                     !_httpServer.closed) {
                   _state = _IDLE;
-                  _startTimeout();
+                  _idleMark = false;
+                  _httpServer._markIdle(this);
                   // Resume the subscription for incoming requests as the
                   // request is now processed.
                   _subscription.resume();
@@ -1945,8 +1945,7 @@
                   // received data was handled.
                   destroy();
                 }
-              })
-              .catchError((e) {
+              }, onError: (_) {
                 destroy();
               });
           response._ignoreBody = request.method == "HEAD";
@@ -1962,21 +1961,13 @@
         });
   }
 
-  void _startTimeout() {
-    assert(_state == _IDLE);
-    _stopTimeout();
-    if (_httpServer.idleTimeout == null) return;
-    _idleTimer = new Timer(_httpServer.idleTimeout, () {
-      destroy();
-    });
+  void markIdle() {
+    _idleMark = true;
   }
 
-  void _stopTimeout() {
-    if (_idleTimer != null) _idleTimer.cancel();
-  }
+  bool get isMarkedIdle => _idleMark;
 
   void destroy() {
-    _stopTimeout();
     if (_state == _CLOSING || _state == _DETACHED) return;
     _state = _CLOSING;
     _socket.destroy();
@@ -1984,7 +1975,6 @@
   }
 
   Future<Socket> detachSocket() {
-    _stopTimeout();
     _state = _DETACHED;
     // Remove connection from server.
     _httpServer._connectionClosed(this);
@@ -2007,9 +1997,10 @@
 
 // HTTP server waiting for socket connections.
 class _HttpServer extends Stream<HttpRequest> implements HttpServer {
-  String serverHeader = _getHttpVersion();
+  String serverHeader;
 
-  Duration idleTimeout = const Duration(seconds: 120);
+  Duration _idleTimeout;
+  Timer _idleTimer;
 
   static Future<HttpServer> bind(address, int port, int backlog) {
     return ServerSocket.bind(address, port, backlog: backlog).then((socket) {
@@ -2036,11 +2027,34 @@
   _HttpServer._(this._serverSocket, this._closeServer) {
     _controller = new StreamController<HttpRequest>(sync: true,
                                                     onCancel: close);
+    idleTimeout = const Duration(seconds: 120);
   }
 
   _HttpServer.listenOn(this._serverSocket) : _closeServer = false {
     _controller = new StreamController<HttpRequest>(sync: true,
                                                     onCancel: close);
+    idleTimeout = const Duration(seconds: 120);
+  }
+
+  Duration get idleTimeout => _idleTimeout;
+
+  void set idleTimeout(Duration duration) {
+    if (_idleTimer != null) {
+      _idleTimer.cancel();
+      _idleTimer = null;
+    }
+    _idleTimeout = duration;
+    if (_idleTimeout != null) {
+      _idleTimer = new Timer.periodic(_idleTimeout, (_) {
+        for (var idle in _idleConnections.toList()) {
+          if (idle.isMarkedIdle) {
+            idle.destroy();
+          } else {
+            idle.markIdle();
+          }
+        }
+      });
+    }
   }
 
   StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
@@ -2052,7 +2066,7 @@
           socket.setOption(SocketOption.TCP_NODELAY, true);
           // Accept the client connection.
           _HttpConnection connection = new _HttpConnection(socket, this);
-          _connections.add(connection);
+          _idleConnections.add(connection);
         },
         onError: (error) {
           // Ignore HandshakeExceptions as they are bound to a single request,
@@ -2076,15 +2090,15 @@
     } else {
       result = new Future.value();
     }
+    idleTimeout = null;
     if (force) {
-      for (var c in _connections.toList()) {
+      for (var c in _activeConnections.toList()) {
         c.destroy();
       }
-      assert(_connections.isEmpty);
-    } else {
-      for (var c in _connections.where((c) => c._isIdle).toList()) {
-        c.destroy();
-      }
+      assert(_activeConnections.isEmpty);
+    }
+    for (var c in _idleConnections.toList()) {
+      c.destroy();
     }
     _maybeCloseSessionManager();
     return result;
@@ -2092,7 +2106,8 @@
 
   void _maybeCloseSessionManager() {
     if (closed &&
-        _connections.isEmpty &&
+        _idleConnections.isEmpty &&
+        _activeConnections.isEmpty &&
         _sessionManagerInstance != null) {
       _sessionManagerInstance.close();
       _sessionManagerInstance = null;
@@ -2120,10 +2135,21 @@
   }
 
   void _connectionClosed(_HttpConnection connection) {
-    _connections.remove(connection);
+    // Remove itself from either idle or active connections.
+    connection.unlink();
     _maybeCloseSessionManager();
   }
 
+  void _markIdle(_HttpConnection connection) {
+    _activeConnections.remove(connection);
+    _idleConnections.add(connection);
+  }
+
+  void _markActive(_HttpConnection connection) {
+    _idleConnections.remove(connection);
+    _activeConnections.add(connection);
+  }
+
   _HttpSessionManager get _sessionManager {
     // Lazy init.
     if (_sessionManagerInstance == null) {
@@ -2134,17 +2160,19 @@
 
   HttpConnectionsInfo connectionsInfo() {
     HttpConnectionsInfo result = new HttpConnectionsInfo();
-    result.total = _connections.length;
-    _connections.forEach((_HttpConnection conn) {
+    result.total = _activeConnections.length + _idleConnections.length;
+    _activeConnections.forEach((_HttpConnection conn) {
       if (conn._isActive) {
         result.active++;
-      } else if (conn._isIdle) {
-        result.idle++;
       } else {
         assert(conn._isClosing);
         result.closing++;
       }
     });
+    _idleConnections.forEach((_HttpConnection conn) {
+      result.idle++;
+      assert(conn._isIdle);
+    });
     return result;
   }
 
@@ -2159,10 +2187,11 @@
   final bool _closeServer;
 
   // Set of currently connected clients.
-  final LinkedList<_HttpConnection> _connections
+  final LinkedList<_HttpConnection> _activeConnections
+      = new LinkedList<_HttpConnection>();
+  final LinkedList<_HttpConnection> _idleConnections
       = new LinkedList<_HttpConnection>();
   StreamController<HttpRequest> _controller;
-  // TODO(ajohnsen): Use close queue?
 }
 
 
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index 56b3e4c..2888138 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -234,9 +234,7 @@
  * and should be handled according to whatever protocol is being
  * upgraded to.
  */
-class _HttpParser
-    extends Stream<_HttpIncoming>
-    implements StreamConsumer<List<int>> {
+class _HttpParser extends Stream<_HttpIncoming> {
   // State.
   bool _parserCalled = false;
 
@@ -249,10 +247,11 @@
   int _httpVersionIndex;
   int _messageType;
   int _statusCode = 0;
-  List _method_or_status_code;
-  List _uri_or_reason_phrase;
-  List _headerField;
-  List _headerValue;
+  int _statusCodeLength = 0;
+  final List<int> _method = [];
+  final List<int> _uri_or_reason_phrase = [];
+  final List<int> _headerField = [];
+  final List<int> _headerValue = [];
 
   int _httpVersion;
   int _transferLength = -1;
@@ -260,8 +259,7 @@
   bool _connectionUpgrade;
   bool _chunked;
 
-  bool _noMessageBody;
-  String _responseToMethod;  // Indicates the method used for the request.
+  bool _noMessageBody = false;
   int _remainingContent = -1;
 
   _HttpHeaders _headers;
@@ -286,7 +284,6 @@
     _controller = new StreamController<_HttpIncoming>(
         sync: true,
         onListen: () {
-          _socketSubscription.resume();
           _paused = false;
         },
         onPause: () {
@@ -316,26 +313,16 @@
                                      cancelOnError: cancelOnError);
   }
 
-  Future<_HttpParser> addStream(Stream<List<int>> stream) {
+  void listenToStream(Stream<List<int>> stream) {
     // Listen to the stream and handle data accordingly. When a
     // _HttpIncoming is created, _dataPause, _dataResume, _dataDone is
     // given to provide a way of controlling the parser.
     // TODO(ajohnsen): Remove _dataPause, _dataResume and _dataDone and clean up
     // how the _HttpIncoming signals the parser.
-    var completer = new Completer();
     _socketSubscription = stream.listen(
         _onData,
         onError: _onError,
-        onDone: () {
-          completer.complete(this);
-        });
-    _socketSubscription.pause();
-    return completer.future;
-  }
-
-  Future<_HttpParser> close() {
-    _onDone();
-    return new Future.value(this);
+        onDone: _onDone);
   }
 
   void _parse() {
@@ -387,7 +374,7 @@
             if (!_isTokenChar(byte)) {
               throw new HttpException("Invalid request method");
             }
-            _method_or_status_code.add(byte);
+            _method.add(byte);
             if (!_requestParser) {
               throw new HttpException("Invalid response line");
             }
@@ -412,12 +399,12 @@
           } else {
             // Did not parse HTTP version. Expect method instead.
             for (int i = 0; i < _httpVersionIndex; i++) {
-              _method_or_status_code.add(_Const.HTTP[i]);
+              _method.add(_Const.HTTP[i]);
             }
             if (byte == _CharCode.SP) {
               _state = _State.REQUEST_LINE_URI;
             } else {
-              _method_or_status_code.add(byte);
+              _method.add(byte);
               _httpVersion = _HttpVersion.UNDETERMINED;
               if (!_requestParser) {
                 throw new HttpException("Invalid response line");
@@ -462,7 +449,7 @@
                 byte == _CharCode.LF) {
               throw new HttpException("Invalid request method");
             }
-            _method_or_status_code.add(byte);
+            _method.add(byte);
           }
           break;
 
@@ -513,19 +500,17 @@
 
         case _State.RESPONSE_LINE_STATUS_CODE:
           if (byte == _CharCode.SP) {
-            if (_method_or_status_code.length != 3) {
-              throw new HttpException("Invalid response status code");
-            }
             _state = _State.RESPONSE_LINE_REASON_PHRASE;
           } else if (byte == _CharCode.CR) {
             // Some HTTP servers does not follow the spec. and send
             // \r\n right after the status code.
             _state = _State.RESPONSE_LINE_ENDING;
           } else {
-            if (byte < 0x30 && 0x39 < byte) {
+            _statusCodeLength++;
+            if ((byte < 0x30 && 0x39 < byte) || _statusCodeLength > 3) {
               throw new HttpException("Invalid response status code");
             } else {
-              _method_or_status_code.add(byte);
+              _statusCode = _statusCode * 10 + byte - 0x30;
             }
           }
           break;
@@ -544,14 +529,14 @@
         case _State.RESPONSE_LINE_ENDING:
           _expect(byte, _CharCode.LF);
           _messageType == _MessageType.RESPONSE;
-          _statusCode = int.parse(
-              new String.fromCharCodes(_method_or_status_code));
           if (_statusCode < 100 || _statusCode > 599) {
             throw new HttpException("Invalid response status code");
           } else {
             // Check whether this response will never have a body.
-            _noMessageBody = _statusCode <= 199 || _statusCode == 204 ||
-                _statusCode == 304;
+            if (_statusCode <= 199 || _statusCode == 204 ||
+                _statusCode == 304) {
+              _noMessageBody = true;
+            }
           }
           _state = _State.HEADER_START;
           break;
@@ -608,13 +593,14 @@
             String headerField = new String.fromCharCodes(_headerField);
             String headerValue = new String.fromCharCodes(_headerValue);
             if (headerField == "transfer-encoding" &&
-                       headerValue.toLowerCase() == "chunked") {
+                _caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
               _chunked = true;
             }
             if (headerField == "connection") {
               List<String> tokens = _tokenizeFieldValue(headerValue);
               for (int i = 0; i < tokens.length; i++) {
-                if (tokens[i].toLowerCase() == "upgrade") {
+                if (_caseInsensitiveCompare("upgrade".codeUnits,
+                                            tokens[i].codeUnits)) {
                   _connectionUpgrade = true;
                 }
                 _headers._add(headerField, tokens[i]);
@@ -659,7 +645,7 @@
           _createIncoming(_transferLength);
           if (_requestParser) {
             _incoming.method =
-                new String.fromCharCodes(_method_or_status_code);
+                new String.fromCharCodes(_method);
             _incoming.uri =
                 Uri.parse(
                     new String.fromCharCodes(_uri_or_reason_phrase));
@@ -668,7 +654,7 @@
             _incoming.reasonPhrase =
                 new String.fromCharCodes(_uri_or_reason_phrase);
           }
-          _method_or_status_code.clear();
+          _method.clear();
           _uri_or_reason_phrase.clear();
           if (_connectionUpgrade) {
             _incoming.upgraded = true;
@@ -679,8 +665,7 @@
             return;
           }
           if (_transferLength == 0 ||
-              (_messageType == _MessageType.RESPONSE &&
-               (_noMessageBody || _responseToMethod == "HEAD"))) {
+              (_messageType == _MessageType.RESPONSE && _noMessageBody)) {
             _reset();
             var tmp = _incoming;
             _closeIncoming();
@@ -752,21 +737,15 @@
           // The body is not handled one byte at a time but in blocks.
           _index--;
           int dataAvailable = _buffer.length - _index;
-          List<int> data;
-          if (_remainingContent == -1 ||
-              dataAvailable <= _remainingContent) {
-            if (_index == 0) {
-              data = _buffer;
-            } else {
-              data = new Uint8List.view(_buffer.buffer,
-                                        _index,
-                                        dataAvailable);
-            }
-          } else {
-            data = new Uint8List.view(_buffer.buffer,
-                                      _index,
-                                      _remainingContent);
+          if (_remainingContent >= 0 && dataAvailable > _remainingContent) {
+            dataAvailable = _remainingContent;
           }
+          // Always present the data as a view. This way we can handle all
+          // cases like this, and the user will not experince different data
+          // typed (which could lead to polymorphic user code).
+          List<int> data = new Uint8List.view(_buffer.buffer,
+                                              _buffer.offsetInBytes + _index,
+                                              dataAvailable);
           _bodyController.add(data);
           if (_remainingContent != -1) {
             _remainingContent -= data.length;
@@ -885,7 +864,9 @@
   bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED;
   bool get persistentConnection => _persistentConnection;
 
-  void set responseToMethod(String method) { _responseToMethod = method; }
+  void set isHead(bool value) {
+    if (value) _noMessageBody = true;
+  }
 
   _HttpDetachedIncoming detachIncoming() {
     // Simulate detached by marking as upgraded.
@@ -906,12 +887,13 @@
     if (_state == _State.UPGRADED) return;
     _state = _State.START;
     _messageType = _MessageType.UNDETERMINED;
-    _headerField = new List();
-    _headerValue = new List();
-    _method_or_status_code = new List();
-    _uri_or_reason_phrase = new List();
+    _headerField.clear();
+    _headerValue.clear();
+    _method.clear();
+    _uri_or_reason_phrase.clear();
 
     _statusCode = 0;
+    _statusCodeLength = 0;
 
     _httpVersion = _HttpVersion.UNDETERMINED;
     _transferLength = -1;
@@ -920,7 +902,6 @@
     _chunked = false;
 
     _noMessageBody = false;
-    _responseToMethod = null;
     _remainingContent = -1;
 
     _headers = null;
@@ -959,6 +940,15 @@
     return (aCode <= byte && byte <= zCode) ? byte + delta : byte;
   }
 
+  // expected should already be lowercase.
+  bool _caseInsensitiveCompare(List<int> expected, List<int> value) {
+    if (expected.length != value.length) return false;
+    for (int i = 0; i < expected.length; i++) {
+      if (expected[i] != _toLowerCase(value[i])) return false;
+    }
+    return true;
+  }
+
   int _expect(int val1, int val2) {
     if (val1 != val2) {
       throw new HttpException("Failed to parse HTTP");
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index f58d567..d6109a2 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -5,8 +5,65 @@
 part of dart.io;
 
 /**
- * The [Platform] class exposes details of the machine and operating
- * system.
+ * Information about the environment in which the current program is running.
+ *
+ * Platform provides information such as the operating system,
+ * the hostname of the computer, the value of environment variables,
+ * the path to the running program,
+ * and so on.
+ *
+ * ## Get the URI to the current Dart script
+ *
+ * Use the [script] getter to get the URI to the currently running
+ * Dart script.
+ *
+ *     import 'dart:io' show Platform;
+ *
+ *     void main() {
+ *       // Get the URI of the script being run.
+ *       var uri = Platform.script;
+ *       // Convert the URI to a path.
+ *       var path = uri.toFilePath();
+ *     }
+ *
+ * ## Get the value of an environment variable
+ *
+ * The [environment] getter returns a the names and values of environment
+ * variables in a [Map] that contains key-value pairs of strings. The Map is
+ * unmodifiable. This sample shows how to get the value of the `PATH`
+ * environment variable.
+ *
+ *     import 'dart:io' show Platform;
+ *
+ *     void main() {
+ *       Map<String, String> envVars = Platform.environment;
+ *       print(envVars['PATH']);
+ *     }
+ * 
+ * ## Determine the OS
+ *
+ * You can get the name of the operating system as a string with the
+ * [operatingSystem] getter. You can also use one of the static boolean
+ * getters: [isMacOS], [isLinux], and [isWindows].
+ *
+ *     import 'dart:io' show Platform, stdout;
+ *
+ *     void main() {
+ *       // Get the operating system as a string.
+ *       String os = Platform.operatingSystem;
+ *       // Or, use a predicate getter.
+ *       if (Platform.isMacOS) {
+ *         Print('is a Mac'); 
+ *       } else {
+ *        print('is not a Mac');
+ *       }
+ *     }
+ *
+ * ## Other resources
+ *
+ * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
+ * provides additional task-oriented code samples that show how to use 
+ * various API from the [dart:io] library.
  */
 class Platform {
   static final _numberOfProcessors = _Platform.numberOfProcessors;
@@ -63,7 +120,7 @@
   /**
    * Get the environment for this process.
    *
-   * The returned environment is a unmodifiable map which content is
+   * The returned environment is an unmodifiable map which content is
    * retrieved from the operating system on its first use.
    *
    * Environment variables on Windows are case-insensitive. The map
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 0cf7126..828145e 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -85,8 +85,97 @@
 int get pid => _ProcessUtils._pid(null);
 
 /**
- * [Process] is used to start new processes using the static
- * [start] and [run] methods.
+ * The means to execute a program.
+ * 
+ * Use the static [start] and [run] methods to start a new process.
+ * The run method executes the process non-interactively to completion.
+ * In contrast, the start method allows your code to interact with the
+ * running process.
+ *
+ * ## Start a process with the run method
+ *
+ * The following code sample uses the run method to create a process
+ * that runs the UNIX command `ls`, which lists the contents of a directory.
+ * The run method completes with a [ProcessResult] object when the process
+ * terminates. This provides access to the output and exit code from the
+ * process. The run method does not return a Process object; this prevents your
+ * code from interacting with the running process.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       // List all files in the current directory in UNIX-like systems.
+ *       Process.run('ls', ['-l']).then((ProcessResult results) {
+ *         print(results.stdout);
+ *       });
+ *     }
+ *
+ * ## Start a process with the start method
+ *
+ * The following example uses start to create the process.
+ * The start method returns a [Future] for a Process object.
+ * When the future completes the process is started and
+ * your code can interact with the
+ * Process: writing to stdin, listening to stdout, and so on.
+ *
+ * The following sample starts the UNIX `cat` utility, which when given no
+ * command-line arguments, echos its input.
+ * The program writes to the process's standard input stream
+ * and prints data from its standard output stream.
+ *
+ *     import 'dart:io';
+ *     import 'dart:convert';
+ *
+ *     main() {
+ *       Process.start('cat', []).then((Process process) {
+ *         process.stdout
+ *             .transform(UTF8.decoder)
+ *             .listen((data) { print(data); });
+ *         process.stdin.writeln('Hello, world!');
+ *         process.stdin.writeln('Hello, galaxy!');
+ *         process.stdin.writeln('Hello, universe!');
+ *       });
+ *     }
+ *
+ * ## Standard I/O streams
+ * 
+ * As seen in the previous code sample, you can interact with the Process's
+ * standard output stream through the getter [stdout],
+ * and you can interact with the Process's standard input stream through 
+ * the getter [stdin].
+ * In addition, Process provides a getter [stderr] for using the Process's
+ * standard error stream.
+ *
+ * A Process's streams are distinct from the top-level streams
+ * for the current program.
+ *
+ * ## Exit codes
+ *
+ * Call the [exitCode] method to get the exit code of the process.
+ * The exit code indicates whether the program terminated successfully
+ * (usually indicated with an exit code of 0) or with an error.
+ *
+ * If the start method is used, the exitCode is available through a future
+ * on the Process object (as shown in the example below).
+ * If the run method is used, the exitCode is available
+ * through a getter on the ProcessResult instance.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       Process.start('ls', ['-l']).then((process) {
+ *         // Get the exit code from the new process.
+ *         process.exitCode.then((exitCode) {
+ *           print('exit code: $exitCode');
+ *         });
+ *       });
+ *     }
+ *
+ * ## Other resources
+ *
+ * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
+ * provides additional task-oriented code samples that show how to use 
+ * various API from the [dart:io] library.
  */
 abstract class Process {
   /**
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index b3c7063..b966c61 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -895,6 +895,7 @@
           _secureFilter = null;
           return;
         }
+        _socket.readEventsEnabled = true;
         if (_filterStatus.writeEmpty && _closedWrite && !_socketClosedWrite) {
           // Checks for and handles all cases of partially closed sockets.
           shutdown(SocketDirection.SEND);
@@ -948,6 +949,8 @@
     var buffer = _secureFilter.buffers[READ_ENCRYPTED];
     if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) {
       _filterStatus.readEmpty = false;
+    } else {
+      _socket.readEventsEnabled = false;
     }
   }
 
@@ -973,7 +976,8 @@
 
   _sendReadEvent() {
     _pendingReadEvent = false;
-    if (_readEventsEnabled &&
+    if (_status != CLOSED &&
+        _readEventsEnabled &&
         _pauseCount == 0 &&
         _secureFilter != null &&
         !_secureFilter.buffers[READ_PLAINTEXT].isEmpty) {
@@ -1167,7 +1171,7 @@
     while (toWrite > 0) {
       // Source returns at most toWrite bytes, and it returns null when empty.
       var inputData = getData(toWrite);
-      if (inputData == null) break;
+      if (inputData == null || inputData.length == 0) break;
       var len = inputData.length;
       data.setRange(end, end + len, inputData);
       advanceEnd(len);
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 5c1fa8f..5b5e62f 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -273,8 +273,12 @@
 StdioType stdioType(object) {
   if (object is _StdStream) {
     object = object._stream;
-  } else if (object is _StdSink) {
-    object = object._sink;
+  } else if (object == stdout || object == stderr) {
+    switch (_StdIOUtils._getStdioHandleType(object == stdout ? 1 : 2)) {
+      case _STDIO_HANDLE_TYPE_TERMINAL: return StdioType.TERMINAL;
+      case _STDIO_HANDLE_TYPE_PIPE: return StdioType.PIPE;
+      case _STDIO_HANDLE_TYPE_FILE:  return StdioType.FILE;
+    }
   }
   if (object is _FileStream) {
     return StdioType.FILE;
@@ -303,4 +307,5 @@
   external static _getStdioOutputStream(int fd);
   external static Stdin _getStdioInputStream();
   external static int _socketType(nativeSocket);
+  external static _getStdioHandleType(int fd);
 }
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index b169afa..ee56378 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -781,6 +781,7 @@
 
   int _outCloseCode;
   String _outCloseReason;
+  Timer _closeTimer;
 
   static final HttpClient _httpClient = new HttpClient();
 
@@ -879,6 +880,7 @@
           }
         },
         onError: (error) {
+          if (_closeTimer != null) _closeTimer.cancel();
           if (error is FormatException) {
             _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
           } else {
@@ -887,6 +889,7 @@
           _controller.close();
         },
         onDone: () {
+          if (_closeTimer != null) _closeTimer.cancel();
           if (_readyState == WebSocket.OPEN) {
             _readyState = WebSocket.CLOSING;
             if (!_isReservedStatusCode(transformer.closeCode)) {
@@ -957,6 +960,13 @@
       _outCloseCode = code;
       _outCloseReason = reason;
     }
+    if (_closeTimer == null && !_controller.isClosed) {
+      // When closing the web-socket, we no longer accept data.
+      _closeTimer = new Timer(const Duration(seconds: 5), () {
+        _subscription.cancel();
+        _controller.close();
+      });
+    }
     return _sink.close();
   }
 
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 4a5b50a..a8063a0 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -58,7 +58,8 @@
    * Returns a future that will complete with an [Isolate] instance if the
    * spawning succeeded. It will complete with an error otherwise.
    */
-  external static Future<Isolate> spawn(void entryPoint(message), var message);
+  external static Future<Isolate> spawn(void entryPoint(message), var message,
+                                        { bool paused: false });
 
   /**
    * Creates and spawns an isolate that runs the code from the library with
@@ -80,7 +81,7 @@
    * spawning succeeded. It will complete with an error otherwise.
    */
   external static Future<Isolate> spawnUri(
-      Uri uri, List<String> args, var message);
+      Uri uri, List<String> args, var message, { bool paused: false });
 
 
   /**
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 39b6c2a..54ac866 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -4,7 +4,7 @@
 
 /**
  * Support for interoperating with JavaScript.
- * 
+ *
  * This library provides access to JavaScript objects from Dart, allowing
  * Dart code to get and set properties, and call methods of JavaScript objects
  * and invoke JavaScript functions. The library takes care of converting
@@ -27,14 +27,14 @@
  * global function `alert()`:
  *
  *     import 'dart:js';
- *     
+ *
  *     main() => context.callMethod('alert', ['Hello from Dart!']);
  *
  * This example shows how to create a [JsObject] from a JavaScript constructor
  * and access its properties:
  *
  *     import 'dart:js';
- *     
+ *
  *     main() {
  *       var object = new JsObject(context['Object']);
  *       object['greeting'] = 'Hello';
@@ -44,7 +44,7 @@
  *     }
  *
  * ## Proxying and automatic conversion
- * 
+ *
  * When setting properties on a JsObject or passing arguments to a Javascript
  * method or function, Dart objects are automatically converted or proxied to
  * JavaScript objects. When accessing JavaScript properties, or when a Dart
@@ -80,7 +80,7 @@
  * `a` and `b` defined:
  *
  *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
- * 
+ *
  * This expression creates a JavaScript array:
  *
  *     var jsArray = new JsObject.jsify([1, 2, 3]);
@@ -166,7 +166,7 @@
    * Use this constructor only if you wish to get access to JavaScript
    * properties attached to a browser host object, such as a Node or Blob, that
    * is normally automatically converted into a native Dart object.
-   * 
+   *
    * An exception will be thrown if [object] either is `null` or has the type
    * `bool`, `num`, or `String`.
    */
@@ -233,7 +233,7 @@
     }
     return _convertToDart(JS('', '#[#]', _jsObject, property));
   }
-  
+
   /**
    * Sets the value associated with [property] on the proxied JavaScript
    * object.
@@ -411,7 +411,7 @@
   }
 
   void addAll(Iterable<E> iterable) {
-    var list = (JS('bool', '# instanceof Array', iterable)) 
+    var list = (JS('bool', '# instanceof Array', iterable))
         ? iterable
         : new List.from(iterable);
     callMethod('push', list);
@@ -483,6 +483,9 @@
 
 bool _isLocalObject(o) => JS('bool', '# instanceof Object', o);
 
+// The shared constructor function for proxies to Dart objects in JavaScript.
+final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }');
+
 dynamic _convertToJS(dynamic o) {
   if (o == null) {
     return null;
@@ -502,8 +505,9 @@
       return jsFunction;
     });
   } else {
+    var ctor = _dartProxyCtor;
     return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
-        (o) => JS('', 'new DartObject(#)', o));
+        (o) => JS('', 'new #(#)', ctor, o));
   }
 }
 
@@ -532,7 +536,7 @@
   } else if (JS('bool', '# instanceof Date', o)) {
     var ms = JS('num', '#.getMilliseconds()', o);
     return new DateTime.fromMillisecondsSinceEpoch(ms);
-  } else if (JS('bool', '#.constructor === DartObject', o)) {
+  } else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) {
     return JS('', '#.o', o);
   } else {
     return _wrapToDart(o);
diff --git a/sdk/lib/math/rectangle.dart b/sdk/lib/math/rectangle.dart
index 0673b0d..069f423 100644
--- a/sdk/lib/math/rectangle.dart
+++ b/sdk/lib/math/rectangle.dart
@@ -12,6 +12,10 @@
  *
  * See also:
  *    [W3C Coordinate Systems Specification](http://www.w3.org/TR/SVG/coords.html#InitialCoordinateSystem).
+ *
+ * The rectangle is the set of points with representable coordinates greater
+ * than or equal to left/top, and with distance to left/top no greater than
+ * width/height (to the limit of the precission of the coordinates).
  */
 abstract class _RectangleBase<T extends num> {
   const _RectangleBase();
@@ -20,9 +24,9 @@
   T get left;
   /** The y-coordinate of the top edge. */
   T get top;
-  /** The `width` of the rectangle. */
+  /** The width of the rectangle. */
   T get width;
-  /** The `height` of the rectangle. */
+  /** The height of the rectangle. */
   T get height;
 
   /** The x-coordinate of the right edge. */
@@ -130,8 +134,35 @@
   final T width;
   final T height;
 
-  const Rectangle(this.left, this.top, this.width, this.height);
+  /**
+   * Create a rectangle spanned by `(left, top)` and `(left+width, top+height)`.
+   *
+   * The rectangle contains the points
+   * with x-coordinate between `left` and `left + width`, and
+   * with y-coordiante between `top` and `top + height`, both inclusive.
+   *
+   * The `width` and `height` should be non-negative.
+   * If `width` or `height` are negative, they are clamped to zero.
+   *
+   * If `width` and `height` are zero, the "rectangle" comprises only the single
+   * point `(left, top)`.
+   */
+  const Rectangle(this.left, this.top, T width, T height)
+      : this.width = (width >= 0) ? width : -width * 0,  // Inline _clampToZero.
+        this.height = (height >= 0) ? height : -height * 0;
 
+  /*
+   * Create a rectangle spanned by the points [a] and [b];
+   *
+   * The rectangle contains the points
+   * with x-coordinate between `a.x` and `b.x`, and
+   * with y-coordiante between `a.y` and `b.y`, both inclusive.
+   *
+   * If the distance between `a.x` and `b.x` is not representable
+   * (which can happen if one or both is a double),
+   * the actual right edge might be slightly off from `max(a.x, b.x)`.
+   * Similar for the y-coordinates and the bottom edge.
+   */
   factory Rectangle.fromPoints(Point<T> a, Point<T> b) {
     T left = min(a.x, b.x);
     T width = max(a.x, b.x) - left;
@@ -145,15 +176,54 @@
  * A class for representing two-dimensional axis-aligned rectangles with mutable
  * properties.
  */
-class MutableRectangle<T extends num>  extends _RectangleBase<T>
-    implements Rectangle<T> {
+class MutableRectangle<T extends num> extends _RectangleBase<T>
+                                      implements Rectangle<T> {
+
+  /**
+   * The x-coordinate of the left edge.
+   *
+   * Setting the value will move the rectangle without changing its width.
+   */
   T left;
+  /**
+   * The y-coordinate of the left edge.
+   *
+   * Setting the value will move the rectangle without changing its height.
+   */
   T top;
-  T width;
-  T height;
+  T _width;
+  T _height;
 
-  MutableRectangle(this.left, this.top, this.width, this.height);
+  /**
+   * Create a mutable rectangle spanned by `(left, top)` and
+   * `(left+width, top+height)`.
+   *
+   * The rectangle contains the points
+   * with x-coordinate between `left` and `left + width`, and
+   * with y-coordiante between `top` and `top + height`, both inclusive.
+   *
+   * The `width` and `height` should be non-negative.
+   * If `width` or `height` are negative, they are clamped to zero.
+   *
+   * If `width` and `height` are zero, the "rectangle" comprises only the single
+   * point `(left, top)`.
+   */
+  MutableRectangle(this.left, this.top, T width, T height)
+      : this._width = (width >= 0) ? width : _clampToZero(width),
+        this._height = (height >= 0) ? height : _clampToZero(height);
 
+  /*
+   * Create a mutable rectangle spanned by the points [a] and [b];
+   *
+   * The rectangle contains the points
+   * with x-coordinate between `a.x` and `b.x`, and
+   * with y-coordiante between `a.y` and `b.y`, both inclusive.
+   *
+   * If the distance between `a.x` and `b.x` is not representable
+   * (which can happen if one or both is a double),
+   * the actual right edge might be slightly off from `max(a.x, b.x)`.
+   * Similar for the y-coordinates and the bottom edge.
+   */
   factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) {
     T left = min(a.x, b.x);
     T width = max(a.x, b.x) - left;
@@ -161,4 +231,46 @@
     T height = max(a.y, b.y) - top;
     return new MutableRectangle<T>(left, top, width, height);
   }
+
+  T get width => _width;
+
+ /**
+   * Sets the width of the rectangle.
+   *
+   * The width must be non-negative.
+   * If a negative width is supplied, it is clamped to zero.
+   *
+   * Setting the value will change the right edge of the rectangle,
+   * but will not change [left].
+   */
+  void set width(T width) {
+    if (width < 0) width = _clampToZero(width);
+    _width = width;
+  }
+
+  T get height => _height;
+
+  /**
+   * Sets the height of the rectangle.
+   *
+   * The height must be non-negative.
+   * If a negative height is supplied, it is clamped to zero.
+   *
+   * Setting the value will change the bottom edge of the rectangle,
+   * but will not change [top].
+   */
+  void set height(T height) {
+    if (height < 0) height = _clampToZero(height);
+    _height = height;
+  }
+}
+
+/**
+ * Converts a negative [int] or [double] to a zero-value of the same type.
+ *
+ * Returns `0` if value is int, `0.0` if value is double.
+ */
+num _clampToZero(num value) {
+  assert(value < 0);
+  return -value * 0;
 }
diff --git a/sdk/lib/typed_data/dart2js/native_typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/native_typed_data_dart2js.dart
index 17a61b6..efc4957 100644
--- a/sdk/lib/typed_data/dart2js/native_typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/native_typed_data_dart2js.dart
@@ -79,7 +79,8 @@
   }
 
   void _checkIndex(int index, int length) {
-    if (JS('bool', '(# >>> 0 != #)', index, index) || index >= length) {
+    if (JS('bool', '(# >>> 0) !== #', index, index) ||
+        JS('int', '#', index) >= length) {  // 'int' guaranteed by above test.
       _invalidIndex(index, length);
     }
   }
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index c476a70..b7c55d5 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -4,7 +4,6 @@
 
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/core/List/sort_A01_t04: Fail, Pass, Timeout # Must be a bug in jsshell, test sometimes times out.
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js && $checked && $runtime == ie9 ]
 LibTest/core/Uri/encodeComponent_A01_t02: Skip
@@ -126,6 +125,7 @@
 LibTest/core/int/toDouble_A01_t01: RuntimeError, OK # co19 issue 200
 
 LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
+LibTest/collection/LinkedList/add_A01_t01: Pass, Slow # Slow tests that needs extra time to finish.
 
 LibTest/core/List/getRange_A03_t01: RuntimeError, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
 
@@ -246,9 +246,9 @@
 LibTest/core/int/toRadixString_A01_t01: RuntimeError, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
 
 [ $compiler == dart2js && $runtime == ie9 ]
+LibTest/collection/LinkedList/add_A01_t01: Pass, Slow, Timeout # Slow tests that needs extra time to finish.
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # co19-roll r607: Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A07_t02: RuntimeError # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/add_A01_t01: Pass, Timeout  # co19-roll r607: Please triage this failure
 LibTest/core/Uri/Uri_A06_t03: Timeout # Issue 13511
 LibTest/math/cos_A01_t01: Fail # co19 issue 44
 
@@ -555,7 +555,7 @@
 LibTest/typed_data/Uint16List/toList_A01_t01: timeout # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/Uint16List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Uint32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint32List/toList_A01_t01: timeout # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint32List/toList_A01_t01: RuntimeError, timeout # issue 16934, co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/Uint32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/toList_A01_t01: fail, timeout # co19-roll r559: Please triage this failure
@@ -609,6 +609,7 @@
 LibTest/core/Stopwatch/elapsed_A01_t02: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/elapsed_A01_t03: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
+LibTest/math/sin_A01_t02: RuntimeError # V8 issue 3006, https://code.google.com/p/v8/issues/detail?id=3006
 
 [ $compiler == dart2js && $minified ]
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index ad284aa..b52328c 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -5,10 +5,6 @@
 [ $compiler == none && $runtime == drt ]
 *: Skip # running co19 tests on content_shell would make our dartium cycle-times very long
 
-[ $compiler == none && $runtime == dartium && $mode == debug ]
-Language/15_Types/4_Interface_Types_A11_t01: Skip # Issue 16343
-Language/15_Types/4_Interface_Types_A11_t02: Skip # Issue 16343
-
 [ $compiler == none && $runtime == dartium ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Pass, Fail # Issue 13719: Please triage this failure.
 Language/14_Libraries_and_Scripts/3_Parts_A02_t02: Pass, Timeout # Issue 13719: Please triage this failure.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index b91152b..10039ae 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -55,7 +55,6 @@
 #end [ $compiler == none && $runtime == vm && $checked ]
 
 [ $compiler == none && $runtime == vm && $mode == debug ]
-Language/15_Types/4_Interface_Types_A11_t01: Pass, Slow
 LibTest/core/List/List_class_A01_t01: Pass, Slow
 
 [ $compiler == none && $runtime == vm && $arch != x64 ]
diff --git a/tests/compiler/dart2js/analyze_all_test.dart b/tests/compiler/dart2js/analyze_all_test.dart
index 5f6a8ab..2d72c76 100644
--- a/tests/compiler/dart2js/analyze_all_test.dart
+++ b/tests/compiler/dart2js/analyze_all_test.dart
@@ -40,7 +40,8 @@
   var compiler2 = compilerFor(SOURCE, uri, analyzeAll: true);
   asyncTest(() => compiler2.runCompiler(uri).then((_) {
     Expect.isTrue(compiler2.compilationFailed);
-    Expect.isTrue(compiler2.warnings.isEmpty, 'unexpected warnings');
+    Expect.isTrue(compiler2.warnings.isEmpty,
+                  'unexpected warnings: ${compiler2.warnings}');
     Expect.equals(2, compiler2.errors.length,
                   'expected exactly two errors, but got ${compiler2.errors}');
 
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index edc0d4c..cce56d6 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -55,7 +55,7 @@
     (String code, List errors, List warnings) {
       Expect.isNull(code);
       Expect.equals(1, errors.length, 'errors=$errors');
-      Expect.equals("Error: Could not find 'main'.", errors[0].toString());
+      Expect.equals("Could not find 'main'.", errors[0].toString());
       Expect.isTrue(warnings.isEmpty, 'warnings=$warnings');
     });
 
@@ -75,7 +75,7 @@
       Expect.isNull(code);
       Expect.equals(1, errors.length);
       Expect.isTrue(
-          errors[0].toString().startsWith("Error: Could not find 'main'."));
+          errors[0].toString().startsWith("Could not find 'main'."));
       Expect.isTrue(warnings.isEmpty);
     });
 
@@ -95,7 +95,7 @@
       Expect.isNull(code);
       Expect.equals(1, errors.length);
       Expect.isTrue(
-          errors[0].toString().startsWith("Error: Could not find 'main'."));
+          errors[0].toString().startsWith("Could not find 'main'."));
       Expect.isTrue(warnings.isEmpty);
     });
 
@@ -109,7 +109,7 @@
       Expect.isTrue(errors.isEmpty);
       Expect.equals(1, warnings.length);
       Expect.equals(
-          "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
+          "Cannot resolve type 'Foo'.", warnings[0].toString());
     });
 
   runCompiler(
@@ -130,7 +130,7 @@
       Expect.isNull(code);
       Expect.isTrue(errors.isEmpty);
       Expect.equals(
-          "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
+          "Cannot resolve type 'Foo'.", warnings[0].toString());
     });
 
   runCompiler(
@@ -142,7 +142,7 @@
       Expect.isTrue(errors.isEmpty);
       Expect.equals(1, warnings.length);
       Expect.equals(
-          "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
+          "Cannot resolve type 'Foo'.", warnings[0].toString());
     });
 
   runCompiler(
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index 03d08e6..26309d0 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -10,9 +10,10 @@
 
 import 'analyze_helper.dart';
 
+const String SIMPLIFY_NEVER_CALLED = "The method 'simplify' is never called";
+
 void main() {
   var uri = currentDirectory.resolve(
       'sdk/lib/_internal/compiler/implementation/use_unused_api.dart');
-  asyncTest(
-      () => analyze([uri], {}, analyzeAll: false));
+  asyncTest(() => analyze([uri], {}, analyzeAll: false));
 }
diff --git a/tests/compiler/dart2js/bad_output_io_test.dart b/tests/compiler/dart2js/bad_output_io_test.dart
new file mode 100644
index 0000000..f8ec58b
--- /dev/null
+++ b/tests/compiler/dart2js/bad_output_io_test.dart
@@ -0,0 +1,67 @@
+// 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 that the compiler can handle imports when package root has not been set.
+
+library dart2js.test.missing_file;
+
+import 'dart:io' show exit;
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+
+import '../../../sdk/lib/_internal/compiler/compiler.dart'
+       show Diagnostic;
+import '../../../sdk/lib/_internal/compiler/implementation/dart2js.dart'
+       show exitFunc, compileFunc, compile, diagnosticHandler;
+import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart'
+       show FormattingDiagnosticHandler;
+
+class CollectingFormattingDiagnosticHandler
+    implements FormattingDiagnosticHandler {
+
+  final provider = null;
+  bool showWarnings = true;
+  bool showHints = true;
+  bool verbose = true;
+  bool isAborting = false;
+  bool enableColors = false;
+  bool throwOnError = false;
+  var lastKind = null;
+
+  final int FATAL = 0;
+  final int INFO = 1;
+
+  final messages = [];
+
+  void info(var message, [kind]) {
+   messages.add([message, kind]);
+  }
+
+  void diagnosticHandler(Uri uri, int begin, int end, String message, kind) {
+    messages.add([message, kind]);
+  }
+
+  void call(Uri uri, int begin, int end, String message, kind) {
+    diagnosticHandler(uri, begin, end, message, kind);
+  }
+}
+
+testOutputProvider(script, libraryRoot, packageRoot, inputProvider, handler,
+                   [options, outputProvider, environment]) {
+  diagnosticHandler = new CollectingFormattingDiagnosticHandler();
+  outputProvider("/non/existing/directory/should/fail/file", "js");
+}
+
+void main() {
+  compileFunc = testOutputProvider;
+  exitFunc = (exitCode) {
+    Expect.equals(1, diagnosticHandler.messages.length);
+    var message = diagnosticHandler.messages[0];
+    Expect.isTrue(message[0].contains("Cannot open file"));
+    Expect.equals(Diagnostic.ERROR, message[1]);
+    Expect.equals(1, exitCode);
+    exit(0);
+  };
+  compile(["foo.dart", "--out=bar.dart"]);
+}
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 6d56f4f..16eee71 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -9,6 +9,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 void compileAndFind(String code,
                     String className,
@@ -225,7 +226,7 @@
       var inferrer = compiler.typesTask.typesInferrer;
       signature.forEachParameter((Element element) {
         Expect.equals(expectedTypes[index++],
-            inferrer.getTypeOfElement(element).simplify(compiler),
+            simplify(inferrer.getTypeOfElement(element), compiler),
             test);
       });
       Expect.equals(index, expectedTypes.length);
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
index 600f228..af72fe0 100644
--- a/tests/compiler/dart2js/closure_tracer_test.dart
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -7,6 +7,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = '''
 testFunctionStatement() {
@@ -116,7 +117,7 @@
     checkType(String name, type) {
       var element = findElement(compiler, name);
       var mask = typesInferrer.getReturnTypeOfElement(element);
-      Expect.equals(type.nullable(), mask.simplify(compiler), name);
+      Expect.equals(type.nullable(), simplify(mask, compiler), name);
     }
 
     checkType('testFunctionStatement', typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 763bf35..790f3cc 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -89,15 +89,15 @@
                           bool analyzeOnly: false,
                           String coreSource: DEFAULT_CORELIB,
                           bool disableInlining: true,
-                          bool allowErrors: true,
-                          bool allowWarnings: true}) {
+                          int expectedErrors,
+                          int expectedWarnings}) {
   MockCompiler compiler = new MockCompiler(
       analyzeAll: analyzeAll,
       analyzeOnly: analyzeOnly,
       coreSource: coreSource,
       disableInlining: disableInlining,
-      allowErrors: allowErrors,
-      allowWarnings: allowWarnings);
+      expectedErrors: expectedErrors,
+      expectedWarnings: expectedWarnings);
   compiler.sourceFiles[uri.toString()] =
       new StringSourceFile(uri.toString(), code);
   return compiler;
@@ -106,12 +106,12 @@
 Future<String> compileAll(String code,
                           {String coreSource: DEFAULT_CORELIB,
                           bool disableInlining: true,
-                          bool allowErrors: true,
-                          bool allowWarnings: true}) {
+                          int expectedErrors,
+                          int expectedWarnings}) {
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler = compilerFor(
       code, uri, coreSource: coreSource, disableInlining: disableInlining,
-      allowErrors: allowErrors, allowWarnings: allowWarnings);
+      expectedErrors: expectedErrors, expectedWarnings: expectedWarnings);
   return compiler.runCompiler(uri).then((_) {
     Expect.isFalse(compiler.compilationFailed,
                    'Unexpected compilation error');
@@ -122,11 +122,11 @@
 Future compileAndCheck(String code,
                        String name,
                        check(MockCompiler compiler, lego.Element element),
-                       {bool allowErrors: true, bool allowWarnings: true}) {
+                       {int expectedErrors, int expectedWarnings}) {
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler = compilerFor(code, uri,
-                                      allowErrors: allowErrors,
-                                      allowWarnings: allowWarnings);
+      expectedErrors: expectedErrors,
+      expectedWarnings: expectedWarnings);
   return compiler.runCompiler(uri).then((_) {
     lego.Element element = findElement(compiler, name);
     return check(compiler, element);
diff --git a/tests/compiler/dart2js/compiler_test.dart b/tests/compiler/dart2js/compiler_test.dart
index 0b2631c..8415ee8 100644
--- a/tests/compiler/dart2js/compiler_test.dart
+++ b/tests/compiler/dart2js/compiler_test.dart
@@ -20,16 +20,22 @@
   setOnError(var f) => onError = f;
   setOnWarning(var f) => onWarning = f;
 
-  void reportWarning(Node node, var message) {
-    if (onWarning != null) onWarning(this, node, message);
-    super.reportWarning(node, message);
+  void reportWarning(Spannable node,
+                     MessageKind messageKind,
+                     [Map arguments = const {}]) {
+    if (onWarning != null) {
+      onWarning(this, node, messageKind.message(arguments));
+    }
+    super.reportWarning(node, messageKind, arguments);
   }
 
   void reportError(Spannable node,
-                   MessageKind errorCode,
+                   MessageKind messageKind,
                    [Map arguments = const {}]) {
-    if (onError != null) onError(this, node, errorCode.error(arguments));
-    super.reportError(node, errorCode, arguments);
+    if (onError != null) {
+      onError(this, node, messageKind.message(arguments));
+    }
+    super.reportError(node, messageKind, arguments);
   }
 }
 
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index e522a35..6ea07a3 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -7,10 +7,12 @@
 import "package:async_helper/async_helper.dart";
 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart';
-import '../../../sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart';
 
 import "parser_helper.dart";
 import "compiler_helper.dart";
+import "type_mask_test_helper.dart";
+import 'dart:mirrors';
 
 /**
  * Finds the node corresponding to the last occurence of the substring
@@ -110,7 +112,7 @@
    * made of [baseTypes].
    */
   void checkNodeHasType(String variable, List<BaseType> baseTypes) {
-    return Expect.equals(
+    Expect.equals(
         concreteFrom(baseTypes),
         inferrer.inferredTypes[findNode(variable)]);
   }
@@ -120,7 +122,7 @@
    * occurence of [: variable; :] in the program is the unknown concrete type.
    */
   void checkNodeHasUnknownType(String variable) {
-    return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnknown());
+    Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnknown());
   }
 
   /**
@@ -129,7 +131,7 @@
    */
   void checkFieldHasType(String className, String fieldName,
                          List<BaseType> baseTypes) {
-    return Expect.equals(
+    Expect.equals(
         concreteFrom(baseTypes),
         inferrer.inferredFieldTypes[findField(className, fieldName)]);
   }
@@ -139,12 +141,19 @@
    * concrete type.
    */
   void checkFieldHasUknownType(String className, String fieldName) {
-    return Expect.isTrue(
+    Expect.isTrue(
         inferrer.inferredFieldTypes[findField(className, fieldName)]
                 .isUnknown());
   }
+
+  /** Checks that the inferred type for [selector] is [mask]. */
+  void checkSelectorHasType(Selector selector, TypeMask mask) {
+    Expect.equals(mask, inferrer.getTypeOfSelector(selector));
+  }
 }
 
+const String DYNAMIC = '"__dynamic_for_test"';
+
 const String CORELIB = r'''
   print(var obj) {}
   abstract class num {
@@ -192,9 +201,9 @@
 }
 
 testDynamicBackDoor() {
-  final String source = r"""
+  final String source = """
     main () {
-      var x = "__dynamic_for_test";
+      var x = $DYNAMIC;
       x;
     }
     """;
@@ -222,7 +231,7 @@
   final String source = r"""
       main() {
         var v1 = 42;
-        var v2 = 42.0;
+        var v2 = 42.1;
         var v3 = 'abc';
         var v4 = true;
         var v5 = null;
@@ -300,7 +309,8 @@
         'foo',
         [result.base('A'), result.base('B'), result.base('C')]);
     // Check that the condition is evaluated.
-    result.checkNodeHasType('bar', [result.int]);
+    // TODO(polux): bar's type could be inferred to be {int} here.
+    result.checkNodeHasType('bar', [result.int, result.nullType]);
   });
 }
 
@@ -363,7 +373,8 @@
   return analyze(source).then((result) {
     result.checkNodeHasType('foo', [result.base('A'), result.base('B')]);
     // Check that the condition is evaluated.
-    result.checkNodeHasType('bar', [result.int]);
+    // TODO(polux): bar's type could be inferred to be {int} here.
+    result.checkNodeHasType('bar', [result.int, result.nullType]);
   });
 }
 
@@ -439,6 +450,27 @@
   });
 }
 
+testToplevelVariable2() {
+  final String source = r"""
+      class A {
+        var x;
+      }
+      final top = new A().x;
+
+      main() {
+        var a = new A();
+        a.x = 42;
+        a.x = "abc";
+        var foo = top;
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.nullType, result.int,
+                                    result.string]);
+  });
+}
+
 testNonRecusiveFunction() {
   final String source = r"""
       f(x, y) => true ? x : y;
@@ -449,6 +481,19 @@
   });
 }
 
+testMultipleReturns() {
+  final String source = r"""
+      f(x, y) {
+        if (true) return x;
+        else return y;
+      }
+      main() { var foo = f(42, "abc"); foo; }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int, result.string]);
+  });
+}
+
 testRecusiveFunction() {
   final String source = r"""
       f(x) {
@@ -474,7 +519,7 @@
 }
 
 testSimpleSend() {
-  final String source = r"""
+  final String source = """
       class A {
         f(x) => x;
       }
@@ -491,7 +536,7 @@
       main() {
         new B(); new D(42); // we instantiate B and D but not C
         var foo = new A().f(42);
-        var bar = "__dynamic_for_test".f(42);
+        var bar = $DYNAMIC.f(42);
         foo; bar;
       }
       """;
@@ -501,23 +546,6 @@
   });
 }
 
-testSendToClosureField() {
-  final String source = r"""
-      f(x) => x;
-      class A {
-        var g;
-        A(this.g);
-      }
-      main() {
-        var foo = new A(f).g(42);
-        foo;
-      }
-      """;
-  return analyze(source).then((result) {
-    result.checkNodeHasType('foo', [result.int]);
-  });
-}
-
 testSendToThis1() {
   final String source = r"""
       class A {
@@ -572,6 +600,26 @@
   });
 }
 
+testSendToThis4() {
+  final String source = """
+      class A {
+        bar() => 42;
+        foo() => bar();
+      }
+      class B extends A {
+        bar() => "abc";
+      }
+      main() {
+        new A(); new B();  // make A and B seen
+        var x = $DYNAMIC.foo();
+        x;
+      }
+      """;
+  return analyze(source).then((AnalysisResult result) {
+    result.checkNodeHasType('x', [result.int, result.string]);
+  });
+}
+
 testConstructor() {
   final String source = r"""
       class A {
@@ -586,13 +634,12 @@
   return analyze(source).then((result) {
     result.checkFieldHasType('A', 'x', [result.int, result.bool]);
     result.checkFieldHasType('A', 'y', [result.string, result.nullType]);
-    // TODO(polux): we can be smarter and infer {string} for z
-    result.checkFieldHasType('A', 'z', [result.string, result.nullType]);
+    result.checkFieldHasType('A', 'z', [result.string]);
   });
 }
 
 testGetters() {
-  final String source = r"""
+  final String source = """
       class A {
         var x;
         A(this.x);
@@ -610,7 +657,7 @@
         var bar = a.y;
         var baz = a.z;
         var qux = null.x;
-        var quux = "__dynamic_for_test".x;
+        var quux = $DYNAMIC.x;
         foo; bar; baz; qux; quux;
       }
       """;
@@ -623,8 +670,28 @@
   });
 }
 
+testDynamicGetters() {
+  final String source = """
+      class A {
+        get x => f();
+        f() => 42;
+      }
+      class B extends A {
+        f() => "abc";
+      }
+      main() {
+        new A(); new B();  // make A and B seen
+        var x = $DYNAMIC.x;
+        x;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('x', [result.int, result.string]);
+  });
+}
+
 testSetters() {
-  final String source = r"""
+  final String source = """
       class A {
         var x;
         var w;
@@ -642,8 +709,8 @@
         a.x = 'abc';
         a.y = true;
         null.x = 42;  // should be ignored
-        "__dynamic_for_test".x = null;
-        "__dynamic_for_test".y = 3.14;
+        $DYNAMIC.x = null;
+        $DYNAMIC.y = 3.14;
       }
       """;
   return analyze(source).then((result) {
@@ -659,7 +726,7 @@
     result.checkFieldHasType('A', 'w',
                              [result.int,       // new A(..., 42)
                               result.bool,      // a.y = true
-                              result.double]);  // dynamic.y = double
+                              result.double]);  // dynamic.y = 3.14
   });
 }
 
@@ -710,9 +777,9 @@
         var test = new Test(foo, foo, foo, foo, foo, foo, foo, foo);
 
         new A(42);
-        new A('abc', w: true, z: 42.0);
+        new A('abc', w: true, z: 42.1);
         test.f1(42);
-        test.f1('abc', w: true, z: 42.0);
+        test.f1('abc', w: true, z: 42.1);
 
         new B('abc', y: true);
         new B(1, 2);  // too many positional arguments
@@ -788,9 +855,9 @@
       var test = new Test(foo, foo, foo, foo, foo, foo);
 
       new A(42);
-      new A('abc', true, 42.0);
+      new A('abc', true, 42.1);
       test.f1(42);
-      test.f1('abc', true, 42.0);
+      test.f1('abc', true, 42.1);
 
       new B('a', true);
       new B(1, 2, 3);  // too many arguments
@@ -894,17 +961,17 @@
     return """
         main() {
           var a = 1 $op 2;
-          var b = 1 $op 2.0;
-          var c = 1.0 $op 2;
-          var d = 1.0 $op 2.0;
-          var e = (1 $op 2.0) $op 1;
-          var f = 1 $op (1 $op 2.0);
-          var g = (1 $op 2.0) $op 1.0;
-          var h = 1.0 $op (1 $op 2);
+          var b = 1 $op 2.1;
+          var c = 1.1 $op 2;
+          var d = 1.1 $op 2.1;
+          var e = (1 $op 2.1) $op 1;
+          var f = 1 $op (1 $op 2.1);
+          var g = (1 $op 2.1) $op 1.1;
+          var h = 1.1 $op (1 $op 2);
           var i = (1 $op 2) $op 1;
           var j = 1 $op (1 $op 2);
-          var k = (1.0 $op 2.0) $op 1.0;
-          var l = 1.0 $op (1.0 $op 2.0);
+          var k = (1.1 $op 2.1) $op 1.1;
+          var l = 1.1 $op (1.1 $op 2.1);
           a; b; c; d; e; f; g; h; i; j; k; l;
         }""";
   }
@@ -1076,15 +1143,16 @@
       }
       main() {
         var foo = 1 != 2;
-        var bar = new A() != 2;
-        var baz = new B() != 2;
+        var bar = (new A() != 2);
+        var baz = (new B() != 2);
         foo; bar; baz;
       }
       """;
   return analyze(source).then((result) {
     result.checkNodeHasType('foo', [result.bool]);
     result.checkNodeHasType('bar', [result.bool]);
-    result.checkNodeHasType('baz', []);
+    // TODO(polux): could be even better: empty
+    result.checkNodeHasType('baz', [result.bool]);
     result.checkFieldHasType('A', 'witness', [result.string, result.nullType]);
   });
 }
@@ -1099,7 +1167,9 @@
       var z = "foo";
     }
     main () {
-      new B();
+      // we need to access y and z once to trigger their analysis
+      new B().y;
+      new B().z;
     }
     """;
   return analyze(source).then((result) {
@@ -1116,7 +1186,8 @@
       var x = top;
     }
     main () {
-      new A();
+      // we need to access X once to trigger its analysis
+      new A().x;
     }
     """;
   return analyze(source).then((result) {
@@ -1154,7 +1225,7 @@
 }
 
 testLists() {
-  final String source = r"""
+  final String source = """
     class A {}
     class B {}
     class C {}
@@ -1171,7 +1242,7 @@
       l1.add(new D());
       l1.insert('a', new E());  // raises an error, so E should not be recorded
       l1.insert(1, new F());
-      "__dynamic_for_test"[1] = new G();
+      $DYNAMIC[1] = new G();
       var x1 = l1[1];
       var x2 = l2[1];
       var x3 = l1['foo'];  // raises an error, should return empty
@@ -1232,8 +1303,12 @@
     }
     """;
   return analyze(source).then((result) {
-    result.checkNodeHasType('x', []);
-    result.checkNodeHasType('y', []);
+    // TODO(polux): It would be better if x and y also had the empty type. This
+    // requires a change in SimpleTypeInferrerVisitor.visitStaticSend which
+    // would impact the default type inference and possibly break dart2js.
+    // Keeping this change for a later CL.
+    result.checkNodeHasUnknownType('x');
+    result.checkNodeHasUnknownType('y');
     result.checkNodeHasType('z', []);
     result.checkNodeHasType('w', []);
   });
@@ -1275,11 +1350,11 @@
 }
 
 testDynamicIsAbsorbing() {
-  final String source = r"""
+  final String source = """
     main () {
       var x = 1;
       if (true) {
-        x = "__dynamic_for_test";
+        x = $DYNAMIC;
       } else {
         x = 42;
       }
@@ -1327,14 +1402,14 @@
       var hNull = JS('bool|Null', '1');
       var i = JS('AbstractA', '1');
       var iNull = JS('AbstractA|Null', '1');
-      var j = JS('X', '1');
 
       a; b; c; cNull; d; dNull; e; eNull; f; fNull; g; gNull; h; hNull; i;
-      iNull; j;
+      iNull;
     }
     """;
-  return analyze(source).then((result) {
+  return analyze(source, maxConcreteTypeSize: 6).then((result) {
     List maybe(List types) => new List.from(types)..add(result.nullType);
+    // a and b have all the types seen by the resolver, which are more than 6
     result.checkNodeHasUnknownType('a');
     result.checkNodeHasUnknownType('b');
     final expectedCType = [result.growableList];
@@ -1360,14 +1435,13 @@
                            result.base('D')];
     result.checkNodeHasType('i', expectedIType);
     result.checkNodeHasType('iNull', maybe(expectedIType));
-    result.checkNodeHasType('j', []);
   });
 }
 
 testJsCallAugmentsSeenClasses() {
-  final String source1 = r"""
+  final String source1 = """
     main () {
-      var x = "__dynamic_for_test".truncate();
+      var x = $DYNAMIC.truncate();
       x;
     }
     """;
@@ -1375,11 +1449,11 @@
     result.checkNodeHasType('x', []);
   }).whenComplete(() {
 
-    final String source2 = r"""
+    final String source2 = """
       import 'dart:foreign';
 
       main () {
-        var x = "__dynamic_for_test".truncate();
+        var x = $DYNAMIC.truncate();
         JS('double', 'foo');
         x;
       }
@@ -1403,12 +1477,12 @@
 }
 
 testSeenClasses() {
-  final String source = r"""
+  final String source = """
       class A {
         witness() => 42;
       }
       class B {
-        witness() => "abc";
+        witness() => "string";
       }
       class AFactory {
         onlyCalledInAFactory() => new A();
@@ -1421,7 +1495,7 @@
         new AFactory().onlyCalledInAFactory();
         new BFactory();
         // should be of type {int} and not {int, String} since B is unreachable
-        var foo = "__dynamic_for_test".witness();
+        var foo = $DYNAMIC.witness();
         foo;
       }
       """;
@@ -1434,8 +1508,8 @@
   final String source = r"""
       main() {
         var a = 1;
-        var b = 1.0;
-        var c = true ? 1 : 1.0;
+        var b = 1.1;
+        var c = true ? 1 : 1.1;
         a; b; c;
       }
       """;
@@ -1461,10 +1535,10 @@
       """;
   return analyze(source).then((result) {
 
-    convert(ConcreteType type) {
-      return result.compiler.typesTask.concreteTypesInferrer
-          .concreteTypeToTypeMask(type);
-    }
+  convert(ConcreteType type) {
+    return result.compiler.typesTask.concreteTypesInferrer
+        .types.concreteTypeToTypeMask(type);
+  }
 
     final nullSingleton =
         result.compiler.typesTask.concreteTypesInferrer.singletonConcreteType(
@@ -1498,7 +1572,7 @@
                   new TypeMask.subclass(a));
 
     Expect.equals(
-        convert(singleton(b).union(singleton(d))).simplify(result.compiler),
+        simplify(convert(singleton(b).union(singleton(d))), result.compiler),
         new TypeMask.nonNullSubtype(a));
   });
 }
@@ -1528,13 +1602,8 @@
       """;
   return analyze(source).then((result) {
 
-    inferredType(Selector selector) {
-      return result.compiler.typesTask.concreteTypesInferrer
-          .getTypeOfSelector(selector);
-    }
 
-    ClassElement abc = findElement(result.compiler, 'ABC');
-    ClassElement bc = findElement(result.compiler, 'BC');
+
     ClassElement a = findElement(result.compiler, 'A');
     ClassElement b = findElement(result.compiler, 'B');
     ClassElement c = findElement(result.compiler, 'C');
@@ -1545,26 +1614,38 @@
 
     Selector foo = new Selector.call("foo", null, 0);
 
-    Expect.equals(
-        inferredType(foo).simplify(result.compiler),
-        new TypeMask.nonNullSubclass(abc));
-    Expect.equals(
-        inferredType(new TypedSelector.subclass(x, foo)),
+    result.checkSelectorHasType(
+        foo,
+        new TypeMask.unionOf([a, b, c]
+            .map((cls) => new TypeMask.nonNullExact(cls)), result.compiler));
+    result.checkSelectorHasType(
+        new TypedSelector.subclass(x, foo),
         new TypeMask.nonNullExact(b));
-    Expect.equals(
-        inferredType(new TypedSelector.subclass(y, foo)),
+    result.checkSelectorHasType(
+        new TypedSelector.subclass(y, foo),
         new TypeMask.nonNullExact(c));
-    Expect.equals(
-        inferredType(new TypedSelector.subclass(z, foo)),
+    result.checkSelectorHasType(
+        new TypedSelector.subclass(z, foo),
         new TypeMask.nonNullExact(a));
-    Expect.equals(
-        inferredType(new TypedSelector.subclass(
-            xy, foo)).simplify(result.compiler),
-        new TypeMask.nonNullSubclass(bc));
+    result.checkSelectorHasType(
+        new TypedSelector.subclass(xy, foo),
+        new TypeMask.unionOf([b, c].map((cls) =>
+            new TypeMask.nonNullExact(cls)), result.compiler));
 
-    Selector bar = new Selector.call("bar", null, 0);
+    result.checkSelectorHasType(new Selector.call("bar", null, 0), null);
+  });
+}
 
-    Expect.isNull(inferredType(bar));
+testEqualsNullSelector() {
+  final String source = r"""
+      main() {
+        1 == null;
+      }
+      """;
+  return analyze(source).then((result) {
+    ClassElement bool = result.compiler.backend.boolImplementation;
+    result.checkSelectorHasType(new Selector.binaryOperator('=='),
+                                new TypeMask.nonNullExact(bool));
   });
 }
 
@@ -1595,7 +1676,7 @@
   });
 }
 
-testClosures() {
+testClosures1() {
   final String source = r"""
       class A {
         final foo = 42;
@@ -1603,25 +1684,29 @@
       class B {
         final foo = "abc";
       }
+      class C {
+        final foo = true;
+      }
       main() {
-        new A(); new B();
-
         var a;
         var f = (x) {
           a = x.foo;
         };
-        var b = f(42);
-        a; b; f;
+        // We make sure that x doesn't have type dynamic by adding C to the
+        // set of seen classes and by checking that a's type doesn't contain
+        // bool.
+        new C();
+        f(new A());
+        f(new B());
+        a;
       }
       """;
   return analyze(source).then((AnalysisResult result) {
-    result.checkNodeHasType('a', [result.int, result.string]);
-    result.checkNodeHasType('f', [result.functionType]);
-    result.checkNodeHasUnknownType('b');
+    result.checkNodeHasType('a', [result.nullType, result.int, result.string]);
   });
 }
 
-testNestedFunctions() {
+testClosures2() {
   final String source = r"""
       class A {
         final foo = 42;
@@ -1629,21 +1714,312 @@
       class B {
         final foo = "abc";
       }
+      class C {
+        final foo = true;
+      }
       main() {
-        new A(); new B();
+        // We make sure that x doesn't have type dynamic by adding C to the
+        // set of seen classes and by checking that a's type doesn't contain
+        // bool. 
+        new C();
 
         var a;
         f(x) {
           a = x.foo;
         }
-        var b = f(42);
-        a; b; f;
+        f(new A());
+        f(new B());
+        a; f;
       }
       """;
   return analyze(source).then((AnalysisResult result) {
-    result.checkNodeHasType('a', [result.int, result.string]);
+    result.checkNodeHasType('a', [result.nullType, result.int, result.string]);
     result.checkNodeHasType('f', [result.functionType]);
-    result.checkNodeHasUnknownType('b');
+  });
+}
+
+testClosures3() {
+  final String source = r"""
+      class A {
+        var g;
+        A(this.g);
+      }
+      main() {
+        var foo = new A((x) => x).g(42);
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testClosures4() {
+  final String source = """
+      class A {
+        var f = $DYNAMIC;
+      }
+      main() {
+        var f = (x) => x;
+        var g = (x) => "a";
+        var h = (x, y) => true;
+
+        var foo = $DYNAMIC(42);
+        var bar = new A().f(1.2);
+        var baz = $DYNAMIC.f(null);
+
+        foo; bar; baz;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int, result.string]);
+    result.checkNodeHasType('bar', [result.double, result.string]);
+    result.checkNodeHasType('baz', [result.nullType, result.string]);
+  });
+}
+
+testClosures5() {
+  final String source = r"""
+      f(x) => x;
+      class A {
+        var g;
+        A(this.g);
+      }
+      main() {
+        var foo = new A(f).g(42);
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testClosures6() {
+  final String source = r"""
+      class A {
+        var g;
+        A(this.g);
+      }
+      class B {
+        f(x) => x;
+      }
+      main() {
+        var foo = new A(new B().f).g(42);
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testClosures7() {
+  final String source = r"""
+      class A {
+        final x = 42;
+        f() => () => x;
+      }
+      main() {
+        var foo = new A().f()();
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testClosures8() {
+  final String source = r"""
+      class A {
+        final x = 42;
+        f() => () => x;
+      }
+      class B extends A {
+        get x => "a";
+      }
+      main() {
+        var foo = new B().f()();
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.string]);
+  });
+}
+
+testClosures9() {
+  final String source = r"""
+      class A {
+        g() => 42;
+        f() => () => g();
+      }
+      class B extends A {
+        g() => "a";
+      }
+      main() {
+        var foo = new B().f()();
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.string]);
+  });
+}
+
+testClosures10() {
+  final String source = r"""
+      class A {
+        f() => 42;
+      }
+      main() {
+        var a = new A();
+        g() => a.f();
+        var foo = g();
+        foo; a;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testClosures11() {
+  final String source = r"""
+      class A {
+        var x;
+        f() => x;
+      }
+      main() {
+        var a = new A();
+        f() => a.f();
+        a.x = 42;
+        var foo = f();
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.nullType, result.int]);
+  });
+}
+
+testClosures12() {
+  final String source = r"""
+      var f = (x) => x;
+      main() {
+        var foo = f(1);
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testRefinement() {
+  final String source = """
+      class A {
+        f() => null;
+        g() => 42;
+      }
+      class B {
+        g() => "aa";
+      }
+      main() {
+        var x = $DYNAMIC ? new A() : new B();
+        x.f();
+        var foo = x.g();
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testDefaultArguments() {
+  final String source = r"""
+      f1([x = 42]) => x;
+      g1([x]) => x;
+
+      f2({x: 42}) => x;
+      g2({x}) => x;
+
+      main() {
+        var xf1 = f1();
+        var xg1 = g1();
+        var xf2 = f2();
+        var xg2 = g2();
+        xf1; xg1; xf2; xg2;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkNodeHasType('xf1', [result.int]);
+    result.checkNodeHasType('xg1', [result.nullType]);
+    result.checkNodeHasType('xf2', [result.int]);
+    result.checkNodeHasType('xg2', [result.nullType]);
+  });
+}
+
+testSuperConstructorCall() {
+  final String source = r"""
+      class A {
+        final x;
+        A(this.x);
+      }
+
+      class B extends A {
+        B(x) : super(x);
+      }
+      main() {
+        var b = new B(42);
+        var foo = b.x;
+        foo;
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkFieldHasType('A', 'x', [result.int]);
+    result.checkNodeHasType('foo', [result.int]);
+  });
+}
+
+testSuperConstructorCall2() {
+  final String source = r"""
+      class A {
+        var x;
+        A() {
+          x = 42;
+        }
+      }
+      class B extends A {
+      }
+      main() {
+        new B();
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkFieldHasType('A', 'x', [result.int]);
+  });
+}
+
+testSuperConstructorCall3() {
+  final String source = r"""
+      class A {
+        var x;
+        A() {
+          x = 42;
+        }
+      }
+      class B extends A {
+        B(unused) {}
+      }
+      main() {
+        new B("abc");
+      }
+      """;
+  return analyze(source).then((result) {
+    result.checkFieldHasType('A', 'x', [result.int]);
   });
 }
 
@@ -1662,23 +2038,26 @@
     testFor3,
     testForIn,
     testToplevelVariable,
+    testToplevelVariable2,
     testNonRecusiveFunction,
+    testMultipleReturns,
     testRecusiveFunction,
     testMutuallyRecusiveFunction,
     testSimpleSend,
-    // testSendToClosureField,  // closures are not yet supported
     testSendToThis1,
     testSendToThis2,
     testSendToThis3,
+    testSendToThis4,
     testConstructor,
     testGetters,
+    testDynamicGetters,
     testSetters,
     testOptionalNamedParameters,
     testOptionalPositionalParameters,
     testListLiterals,
     testMapLiterals,
     testReturn,
-    // testNoReturn, // right now we infer the empty type instead of null
+    testNoReturn,
     testArithmeticOperators,
     testBooleanOperators,
     testBooleanOperatorsShortCirtcuit,
@@ -1704,8 +2083,25 @@
     testIntDoubleNum,
     testConcreteTypeToTypeMask,
     testSelectors,
+    // TODO(polux): this test is failing, see http://dartbug.com/16825.
+    //testEqualsNullSelector,
     testMixins,
-    testClosures,
-    testNestedFunctions,
+    testClosures1,
+    testClosures2,
+    testClosures3,
+    testClosures4,
+    testClosures5,
+    testClosures6,
+    testClosures7,
+    testClosures8,
+    testClosures9,
+    testClosures10,
+    testClosures11,
+    testClosures12,
+    testRefinement,
+    testDefaultArguments,
+    testSuperConstructorCall,
+    testSuperConstructorCall2,
+    testSuperConstructorCall3,
   ], (f) => f()));
 }
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index f73cebd..c822fb3 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -13,10 +13,6 @@
 simple_inferrer_const_closure2_test: Fail # Issue 16507
 simple_inferrer_global_field_closure_test: Fail # Issue 16507
 
-mirrors/relation_subtype_test: Fail # Issue 16736
-mirrors/relation_assignable_test: Fail # Issue 16736
-mirrors/relation_subclass_test: Fail # Issue 16737
-
 logical_expression_test: Fail # Issue 17027
 
 [ $mode == debug ]
diff --git a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart b/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
index 890397a..45955b5 100644
--- a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
+++ b/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
@@ -65,13 +65,13 @@
 const Map MEMORY_SOURCE_FILES = const {"main.dart": """
 import "dart:async";
 
-@def import 'lib.dart' show f, A;
+@def import 'lib.dart' as lib show f, A;
 
 const def = const DeferredLibrary("deferred");
 
 void main() {
   def.load().then((_) {
-    print(f(new A<A>()));
+    print(lib.f(new lib.A<lib.A>()));
   });
 }
 """, "lib.dart": """
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart
index 5f21cc5..3de5634 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart
@@ -59,7 +59,7 @@
 const Map MEMORY_SOURCE_FILES = const {"main.dart": """
 import "dart:async";
 
-@def import 'lib.dart' show f1;
+@def import 'lib.dart' as lib show f1;
 import 'lib.dart' show f2;
 
 const def = const DeferredLibrary("deferred");
@@ -67,7 +67,7 @@
 void main() {
   print(f2());
   def.load().then((_) {
-    print(f1());
+    print(lib.f1());
   });
 }
 """, "lib.dart": """
diff --git a/tests/compiler/dart2js/deferred_not_in_main_test.dart b/tests/compiler/dart2js/deferred_not_in_main_test.dart
index e27e689..a7002c2 100644
--- a/tests/compiler/dart2js/deferred_not_in_main_test.dart
+++ b/tests/compiler/dart2js/deferred_not_in_main_test.dart
@@ -68,12 +68,12 @@
 library lib1;
 
 import 'dart:async';
-@def import 'lib2.dart';
+@def import 'lib2.dart' as lib2;
 
 const def = const DeferredLibrary('lib2');
 
 void foo1() {
-  def.load().then((_) => foo2());
+  def.load().then((_) => lib2.foo2());
 }
 """,
   "lib2.dart":"""
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 5e93e2e29..f9a41a4 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -34,13 +34,11 @@
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     diagnostics.sort();
     var expected = [
-        "memory:exporter.dart:43:47:Info: 'hest' is defined here."
-        ":info",
-        "memory:library.dart:41:45:Info: 'hest' is defined here."
-        ":info",
-        "memory:main.dart:0:22:Info: 'hest' is imported here.:info",
-        "memory:main.dart:23:46:Info: 'hest' is imported here.:info",
-        "memory:main.dart:86:90:Error: Duplicate import of 'hest'.:error"
+        "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:90:Duplicate import of 'hest'.:error"
     ];
     Expect.listEquals(expected, diagnostics);
     Expect.isTrue(compiler.compilationFailed);
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index b0afedd..fd5c38f 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -88,8 +88,8 @@
         break;

       case 'warning':

         onTest(testMarker, testType);

-        reportWarningCode(CURRENT_ELEMENT_SPANNABLE,

-                          MessageKind.GENERIC, {'text': marker});

+        reportWarning(CURRENT_ELEMENT_SPANNABLE,

+                      MessageKind.GENERIC, {'text': marker});

         break;

       case 'error':

         onTest(testMarker, testType);

diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 54c718a..9f0d498 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -10,6 +10,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 void compileAndFind(String code,
                     String className,
@@ -487,7 +488,7 @@
         TypeMask type = f(compiler.typesTask);
         var inferrer = compiler.typesTask.typesInferrer;
         TypeMask inferredType =
-            inferrer.getTypeOfElement(field).simplify(inferrer.compiler);
+            simplify(inferrer.getTypeOfElement(field), inferrer.compiler);
         Expect.equals(type, inferredType, test);
     });
   });
diff --git a/tests/compiler/dart2js/hide_package_warnings_test.dart b/tests/compiler/dart2js/hide_package_warnings_test.dart
new file mode 100644
index 0000000..639eef8
--- /dev/null
+++ b/tests/compiler/dart2js/hide_package_warnings_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the '--hide-package-warnings' option works as intended.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'memory_compiler.dart';
+
+/// Error code that creates 1 warning, 1 hint, and 1 info.
+const ERROR_CODE = """
+m(Object o) {
+  if (o is String) {
+    o = o.length;
+  }
+}""";
+
+const SOURCE = const {
+  'main.dart': """
+import 'package:pkg_error1/pkg_error1.dart';
+import 'package:pkg_error2/pkg_error2.dart';
+import 'package:pkg_noerror/pkg_noerror.dart';
+import 'error.dart';               
+""",
+
+  'error.dart': ERROR_CODE,
+
+  'pkg/pkg_error1/pkg_error1.dart': """
+import 'package:pkg_error2/pkg_error2.dart';
+import 'package:pkg_noerror/pkg_noerror.dart';
+$ERROR_CODE""",
+
+  'pkg/pkg_error2/pkg_error2.dart': """
+import 'package:pkg_error1/pkg_error1.dart';
+import 'package:pkg_noerror/pkg_noerror.dart';
+$ERROR_CODE""",
+
+  'pkg/pkg_noerror/pkg_noerror.dart': """
+import 'package:pkg_error1/pkg_error1.dart';
+import 'package:pkg_error2/pkg_error2.dart';
+"""};
+
+void test(List<Uri> entryPoints,
+          {bool hidePackageWarnings: false,
+           int warnings: 0,
+           int hints: 0,
+           int infos: 0}) {
+  var options = ['--analyze-only', '--analyze-all'];
+  if (hidePackageWarnings) {
+    options.add('--hide-package-warnings');
+  }
+  var collector = new DiagnosticCollector();
+  var compiler = compilerFor(SOURCE,
+                             options: options,
+                             packageRoot: Uri.parse('memory:pkg/'),
+                             diagnosticHandler: collector);
+  Uri mainUri = null;
+  if (entryPoints.length == 1) {
+    mainUri = entryPoints[0];
+  } else {
+    compiler.librariesToAnalyzeWhenRun = entryPoints;
+  }
+  asyncTest(() => compiler.run(mainUri).then((_) {
+    print('==================================================================');
+    print('test: $entryPoints hidePackageWarnings=$hidePackageWarnings');
+    Expect.equals(0, collector.errors.length,
+                  'Unexpected errors: ${collector.errors}');
+    Expect.equals(warnings, collector.warnings.length,
+                  'Unexpected warnings: ${collector.warnings}');
+    Expect.equals(hints, collector.hints.length,
+                  'Unexpected hints: ${collector.hints}');
+    Expect.equals(infos, collector.infos.length,
+                  'Unexpected infos: ${collector.infos}');
+    print('==================================================================');
+  }));
+}
+
+void main() {
+  test([Uri.parse('memory:main.dart')],
+       hidePackageWarnings: false,
+       // From error.dart, package:pkg_error1 and package:pkg_error2:
+       warnings: 3, hints: 3, infos: 3);
+  test([Uri.parse('memory:main.dart')],
+       hidePackageWarnings: true,
+       // From error.dart only:
+       warnings: 1, hints: 1, infos: 1);
+  test([Uri.parse('package:pkg_error1/pkg_error1.dart')],
+       hidePackageWarnings: false,
+       // From package:pkg_error1 and package:pkg_error2:
+       warnings: 2, hints: 2, infos: 2);
+  test([Uri.parse('package:pkg_error1/pkg_error1.dart')],
+       hidePackageWarnings: true,
+       // From package:pkg_error1/pkg_error1.dart only:
+       warnings: 1, hints: 1, infos: 1);
+  test([Uri.parse('package:pkg_noerror/pkg_noerror.dart')],
+       hidePackageWarnings: false,
+       // From package:pkg_error1 and package:pkg_error2:
+       warnings: 2, hints: 2, infos: 2);
+  test([Uri.parse('package:pkg_noerror/pkg_noerror.dart')],
+       hidePackageWarnings: true);
+}
+
diff --git a/tests/compiler/dart2js/in_user_code_test.dart b/tests/compiler/dart2js/in_user_code_test.dart
index b860104..415a1dc 100644
--- a/tests/compiler/dart2js/in_user_code_test.dart
+++ b/tests/compiler/dart2js/in_user_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test that the debugging helper [Compiler.inUserCode] works as intended.
+// Test that the helper [Compiler.inUserCode] works as intended.
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index 7cc2f55..6a38130 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -6,6 +6,7 @@
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 bar() => 42;
@@ -36,7 +37,7 @@
       var element = findElement(compiler, name);
       Expect.equals(
           type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
           name);
     }
 
@@ -44,7 +45,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(methodName);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler));
     }
 
     checkReturn('bar', typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index 56c5fff..4f2d7b2 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -13,7 +13,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
-
+import 'type_mask_test_helper.dart';
 
 const String TEST = r'''
 var myList = [42];
@@ -32,7 +32,7 @@
     checkType(String name, type) {
       var element = findElement(compiler, name);
       ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
-      Expect.equals(type, mask.elementType.simplify(compiler), name);
+      Expect.equals(type, simplify(mask.elementType, compiler), name);
     }
 
     checkType('myList', compiler.typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
index d8fb177..4cf3a8f 100644
--- a/tests/compiler/dart2js/list_tracer3_test.dart
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -13,6 +13,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 
 const String TEST = r'''
@@ -34,7 +35,7 @@
     checkType(String name, type) {
       var element = findElement(compiler, name);
       ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
-      Expect.equals(type, mask.elementType.simplify(compiler), name);
+      Expect.equals(type, simplify(mask.elementType, compiler), name);
     }
 
     var interceptorType =
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index e2e8d82..9a3bfda 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -10,7 +10,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
-
+import 'type_mask_test_helper.dart';
 
 String generateTest(String listAllocation) {
   return """
@@ -199,7 +199,7 @@
 void doTest(String allocation, {bool nullify}) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri,
-                             allowErrors: false, allowWarnings: false);
+      expectedErrors: 0, expectedWarnings: 1);
   asyncTest(() => compiler.runCompiler(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
@@ -208,7 +208,7 @@
       var element = findElement(compiler, name);
       ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
       if (nullify) type = type.nullable();
-      Expect.equals(type, mask.elementType.simplify(compiler), name);
+      Expect.equals(type, simplify(mask.elementType, compiler), name);
     }
 
     checkType('listInField', typesTask.numType);
diff --git a/tests/compiler/dart2js/lookup_member_test.dart b/tests/compiler/dart2js/lookup_member_test.dart
index 70a93f1..bc8bf85 100644
--- a/tests/compiler/dart2js/lookup_member_test.dart
+++ b/tests/compiler/dart2js/lookup_member_test.dart
@@ -9,7 +9,7 @@
 import 'type_test_helper.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart"
-       show Element, ClassElement;
+       show Element, ClassElement, MemberSignature, PublicName;
 
 void main() {
   test();
@@ -32,9 +32,10 @@
       """).then((env) {
     void expect(InterfaceType receiverType, String memberName,
                 DartType expectedType) {
-      InterfaceTypeMember member = receiverType.lookupMember(memberName);
+      MemberSignature member = receiverType.lookupInterfaceMember(
+          new PublicName(memberName));
       Expect.isNotNull(member);
-      DartType memberType = member.computeType(env.compiler);
+      DartType memberType = member.type;
       Expect.equals(expectedType, memberType,
           'Wrong member type for $receiverType.$memberName.');
     }
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index 8dc4fcd..fe0767a 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -10,6 +10,7 @@
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 
 String generateTest(String mapAllocation) {
@@ -214,7 +215,7 @@
             String valueElement]) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri,
-                             allowErrors: false, allowWarnings: false);
+      expectedErrors: 0, expectedWarnings: 0);
   asyncTest(() => compiler.runCompiler(uri).then((_) {
     var keyType, valueType;
     var typesTask = compiler.typesTask;
@@ -236,12 +237,12 @@
     checkType(String name, keyType, valueType) {
       var element = findElement(compiler, name);
       MapTypeMask mask = typesInferrer.getTypeOfElement(element);
-      Expect.equals(keyType, mask.keyType.simplify(compiler), name);
-      Expect.equals(valueType, mask.valueType.simplify(compiler), name);
+      Expect.equals(keyType, simplify(mask.keyType, compiler), name);
+      Expect.equals(valueType, simplify(mask.valueType, compiler), name);
     }
 
-    K(TypeMask other) => keyType.union(other, compiler).simplify(compiler);
-    V(TypeMask other) => valueType.union(other, compiler).simplify(compiler);
+    K(TypeMask other) => simplify(keyType.union(other, compiler), compiler);
+    V(TypeMask other) => simplify(valueType.union(other, compiler), compiler);
 
     checkType('mapInField', K(aKeyType), V(typesTask.numType));
     checkType('mapPassedToMethod', K(aKeyType), V(typesTask.numType));
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 269cc1c..b4091f3 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -8,7 +8,6 @@
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
        show NullSink;
-import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
 
 import '../../../sdk/lib/_internal/compiler/compiler.dart'
        show Diagnostic, DiagnosticHandler;
@@ -26,6 +25,8 @@
   final Diagnostic kind;
 
   DiagnosticMessage(this.uri, this.begin, this.end, this.message, this.kind);
+
+  String toString() => '$uri:$begin:$end:$message:$kind';
 }
 
 class DiagnosticCollector {
@@ -52,6 +53,10 @@
   Iterable<DiagnosticMessage> get hints {
     return filterMessagesByKind(Diagnostic.HINT);
   }
+
+  Iterable<DiagnosticMessage> get infos {
+    return filterMessagesByKind(Diagnostic.INFO);
+  }
 }
 
 DiagnosticHandler createDiagnosticHandler(DiagnosticHandler diagnosticHandler,
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
index 95c7e6b..093833e 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
@@ -8,6 +8,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show compilerFor;
 import 'compiler_helper.dart' show findElement;
+import 'type_mask_test_helper.dart';
 
 const MEMORY_SOURCE_FILES = const <String, String> {
   'main.dart': """
@@ -27,9 +28,9 @@
   asyncTest(() => compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
     var element = findElement(compiler, 'field');
     var typesTask = compiler.typesTask;
-    var typesInferrer = typesTask.typesInferrer;        
+    var typesInferrer = typesTask.typesInferrer;
     Expect.equals(typesTask.uint31Type,
-                  typesInferrer.getTypeOfElement(element).simplify(compiler),
+                  simplify(typesInferrer.getTypeOfElement(element), compiler),
                   'field');
   }));
 }
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
index 0dccbe2..8395fed 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
@@ -8,6 +8,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show compilerFor;
 import 'compiler_helper.dart' show findElement;
+import 'type_mask_test_helper.dart';
 
 const MEMORY_SOURCE_FILES = const <String, String> {
   'main.dart': """
@@ -27,9 +28,9 @@
   asyncTest(() => compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
     var element = findElement(compiler, 'field');
     var typesTask = compiler.typesTask;
-    var typesInferrer = typesTask.typesInferrer;        
+    var typesInferrer = typesTask.typesInferrer;
     Expect.equals(typesTask.uint31Type,
-                  typesInferrer.getTypeOfElement(element).simplify(compiler),
+                  simplify(typesInferrer.getTypeOfElement(element), compiler),
                   'field');
   }));
 }
diff --git a/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart b/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart
new file mode 100644
index 0000000..3dbabd1
--- /dev/null
+++ b/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart
@@ -0,0 +1,62 @@
+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "../memory_compiler.dart";
+
+const SOURCE = const {
+  'main.dart': """
+library main;
+
+class Class {
+  var a, b, c, d, e, f, g, h;
+  Class.optional(this.a, int b, void this.c(),
+                 [this.d, int this.e, void this.f(),
+                  this.g = 0, int this.h = 0]);
+  Class.named(this.a, int b, void this.c(),
+                 {this.d, int this.e, void this.f(),
+                  this.g: 0, int this.h: 0});
+  methodOptional(a, int b, void c(),
+                 [d, int e, void f(),
+                  g = 0, int h = 0]) {}
+  methodNamed(a, int b, void c(),
+              {d, int e, void f(),
+               g: 0, int h: 0}) {}
+}
+""",
+};
+
+main() {
+  asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
+    LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
+    ClassMirror classMirror = dartCore.declarations[#Class];
+    testMethod(classMirror.declarations[#optional]);
+    testMethod(classMirror.declarations[#named]);
+    testMethod(classMirror.declarations[#methodOptional]);
+    testMethod(classMirror.declarations[#methodNamed]);
+  }));
+}
+
+testMethod(MethodMirror mirror) {
+  Expect.equals(8, mirror.parameters.length);
+  for (int i = 0 ; i < 6 ; i++) {
+    testParameter(mirror.parameters[i], false);
+  }
+  for (int i = 6 ; i < 8 ; i++) {
+    testParameter(mirror.parameters[i], true);
+  }
+}
+
+testParameter(ParameterMirror mirror, bool expectDefaultValue) {
+  if (expectDefaultValue) {
+    Expect.isTrue(mirror.hasDefaultValue);
+    Expect.isNotNull(mirror.defaultValue);
+  } else {
+    Expect.isFalse(mirror.hasDefaultValue);
+    Expect.isNull(mirror.defaultValue);
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 5f6d467..6d11ba0 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -58,7 +58,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 364;
+    int expectedMethodCount = 355;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/missing_file_test.dart
index b57786e..323ab25 100644
--- a/tests/compiler/dart2js/missing_file_test.dart
+++ b/tests/compiler/dart2js/missing_file_test.dart
@@ -66,11 +66,11 @@
 
 void main() {
   runCompiler(Uri.parse('memory:main.dart'),
-              "Error: Can't read 'memory:foo.dart' "
+              "Can't read 'memory:foo.dart' "
               "(Exception: No such file memory:foo.dart).");
   runCompiler(Uri.parse('memory:foo.dart'),
-              "Error: Can't read 'memory:foo.dart' "
+              "Can't read 'memory:foo.dart' "
               "(Exception: No such file memory:foo.dart).");
   runCompiler(Uri.parse('dart:foo'),
-              "Error: Library not found 'dart:foo'.");
+              "Library not found 'dart:foo'.");
 }
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index eca7e6f..3800f22 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -237,8 +237,12 @@
   List<WarningMessage> errors;
   List<WarningMessage> hints;
   List<WarningMessage> infos;
-  final bool allowWarnings;
-  final bool allowErrors;
+  List<WarningMessage> crashes;
+  /// Expected number of warnings. If `null`, the number of warnings is
+  /// not checked.
+  final int expectedWarnings;
+  /// Expected number of errors. If `null`, the number of errors is not checked.
+  final int expectedErrors;
   final Map<String, SourceFile> sourceFiles;
   Node parsedTree;
 
@@ -258,10 +262,9 @@
                 // Our unit tests check code generation output that is
                 // affected by inlining support.
                 bool disableInlining: true,
-                bool this.allowWarnings: true,
-                bool this.allowErrors: true})
-      : warnings = [], errors = [], hints = [], infos = [],
-        sourceFiles = new Map<String, SourceFile>(),
+                int this.expectedWarnings,
+                int this.expectedErrors})
+      : sourceFiles = new Map<String, SourceFile>(),
         super(enableTypeAssertions: enableTypeAssertions,
               enableMinification: enableMinification,
               enableConcreteTypeInference: enableConcreteTypeInference,
@@ -271,6 +274,7 @@
               analyzeOnly: analyzeOnly,
               emitJavaScript: emitJavaScript,
               preserveComments: preserveComments) {
+    clearMessages();
     coreLibrary = createLibrary("core", coreSource);
 
     // We need to set the assert method to avoid calls with a 'null'
@@ -305,9 +309,11 @@
 
   Future runCompiler(Uri uri) {
     return super.runCompiler(uri).then((result) {
-      if (!allowErrors && !errors.isEmpty) {
+      if (expectedErrors != null &&
+          expectedErrors != errors.length) {
         throw "unexpected error during compilation ${errors}";
-      } else if (!allowWarnings && !warnings.isEmpty) {
+      } else if (expectedWarnings != null &&
+                 expectedWarnings != warnings.length) {
         throw "unexpected warnings during compilation ${warnings}";
       } else {
         return result;
@@ -339,46 +345,28 @@
     return library;
   }
 
-  void reportWarning(Node node, var message) {
-    if (message is! Message) message = message.message;
-    warnings.add(new WarningMessage(node, message));
-    reportDiagnostic(spanFromNode(node),
-        'Warning: $message', api.Diagnostic.WARNING);
-  }
-
-  void reportError(Spannable node,
-                   MessageKind errorCode,
-                   [Map arguments = const {}]) {
-    Message message = errorCode.message(arguments);
-    errors.add(new WarningMessage(node, message));
-    reportDiagnostic(spanFromSpannable(node), '$message', api.Diagnostic.ERROR);
-  }
-
-  void reportInfo(Spannable node,
-                   MessageKind errorCode,
-                   [Map arguments = const {}]) {
-    Message message = errorCode.message(arguments);
-    infos.add(new WarningMessage(node, message));
-    reportDiagnostic(spanFromSpannable(node), '$message', api.Diagnostic.INFO);
-  }
-
-  void reportHint(Spannable node,
-                   MessageKind errorCode,
-                   [Map arguments = const {}]) {
-    Message message = errorCode.message(arguments);
-    hints.add(new WarningMessage(node, message));
-    reportDiagnostic(spanFromSpannable(node), '$message', api.Diagnostic.HINT);
+  // TODO(johnniwinther): Remove this when we don't filter certain type checker
+  // warnings.
+  void reportWarning(Spannable node, MessageKind messageKind,
+                     [Map arguments = const {}]) {
+    reportDiagnostic(node,
+                     messageKind.message(arguments, terseDiagnostics),
+                     api.Diagnostic.WARNING);
   }
 
   void reportFatalError(Spannable node,
-                        MessageKind errorCode,
+                        MessageKind messageKind,
                         [Map arguments = const {}]) {
-    reportError(node, errorCode, arguments);
+    reportError(node, messageKind, arguments);
   }
 
-  void reportMessage(SourceSpan span, var message, api.Diagnostic kind) {
-    var diagnostic = new WarningMessage(null, message.message);
-    if (kind == api.Diagnostic.ERROR) {
+  void reportDiagnostic(Spannable node,
+                        Message message,
+                        api.Diagnostic kind) {
+    var diagnostic = new WarningMessage(node, 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);
@@ -387,26 +375,24 @@
     } else if (kind == api.Diagnostic.HINT) {
       hints.add(diagnostic);
     }
-    reportDiagnostic(span, "$message", kind);
-  }
-
-  void reportDiagnostic(SourceSpan span, String message, api.Diagnostic kind) {
     if (diagnosticHandler != null) {
+      SourceSpan span = spanFromSpannable(node);
       if (span != null) {
-        diagnosticHandler(span.uri, span.begin, span.end, message, kind);
+        diagnosticHandler(span.uri, span.begin, span.end, '$message', kind);
       } else {
-        diagnosticHandler(null, null, null, message, kind);
+        diagnosticHandler(null, null, null, '$message', kind);
       }
     }
   }
 
-  bool get compilationFailed => !errors.isEmpty;
+  bool get compilationFailed => !crashes.isEmpty || !errors.isEmpty;
 
   void clearMessages() {
     warnings = [];
     errors = [];
     hints = [];
     infos = [];
+    crashes = [];
   }
 
   CollectingTreeElements resolveStatement(String text) {
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 75cfedf..704e6b2 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -59,7 +59,7 @@
 
   asyncTest(() => compiler.run(main).then((_) {
     Expect.equals(1, errors.length);
-    Expect.equals("Error: Cannot resolve 'package:foo/foo.dart'. "
+    Expect.equals("Cannot resolve 'package:foo/foo.dart'. "
                   "Package root has not been set.",
                   errors[0]);
   }));
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 94c3b57..acf46ea 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -40,11 +40,11 @@
     log(message);
   }
 
-  SourceSpan spanFromSpannable(node, [uri]) {
+  SourceSpan spanFromSpannable(node) {
     throw 'unsupported operation';
   }
 
-  void reportMessage(SourceSpan span, Diagnostic message, kind) {
+  void reportMessage(SourceSpan span, Message message, kind) {
     log(message);
   }
 
@@ -52,6 +52,10 @@
     log(new Message(errorCode, arguments, false));
   }
 
+  void reportWarning(Spannable node, MessageKind errorCode, [Map arguments]) {
+    log(new Message(errorCode, arguments, false));
+  }
+
   void reportInfo(Spannable node, MessageKind errorCode, [Map arguments]) {
     log(new Message(errorCode, arguments, false));
   }
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 9657bfa..1ae7f8d 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -163,6 +163,53 @@
   }));
 }
 
+testPatchRedirectingConstructor() {
+  asyncTest(() => applyPatch(
+      """
+      class Class {
+        Class(x) : this._(x, false);
+
+        external Class._(x, y);
+      }
+      """,
+      r"""
+      patch class Class {
+        patch Class._(x, y) { print('$x,$y'); }
+      }
+      """).then((compiler) {
+    var classOrigin = ensure(compiler, "Class", compiler.coreLibrary.find,
+                             expectIsPatched: true);
+    classOrigin.ensureResolved(compiler);
+
+    var classPatch = ensure(compiler, "Class", compiler.coreLibrary.patch.find,
+                            expectIsPatch: true);
+
+    Expect.equals(classOrigin, classPatch.origin);
+    Expect.equals(classPatch, classOrigin.patch);
+
+    var constructorRedirecting =
+        ensure(compiler, "",
+               (name) => classOrigin.localLookup(name));
+    var constructorOrigin =
+        ensure(compiler, "_",
+               (name) => classOrigin.localLookup(name),
+               expectIsPatched: true);
+    var constructorPatch =
+        ensure(compiler, "_",
+               (name) => classPatch.localLookup(name),
+               expectIsPatch: true);
+    Expect.equals(constructorOrigin, constructorPatch.origin);
+    Expect.equals(constructorPatch, constructorOrigin.patch);
+
+    compiler.resolver.resolve(constructorRedirecting);
+
+    Expect.isTrue(compiler.warnings.isEmpty,
+                  "Unexpected warnings: ${compiler.warnings}");
+    Expect.isTrue(compiler.errors.isEmpty,
+                  "Unexpected errors: ${compiler.errors}");
+   }));
+}
+
 testPatchMember() {
   asyncTest(() => applyPatch(
       """
@@ -402,7 +449,7 @@
     Expect.isTrue(
         compiler.errors[0].message.kind ==
             MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
-    Expect.stringEquals('Error: External method without an implementation.',
+    Expect.stringEquals('External method without an implementation.',
                         compiler.errors[0].message.toString());
   }));
 }
@@ -434,7 +481,7 @@
     Expect.isTrue(
         compiler.errors[0].message.kind ==
             MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
-    Expect.stringEquals('Error: External method without an implementation.',
+    Expect.stringEquals('External method without an implementation.',
                         compiler.errors[0].message.toString());
   }));
 }
@@ -776,14 +823,14 @@
     }));
   }
 
-  expect('String s = 0;', MessageKind.NOT_ASSIGNABLE.warning);
-  expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE.warning);
+  expect('String s = 0;', MessageKind.NOT_ASSIGNABLE);
+  expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE);
   expect('''
          class Class {
            String s = 0;
          }
          ''',
-         MessageKind.NOT_ASSIGNABLE.warning);
+         MessageKind.NOT_ASSIGNABLE);
   expect('''
          class Class {
            void method() {
@@ -791,7 +838,7 @@
            }
          }
          ''',
-         MessageKind.NOT_ASSIGNABLE.warning);
+         MessageKind.NOT_ASSIGNABLE);
 }
 
 void testTypecheckPatchedMembers() {
@@ -806,13 +853,14 @@
     compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
     return compiler.runCompiler(null).then((_) {
       compareWarningKinds(patchText,
-          [MessageKind.NOT_ASSIGNABLE.warning], compiler.warnings);
+          [MessageKind.NOT_ASSIGNABLE], compiler.warnings);
     });
   }));
 }
 
 main() {
   testPatchConstructor();
+  testPatchRedirectingConstructor();
   testPatchFunction();
   testPatchMember();
   testPatchGetter();
diff --git a/tests/compiler/dart2js/private_test.dart b/tests/compiler/dart2js/private_test.dart
index 9857d54..45c41dd 100644
--- a/tests/compiler/dart2js/private_test.dart
+++ b/tests/compiler/dart2js/private_test.dart
@@ -75,22 +75,22 @@
 
 void main() {
   // Read from private variable.
-  analyze('var value = _privateVariable;', MessageKind.CANNOT_RESOLVE.warning);
+  analyze('var value = _privateVariable;', MessageKind.CANNOT_RESOLVE);
   // Write to private variable.
-  analyze('_privateVariable = 0;', MessageKind.CANNOT_RESOLVE.warning);
+  analyze('_privateVariable = 0;', MessageKind.CANNOT_RESOLVE);
   // Access private function.
-  analyze('var value = _privateFunction;', MessageKind.CANNOT_RESOLVE.warning);
+  analyze('var value = _privateFunction;', MessageKind.CANNOT_RESOLVE);
   // Call private function.
-  analyze('_privateFunction();', MessageKind.CANNOT_RESOLVE.warning);
+  analyze('_privateFunction();', MessageKind.CANNOT_RESOLVE);
 
   // Call unnamed (public) constructor on private class.
-  analyze('new _PrivateClass();', MessageKind.CANNOT_RESOLVE.warning);
+  analyze('new _PrivateClass();', MessageKind.CANNOT_RESOLVE);
   // Call public constructor on private class.
   analyze('new _PrivateClass.publicConstructor();',
-          MessageKind.CANNOT_RESOLVE.warning);
+          MessageKind.CANNOT_RESOLVE);
   // Call private constructor on private class.
   analyze('new _PrivateClass._privateConstructor();',
-      MessageKind.CANNOT_RESOLVE.warning);
+      MessageKind.CANNOT_RESOLVE);
   // Call public getter of private type.
   analyze('var value = publicClass.private;');
   // Read from private field on private class.
@@ -131,7 +131,7 @@
   analyze('publicClass = new PublicClass.publicConstructor();');
   // Call private constructor on public class.
   analyze('publicClass = new PublicClass._privateConstructor();',
-      MessageKind.CANNOT_FIND_CONSTRUCTOR.warning);
+      MessageKind.CANNOT_FIND_CONSTRUCTOR);
   // Read from private field on public class.
   analyze('var value = publicClass._privateField;',
       MessageKind.PRIVATE_ACCESS);
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index fd1534a..5673e4a 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -114,9 +114,11 @@
 """);
   compiler.resolveStatement("Bar bar;");
   ClassElement classBar = compiler.mainApp.find("Bar");
-  Expect.equals(1, compiler.errors.length);
   Expect.equals(0, compiler.warnings.length);
-  Expect.equals(MessageKind.MULTI_INHERITANCE, compiler.errors[0].message.kind);
+  Expect.equals(0, compiler.errors.length);
+  Expect.equals(1, compiler.crashes.length);
+  Expect.equals(MessageKind.MULTI_INHERITANCE,
+                compiler.crashes[0].message.kind);
 }
 
 testTypeVariables() {
@@ -150,7 +152,7 @@
   compiler.parseScript('class Foo<T, U> {}');
   compiler.resolveStatement('Foo<notype, int> x;');
   Expect.equals(1, compiler.warnings.length);
-  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE.warning,
+  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
                 compiler.warnings[0].message.kind);
   Expect.equals(0, compiler.errors.length);
 
@@ -159,7 +161,7 @@
   compiler.resolveStatement('var x = new Foo<notype, int>();');
   Expect.equals(1, compiler.warnings.length);
   Expect.equals(0, compiler.errors.length);
-  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE.warning,
+  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
                 compiler.warnings[0].message.kind);
 
   compiler = new MockCompiler();
@@ -438,7 +440,7 @@
 
   Expect.equals(
       new Message(
-          MessageKind.CANNOT_RESOLVE_TYPE.warning,  {'typeName': 'Foo'}, false),
+          MessageKind.CANNOT_RESOLVE_TYPE,  {'typeName': 'Foo'}, false),
       compiler.warnings[0].message);
   VariableDefinitions definition = compiler.parsedTree;
   Expect.equals(warningNode, definition.type);
@@ -487,7 +489,7 @@
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
       new Message(
-          MessageKind.CANNOT_RESOLVE_TYPE.warning, {'typeName': 'var'}, false),
+          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'var'}, false),
       compiler.errors[0].message);
   compiler.clearMessages();
 }
@@ -499,7 +501,7 @@
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
       new Message(
-          MessageKind.CANNOT_RESOLVE_TYPE.warning, {'typeName': 'bar'}, false),
+          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'bar'}, false),
       compiler.errors[0].message);
   compiler.clearMessages();
 
@@ -584,7 +586,7 @@
   compiler.resolver.resolve(fooElement);
 
   compareWarningKinds(
-      script, [MessageKind.INVALID_ARGUMENTS.warning], compiler.warnings);
+      script, [MessageKind.INVALID_ARGUMENTS], compiler.warnings);
   compareWarningKinds(script, [], compiler.errors);
 }
 
@@ -665,7 +667,7 @@
   Expect.equals(2, compiler.errors.length);
   Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                 compiler.errors[0].message.kind);
-  Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR.error,
+  Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR,
                 compiler.errors[1].message.kind);
 
   compiler = new MockCompiler();
@@ -732,9 +734,10 @@
   mainElement = compiler.mainApp.find(MAIN);
   compiler.resolver.resolve(mainElement);
   Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.errors.length);
+  Expect.equals(0, compiler.errors.length);
+  Expect.equals(1, compiler.crashes.length);
   Expect.equals(MessageKind.MULTI_INHERITANCE,
-                compiler.errors[0].message.kind);
+                compiler.crashes[0].message.kind);
 }
 
 testInitializers() {
@@ -767,7 +770,7 @@
               }""";
   resolveConstructor(script, "A a = new A();", "A", "", 0,
                      expectedWarnings: [],
-                     expectedErrors: [MessageKind.CANNOT_RESOLVE.error]);
+                     expectedErrors: [MessageKind.CANNOT_RESOLVE]);
 
   script = """class A {
                 int foo;
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index 19926f0..97531a6 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 class X {}
@@ -64,7 +65,7 @@
     checkReturn(String name, type) {
       var element = findElement(compiler, name);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler));
     }
 
     var subclassOfInterceptor =
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index 3476096..13cca3a 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 returnInt1() {
@@ -123,7 +124,7 @@
     checkReturn(String name, type) {
       var element = findElement(compiler, name);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
           name);
     }
 
@@ -142,7 +143,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(methodName);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler));
     }
     var cls = findElement(compiler, 'A');
     checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls));
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
index 184229a..8e1ef62 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -35,7 +36,7 @@
       var signature = functionElement.functionSignature;
       var element = signature.requiredParameters.first;
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getTypeOfElement(element), compiler),
           functionName);
     }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
index 36c988d..9a2fb7c 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -36,7 +37,7 @@
       var signature = functionElement.functionSignature;
       var element = signature.requiredParameters.first;
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getTypeOfElement(element), compiler),
           functionName);
     }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
index 46b4e83..50d6f2a 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -36,7 +37,7 @@
       var signature = functionElement.functionSignature;
       var element = signature.requiredParameters.first;
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getTypeOfElement(element), compiler),
           functionName);
     }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index 592346b..817747c 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -8,6 +8,7 @@
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -33,7 +34,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(fieldName);
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getTypeOfElement(element), compiler));
     }
 
     checkFieldTypeInClass('A', 'dynamicField',
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 15f77ab..29d0940 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -6,6 +6,7 @@
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -36,7 +37,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(fieldName);
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getTypeOfElement(element), compiler));
     }
 
     checkFieldTypeInClass('A', 'intField', compiler.typesTask.uint31Type);
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 0b9510e..2d673f1 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -35,7 +36,7 @@
       var signature = functionElement.functionSignature;
       var element = signature.requiredParameters.first;
       Expect.equals(type,
-          typesInferrer.getTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getTypeOfElement(element), compiler),
           functionName);
     }
 
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 3daef45..9e3a987 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -7,6 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST1 = """
 class A {
@@ -101,7 +102,7 @@
     var element = findElement(compiler, name);
     Expect.equals(
         type,
-        typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+        simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
         name);
   }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index 0b1e8b0..2050354 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -6,6 +6,7 @@
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 
@@ -72,7 +73,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(methodName);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
           methodName);
     }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index b2dd57f..10d4d66 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -7,9 +7,11 @@
 import
     '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
     show TypeMask;
+import 'type_mask_test_helper.dart';
 
 import 'compiler_helper.dart';
 import 'parser_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 returnNum1(a) {
@@ -714,7 +716,7 @@
       var element = findElement(compiler, name);
       Expect.equals(
           type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
           name);
     }
     var interceptorType =
@@ -775,9 +777,11 @@
     checkReturn('returnTopLevelGetter', typesTask.uint31Type);
     checkReturn('testDeadCode', typesTask.uint31Type);
     checkReturn('testLabeledIf', typesTask.uint31Type.nullable());
-    checkReturn('testSwitch1', typesTask.intType
-        .union(typesTask.doubleType, compiler)
-        .nullable().simplify(compiler));
+    checkReturn('testSwitch1', simplify(
+        typesTask.intType
+            .union(typesTask.doubleType, compiler)
+            .nullable(),
+        compiler));
     checkReturn('testSwitch2', typesTask.uint31Type);
     checkReturn('testSwitch3', interceptorType.nullable());
     checkReturn('testSwitch4', typesTask.uint31Type);
@@ -800,7 +804,7 @@
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(methodName);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
           '$className:$methodName');
     }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 331f76a..10aedf9 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -8,6 +8,7 @@
     show TypeMask;
 
 import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
 
 const String TEST = """
 returnInt1() {
@@ -174,7 +175,7 @@
     checkReturn(String name, type) {
       var element = findElement(compiler, name);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          simplify(typesInferrer.getReturnTypeOfElement(element), compiler));
     }
 
     checkReturn('returnInt1', typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart
index f755503..2cc9827 100644
--- a/tests/compiler/dart2js/subtype_test.dart
+++ b/tests/compiler/dart2js/subtype_test.dart
@@ -62,6 +62,14 @@
     DartType int_ = env['int'];
     DartType String_ = env['String'];
     DartType dynamic_ = env['dynamic'];
+    DartType void_ = env['void'];
+
+    expect(true, void_, void_);
+    expect(true, void_, dynamic_);
+    // Unsure about the next one, see dartbug.com/14933.
+    expect(true, dynamic_, void_, expectMoreSpecific: false);
+    expect(false, void_, Object_);
+    expect(false, Object_, void_);
 
     expect(true, Object_, Object_);
     expect(true, num_, Object_);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 4a3d53d..88e1ce7 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -17,8 +17,8 @@
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 
-final MessageKind NOT_ASSIGNABLE = MessageKind.NOT_ASSIGNABLE.warning;
-final MessageKind MEMBER_NOT_FOUND = MessageKind.MEMBER_NOT_FOUND.warning;
+final MessageKind NOT_ASSIGNABLE = MessageKind.NOT_ASSIGNABLE;
+final MessageKind MEMBER_NOT_FOUND = MessageKind.MEMBER_NOT_FOUND;
 
 DartType voidType;
 DartType intType;
@@ -604,14 +604,11 @@
   check(c, "int k = staticMethod('string');");
   check(c, "String k = staticMethod('string');",
         NOT_ASSIGNABLE);
-  check(d, "staticMethod();",
-        MessageKind.MISSING_ARGUMENT);
-  check(d, "staticMethod(1);",
-        NOT_ASSIGNABLE);
-  check(d, "staticMethod('string');");
-  check(d, "int k = staticMethod('string');");
-  check(d, "String k = staticMethod('string');",
-        NOT_ASSIGNABLE);
+  check(d, "staticMethod();", MessageKind.METHOD_NOT_FOUND);
+  check(d, "staticMethod(1);", MessageKind.METHOD_NOT_FOUND);
+  check(d, "staticMethod('string');", MessageKind.METHOD_NOT_FOUND);
+  check(d, "int k = staticMethod('string');", MessageKind.METHOD_NOT_FOUND);
+  check(d, "String k = staticMethod('string');", MessageKind.METHOD_NOT_FOUND);
 
   // Invocation on dynamic variable.
   check(c, "e.foo();");
@@ -1127,7 +1124,7 @@
 
   analyzeIn(method, "{ String typeName = T.toString(); }");
   analyzeIn(method, "{ T.foo; }", MEMBER_NOT_FOUND);
-  analyzeIn(method, "{ T.foo = 0; }", MessageKind.PROPERTY_NOT_FOUND);
+  analyzeIn(method, "{ T.foo = 0; }", MessageKind.SETTER_NOT_FOUND);
   analyzeIn(method, "{ T.foo(); }", MessageKind.METHOD_NOT_FOUND);
   analyzeIn(method, "{ T + 1; }", MessageKind.OPERATOR_NOT_FOUND);
 }
@@ -1536,10 +1533,8 @@
   check("int v = c.overriddenField;");
   check("c.overriddenField = 0;");
   check("int v = c.getterField;");
-  // TODO(johnniwinther): Check write of property without setter.
-  //check("c.getterField = 0;", MessageKind.CANNOT_RESOLVE_SETTER);
-  // TODO(johnniwinther): Check read of property without getter.
-  //check("int v = c.setterField;", MessageKind.CANNOT_RESOLVE_GETTER);
+  check("c.getterField = 0;", MessageKind.SETTER_NOT_FOUND);
+  check("int v = c.setterField;", MessageKind.GETTER_NOT_FOUND);
   check("c.setterField = 0;");
 
   check("int v = gc.overriddenField;");
@@ -1547,15 +1542,13 @@
   check("int v = gc.setterField;");
   check("gc.setterField = 0;");
   check("int v = gc.getterField;");
-  // TODO(johnniwinther): Check write of property without setter.
-  //check("gc.getterField = 0;", MessageKind.CANNOT_RESOLVE_SETTER);
+  check("gc.getterField = 0;", MessageKind.SETTER_NOT_FOUND);
 
   check("int v = sc.overriddenField;");
   check("sc.overriddenField = 0;");
   check("int v = sc.getterField;");
   check("sc.getterField = 0;");
-  // TODO(johnniwinther): Check read of property without getter.
-  //check("int v = sc.setterField;", MessageKind.CANNOT_RESOLVE_GETTER);
+  check("int v = sc.setterField;", MessageKind.GETTER_NOT_FOUND);
   check("sc.setterField = 0;");
 }
 
@@ -1592,7 +1585,7 @@
             if (a is C) {
               var x = a.c;
             }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [MessageKind.NOT_MORE_SPECIFIC_SUBTYPE],
         infos: []);
 
@@ -1601,8 +1594,8 @@
             if (a is C) {
               var x = '${a.c}${a.c}';
             }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning,
-                   MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND,
+                   MessageKind.MEMBER_NOT_FOUND],
         hints: [MessageKind.NOT_MORE_SPECIFIC_SUBTYPE],
         infos: []);
 
@@ -1611,8 +1604,8 @@
             if (a is C) {
               var x = '${a.d}${a.d}'; // Type promotion wouldn't help.
             }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning,
-                   MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND,
+                   MessageKind.MEMBER_NOT_FOUND],
         hints: [],
         infos: []);
 
@@ -1621,7 +1614,7 @@
            if (d is E) { // Suggest E<int>.
              var x = d.e;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [checkMessage(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
                              {'shownTypeSuggestion': 'E<int>'})],
         infos: []);
@@ -1631,7 +1624,7 @@
            if (d is F) { // Suggest F<int, dynamic>.
              var x = d.f;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [checkMessage(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
                              {'shownTypeSuggestion': 'F<int, dynamic>'})],
         infos: []);
@@ -1641,7 +1634,7 @@
            if (d is G) { // Suggest G<int>.
              var x = d.f;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [checkMessage(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
                              {'shownTypeSuggestion': 'G<int>'})],
         infos: []);
@@ -1651,7 +1644,7 @@
            if (f is G) { // Cannot suggest a more specific type.
              var x = f.g;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [MessageKind.NOT_MORE_SPECIFIC],
         infos: []);
 
@@ -1660,7 +1653,7 @@
            if (d is E) {
              var x = d.f; // Type promotion wouldn't help.
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [],
         infos: []);
 
@@ -1670,7 +1663,7 @@
              a = null;
              var x = a.b;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [MessageKind.POTENTIAL_MUTATION],
         infos: [MessageKind.POTENTIAL_MUTATION_HERE]);
 
@@ -1680,7 +1673,7 @@
              a = null;
              var x = a.c; // Type promotion wouldn't help.
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [],
         infos: []);
 
@@ -1690,7 +1683,7 @@
            if (a is B) {
              var x = a.b;
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [MessageKind.POTENTIAL_MUTATION_IN_CLOSURE],
         infos: [MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE]);
 
@@ -1700,7 +1693,7 @@
            if (a is B) {
              var x = a.c; // Type promotion wouldn't help.
            }''',
-        warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+        warnings: [MessageKind.MEMBER_NOT_FOUND],
         hints: [],
         infos: []);
 
@@ -1711,7 +1704,7 @@
              var y = a.b;
            }
            a = new A();''',
-      warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+      warnings: [MessageKind.MEMBER_NOT_FOUND],
       hints: [MessageKind.ACCESSED_IN_CLOSURE],
       infos: [MessageKind.ACCESSED_IN_CLOSURE_HERE,
               MessageKind.POTENTIAL_MUTATION_HERE]);
@@ -1723,7 +1716,7 @@
              var y = a.c; // Type promotion wouldn't help.
            }
            a = new A();''',
-      warnings: [MessageKind.MEMBER_NOT_FOUND.warning],
+      warnings: [MessageKind.MEMBER_NOT_FOUND],
       hints: [],
       infos: []);
 }
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index ada744d4..a6d9f8c 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -7,6 +7,7 @@
 import "parser_helper.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/ssa/ssa.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/types/types.dart";
+import "type_mask_test_helper.dart";
 
 TypeMask nullType;
 TypeMask objectType;
@@ -97,7 +98,7 @@
 
 void testUnion(MockCompiler compiler) {
   RuleSet ruleSet = new RuleSet('union',
-      (t1, t2) => t1.union(t2, compiler).simplify(compiler));
+      (t1, t2) => simplify(t1.union(t2, compiler), compiler));
   rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
   check(type1, type2, predicate) => ruleSet.check(type1, type2, predicate);
 
diff --git a/tests/compiler/dart2js/type_mask_test_helper.dart b/tests/compiler/dart2js/type_mask_test_helper.dart
new file mode 100644
index 0000000..88f234d
--- /dev/null
+++ b/tests/compiler/dart2js/type_mask_test_helper.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library type_mask_test_helper;
+
+import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+    show Compiler;
+
+TypeMask simplify(TypeMask mask, Compiler compiler) {
+  if (mask is ForwardingTypeMask) {
+    return simplify(mask.forwardTo, compiler);
+  } else if (mask is UnionTypeMask) {
+    return UnionTypeMask.flatten(mask.disjointMasks, compiler);
+  } else {
+    return mask;
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/16967_test.dart b/tests/compiler/dart2js_extra/16967_test.dart
new file mode 100644
index 0000000..26d9df7
--- /dev/null
+++ b/tests/compiler/dart2js_extra/16967_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+// Regression test for http://dartbug.com/16967
+// Tests type propagation of negation.
+
+void main() {
+  new Foo().test();
+}
+
+class Foo {
+  var scale = 1;
+
+  void test() {
+    var scaleX = scale;
+    var scaleY = scale;
+    var flipX = true;
+
+    if (flipX) {
+      scaleX = -scaleX;
+    }
+
+    Expect.equals('X: -1, Y: 1', 'X: $scaleX, Y: $scaleY');
+    Expect.equals('true', '${scaleX < 0}', '$scaleX < 0');
+    Expect.equals('false', '${scaleY < 0}', '$scaleY < 0');
+  }
+}
diff --git a/tests/compiler/dart2js_extra/17094_test.dart b/tests/compiler/dart2js_extra/17094_test.dart
new file mode 100644
index 0000000..25452f2
--- /dev/null
+++ b/tests/compiler/dart2js_extra/17094_test.dart
@@ -0,0 +1,35 @@
+// 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 "package:expect/expect.dart";
+
+//  Interpolation effect analysis test.
+
+get never => new DateTime.now().millisecondsSinceEpoch == 0;
+
+class A {
+  int a = 0;
+  toString() { ++a; return 'A'; }
+}
+
+// Many interpolations to make function too big to inline.
+// Summary for [fmt] must include effects from toString().
+fmt(x) => '$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x';
+
+test(a) {
+  if (a == null) return;
+  if (never) a.a += 1;
+  var b = a.a;     // field load
+  var c = fmt(a);  // field modified through implicit call to toString()
+  var d = a.a;     // field re-load
+  Expect.equals('A 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 30', '$a $b $c $d');
+
+  // Extra use of [fmt] to prevent inlining on basis of single reference.
+  Expect.equals('', fmt(''));
+}
+
+main() {
+  test(null);
+  test(new A());
+}
diff --git a/tests/compiler/dart2js_extra/bound_closure_interceptor_type_test.dart b/tests/compiler/dart2js_extra/bound_closure_interceptor_type_test.dart
index 0216c7d..fa1b7a1 100644
--- a/tests/compiler/dart2js_extra/bound_closure_interceptor_type_test.dart
+++ b/tests/compiler/dart2js_extra/bound_closure_interceptor_type_test.dart
@@ -104,7 +104,7 @@
     }
   }
 
-  var objectsDyn = [[], new A(), new A<Dynamic>()];
+  var objectsDyn = [[], new A(), new A<dynamic>()];
   var objectsInt = [<int>[], new A<int>()];
   var objectsStr = [<String>[], new A<String>()];
   var objectsLst = [<List>[], new A<List>()];
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 504e89f..775060a 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -10,6 +10,7 @@
 no_such_method_test: Fail # Wrong Invocation.memberName.
 deferred/deferred_constant_test: Fail # http://dartbug.com/11138
 constant_javascript_semantics4_test: Fail, OK
+17094_test: Fail # http://dartbug.com/17094
 
 [ $compiler == dart2js && $runtime == jsshell ]
 mirror_printer_test: Pass, Slow # Issue 16473
@@ -18,7 +19,7 @@
 variable_type_test/03: Fail, OK
 variable_type_test/01: Fail, OK
 
-[ $compiler == dart2js && $checked && ($runtime == d8 || $runtime == chrome) ]
+[ $compiler == dart2js && ($runtime == d8 || $runtime == chrome || $runtime == drt) ]
 bound_closure_interceptor_type_test: Fail, Pass # v8 issue 3084. https://code.google.com/p/v8/issues/detail?id=3084
 
 [ $compiler == dart2js && $host_checked && $checked == false ]
@@ -56,9 +57,9 @@
 bailout8_test: Fail, OK # Mismatch in thrown exception.
 
 [ $csp ]
-deferred/deferred_class_test: Fail # http://dartbug.com/3940
-deferred/deferred_constant_test: Fail # http://dartbug.com/3940
-deferred/deferred_constant2_test: Fail # http://dartbug.com/3940
-deferred/deferred_constant3_test: Fail # http://dartbug.com/3940
-deferred/deferred_constant4_test: Fail # http://dartbug.com/3940
-deferred/deferred_constant5_test: Fail # http://dartbug.com/3940
+deferred/deferred_class_test: Fail # http://dartbug.com/16898
+deferred/deferred_constant_test: Fail # http://dartbug.com/16898
+deferred/deferred_constant2_test: Fail # http://dartbug.com/16898
+deferred/deferred_constant3_test: Fail # http://dartbug.com/16898
+deferred/deferred_constant4_test: Fail # http://dartbug.com/16898
+deferred/deferred_constant5_test: Fail # http://dartbug.com/16898
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
index 7b6279b..ae4964a 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_class_library.dart';
+@lazy import 'deferred_class_library.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library');
 
@@ -15,7 +15,7 @@
 
 main() {
   var x;
-  Expect.throws(() { x = new MyClass(); }, isNoSuchMethodError);
+  Expect.throws(() { x = new lib.MyClass(); }, isNoSuchMethodError);
   Expect.isNull(x);
   int counter = 0;
   asyncStart();
@@ -23,7 +23,7 @@
     Expect.isTrue(didLoad);
     Expect.equals(1, ++counter);
     print('deferred_class_library was loaded');
-    x = new MyClass();
+    x = new lib.MyClass();
     Expect.equals(42, x.foo(87));
     asyncEnd();
   });
@@ -34,12 +34,12 @@
     Expect.isFalse(didLoad);
     Expect.equals(2, ++counter);
     print('deferred_class_library was loaded');
-    x = new MyClass();
+    x = new lib.MyClass();
     Expect.equals(42, x.foo(87));
     asyncEnd();
   });
   Expect.equals(0, counter);
   Expect.isNull(x);
-  Expect.throws(() { x = new MyClass(); }, isNoSuchMethodError);
+  Expect.throws(() { x = new lib.MyClass(); }, isNoSuchMethodError);
   Expect.isNull(x);
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
index db7e9eb..cb67911 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_class_library2.dart';
+@lazy import 'deferred_class_library2.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library2');
 
@@ -15,7 +15,7 @@
   asyncStart();
   lazy.load().then((bool didLoad) {
     Expect.isTrue(didLoad);
-    Expect.equals(499, C1.value);
+    Expect.equals(499, lib.C1.value);
     asyncEnd();
   });
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
index 8ae2b12..876dfa3 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_class_library2.dart';
+@lazy import 'deferred_class_library2.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library2');
 
@@ -15,19 +15,19 @@
   asyncStart();
   lazy.load().then((bool didLoad) {
     Expect.isTrue(didLoad);
-    Expect.equals(499, C1.value);
-    Expect.equals(99, C2[0].value);
-    Expect.equals(42, foo().value);
-    Expect.equals(777, bar().value);
-    Expect.equals(111, new Gee().value);
-    Expect.equals(321, new Gee.n321().value);
-    Expect.equals(135, new Gee.n135().value);
-    Expect.equals(246, new Gee.n246().value);
-    Expect.equals(888, new Gee.n888().value);
-    Expect.equals(979, new Gee2().value);
-    Expect.equals(321, new Gee2.n321().value);
-    Expect.equals(151, new Gee2.n151().value);
-    Expect.equals(888, new Gee2.n888().value);
+    Expect.equals(499, lib.C1.value);
+    Expect.equals(99, lib.C2[0].value);
+    Expect.equals(42, lib.foo().value);
+    Expect.equals(777, lib.bar().value);
+    Expect.equals(111, new lib.Gee().value);
+    Expect.equals(321, new lib.Gee.n321().value);
+    Expect.equals(135, new lib.Gee.n135().value);
+    Expect.equals(246, new lib.Gee.n246().value);
+    Expect.equals(888, new lib.Gee.n888().value);
+    Expect.equals(979, new lib.Gee2().value);
+    Expect.equals(321, new lib.Gee2.n321().value);
+    Expect.equals(151, new lib.Gee2.n151().value);
+    Expect.equals(888, new lib.Gee2.n888().value);
     asyncEnd();
   });
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
index 7d0cc91..e22d11b 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_class_library2.dart';
+@lazy import 'deferred_class_library2.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library2');
 
@@ -16,7 +16,7 @@
   lazy.load().then((bool didLoad) {
     Expect.isTrue(didLoad);
     // Only Gee2.n888 to make sure no other constant pulls in its super.
-    Expect.equals(888, new Gee2.n888().value);
+    Expect.equals(888, new lib.Gee2.n888().value);
     asyncEnd();
   });
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart
index 14abc76..e0d241c 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_class_library2.dart';
+@lazy import 'deferred_class_library2.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library2');
 
@@ -15,12 +15,12 @@
   asyncStart();
   lazy.load().then((bool didLoad) {
     Expect.isTrue(didLoad);
-    Expect.equals(321, const Gee.n321().value);
-    Expect.equals(246, const Gee.n246().value);
-    Expect.equals(888, const Gee.n888().value);
-    Expect.equals(321, const Gee2.n321().value);
-    Expect.equals(151, const Gee2.n151().value);
-    Expect.equals(888, const Gee2.n888().value);
+    Expect.equals(321, const lib.Gee.n321().value);
+    Expect.equals(246, const lib.Gee.n246().value);
+    Expect.equals(888, const lib.Gee.n888().value);
+    Expect.equals(321, const lib.Gee2.n321().value);
+    Expect.equals(151, const lib.Gee2.n151().value);
+    Expect.equals(888, const lib.Gee2.n888().value);
     asyncEnd();
   });
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
index 406eb4a..09b27f0 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
@@ -10,7 +10,7 @@
 
 import 'dart:async';
 
-@lazy import 'deferred_function_library.dart';
+@lazy import 'deferred_function_library.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_function_library');
 
@@ -20,11 +20,11 @@
   // TODO(ahe): There is a problem with type inference of deferred
   // function closures.  We think they are never null.
   if (new DateTime.now().millisecondsSinceEpoch == 87) return null;
-  return foo;
+  return lib.foo;
 }
 
 main() {
-  Expect.throws(() { foo('a'); }, isNoSuchMethodError);
+  Expect.throws(() { lib.foo('a'); }, isNoSuchMethodError);
   Expect.throws(readFoo, isNoSuchMethodError);
   int counter = 0;
   asyncStart();
@@ -32,7 +32,7 @@
     Expect.isTrue(didLoad);
     Expect.equals(1, ++counter);
     print('lazy was loaded');
-    Expect.equals(42, foo('b'));
+    Expect.equals(42, lib.foo('b'));
     Expect.isNotNull(readFoo());
     asyncEnd();
   });
@@ -42,11 +42,11 @@
     Expect.isFalse(didLoad);
     Expect.equals(2, ++counter);
     print('lazy was loaded');
-    Expect.equals(42, foo('b'));
+    Expect.equals(42, lib.foo('b'));
     Expect.isNotNull(readFoo());
     asyncEnd();
   });
   Expect.equals(0, counter);
-  Expect.throws(() { foo('a'); }, isNoSuchMethodError);
+  Expect.throws(() { lib.foo('a'); }, isNoSuchMethodError);
   Expect.throws(readFoo, isNoSuchMethodError);
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_unused_classes_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_unused_classes_test.dart
index db4389e..c8b76f0 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_unused_classes_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_unused_classes_test.dart
@@ -7,7 +7,7 @@
 import "package:expect/expect.dart";
 import 'dart:async';
 
-@lazy import 'deferred_class_library.dart';
+@lazy import 'deferred_class_library.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_class_library');
 
diff --git a/tests/compiler/dart2js_extra/regress/4492_test.dart b/tests/compiler/dart2js_extra/regress/4492_test.dart
index a80ae98..2b3d6c8 100644
--- a/tests/compiler/dart2js_extra/regress/4492_test.dart
+++ b/tests/compiler/dart2js_extra/regress/4492_test.dart
@@ -12,5 +12,6 @@
   }
 }
 
-main() => Expect.throws(() => new A().x(1, 2),
-                        (e) => e is NoSuchMethodError);
+main() {
+  Expect.throws(() => new A().x(1, 2));
+}
diff --git a/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
new file mode 100644
index 0000000..14ff9a5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
Binary files differ
diff --git a/tests/compiler/dart2js_extra/string_interpolation_opt1_test.dart b/tests/compiler/dart2js_extra/string_interpolation_opt1_test.dart
new file mode 100644
index 0000000..329d633
--- /dev/null
+++ b/tests/compiler/dart2js_extra/string_interpolation_opt1_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+// Test that String interpolation works in some optimized cases.
+
+bool get inscrutableFalse => new Random().nextDouble() > 2;
+
+returnsNullOrString(x) {
+  if (inscrutableFalse) return 'hi';
+  if (inscrutableFalse) return null;
+  return x;
+}
+
+returnsNullOrInt(x) {
+  if (inscrutableFalse) return 123;
+  if (inscrutableFalse) return null;
+  return x;
+}
+
+spoil(a) {
+  a[3] = 123;
+  a[4] = 'ddd';
+}
+
+void testString() {
+  var a = new List(100);  // 'null' values in here are JavaScript undefined.
+  spoil(a);
+  var s = returnsNullOrString('hi');
+  var x = a[2];
+  if (x == null) {
+    s = returnsNullOrString(x);
+  }
+
+  Expect.equals('s: null', 's: $s');
+}
+
+void testInt() {
+  var a = new List(100);  // 'null' values in here are JavaScript undefined.
+  spoil(a);
+  var s = returnsNullOrInt(123);
+  var x = a[2];
+  if (x == null) {
+    s = returnsNullOrInt(x);
+  }
+
+  Expect.equals('s: null', 's: $s');
+}
+
+void main() {
+  testInt();
+  testString();
+}
diff --git a/tests/compiler/dart2js_native/compute_this_script_test.dart b/tests/compiler/dart2js_native/compute_this_script_test.dart
index 55092b4..e8316e8 100644
--- a/tests/compiler/dart2js_native/compute_this_script_test.dart
+++ b/tests/compiler/dart2js_native/compute_this_script_test.dart
@@ -5,8 +5,14 @@
 // Test of IsolateNatives.computeThisScript().
 
 import 'dart:_isolate_helper';
+// The isolate helper library is not correctly set up if the dart:isolate
+// library hasn't been loaded.
+import 'dart:isolate';
 
 main() {
+  // Need to use the isolate-library so dart2js correctly initializes the
+  // library.
+  Capability cab = new Capability();
   String script = IsolateNatives.computeThisScript();
 
   // This is somewhat brittle and relies on an implementation detail
diff --git a/tests/corelib/apply2_test.dart b/tests/corelib/apply2_test.dart
index f2984bf..021f415 100644
--- a/tests/corelib/apply2_test.dart
+++ b/tests/corelib/apply2_test.dart
@@ -29,6 +29,7 @@
   var c4 = ({a: 1}) => 'c4 $a';
   var c5 = ({a: 1, b: 2}) => 'c5 $a $b';
   var c6 = ({b: 1, a: 2}) => 'c6 $a $b';
+  var c7 = (x, {b: 1, a: 2}) => 'c7 $x $a $b';
 
   Expect.equals('c1', apply(c1, new ArgumentDescriptor(null, null)));
   Expect.equals('c1', apply(c1, new ArgumentDescriptor([], null)));
@@ -87,4 +88,18 @@
   throwsNSME(() => apply(c6, new ArgumentDescriptor([1], {})));
   throwsNSME(() =>
       apply(c6, new ArgumentDescriptor([], {'a': 1, 'b': 2, 'c': 3})));
+
+  Expect.equals('c7 7 2 1', apply(c7, new ArgumentDescriptor([7], null)));
+  Expect.equals('c7 7 3 1', apply(c7, new ArgumentDescriptor([7], {'a': 3})));
+  Expect.equals('c7 7 2 1', apply(c7, new ArgumentDescriptor([7], {})));
+  Expect.equals('c7 7 3 4',
+      apply(c7, new ArgumentDescriptor([7], {'a': 3, 'b': 4})));
+  Expect.equals('c7 7 4 3',
+      apply(c7, new ArgumentDescriptor([7], {'b': 3, 'a': 4})));
+  Expect.equals('c7 7 2 3',
+      apply(c7, new ArgumentDescriptor([7], {'b': 3})));
+  throwsNSME(() => apply(c7, new ArgumentDescriptor([], {'a': 1})));
+  throwsNSME(() => apply(c7, new ArgumentDescriptor([], {})));
+  throwsNSME(() =>
+      apply(c7, new ArgumentDescriptor([7], {'a': 1, 'b': 2, 'c': 3})));
 }
diff --git a/tests/corelib/core_runtime_types_test.dart b/tests/corelib/core_runtime_types_test.dart
index ee91954..017df05 100644
--- a/tests/corelib/core_runtime_types_test.dart
+++ b/tests/corelib/core_runtime_types_test.dart
@@ -83,9 +83,10 @@
   static testOperatorErrors() {
     var objs = [1, '2', [3], null, true, new Map()];
     for (var i=0; i < objs.length; i++) {
-      for (var j=i+1; j < objs.length; j++) {
+      for (var j= i + 1; j < objs.length; j++) {
         testBinaryOperatorErrors(objs[i], objs[j]);
-        testBinaryOperatorErrors(objs[j], objs[i]);
+        // Allow "String * int".
+        if (j > 2) testBinaryOperatorErrors(objs[j], objs[i]);
       }
       if (objs[i] != 1) {
         testUnaryOperatorErrors(objs[i]);
diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart
index 805d5c6..dcd656d 100644
--- a/tests/corelib/date_time_test.dart
+++ b/tests/corelib/date_time_test.dart
@@ -6,827 +6,923 @@
 
 // Dart test program for DateTime.
 
-class DateTest {
-  // Tests if the time moves eventually forward.
-  static void testNow() {
-    var t1 = new DateTime.now();
-    bool timeMovedForward = false;
-    for (int i = 0; i < 1000000; i++) {
-      var t2 = new DateTime.now();
-      if (t1.millisecondsSinceEpoch < t2.millisecondsSinceEpoch) {
-        timeMovedForward = true;
-        break;
-      }
+// Tests if the time moves eventually forward.
+void testNow() {
+  var t1 = new DateTime.now();
+  bool timeMovedForward = false;
+  for (int i = 0; i < 1000000; i++) {
+    var t2 = new DateTime.now();
+    if (t1.millisecondsSinceEpoch < t2.millisecondsSinceEpoch) {
+      timeMovedForward = true;
+      break;
     }
-    Expect.equals(true, timeMovedForward);
-    Expect.isFalse(t1.isUtc);
   }
-
-  static void testValue() {
-    var dt1 = new DateTime.now();
-    var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch;
-    var dt2 = new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
-    Expect.equals(millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
-  }
-
-  static void testFarAwayDates() {
-    DateTime dt =
-        new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
-    Expect.equals(33658, dt.year);
-    Expect.equals(9, dt.month);
-    Expect.equals(27, dt.day);
-    Expect.equals(1, dt.hour);
-    Expect.equals(46, dt.minute);
-    Expect.equals(40, dt.second);
-    Expect.equals(1, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
-    Expect.equals(-29719, dt.year);
-    Expect.equals(4, dt.month);
-    Expect.equals(5, dt.day);
-    Expect.equals(22, dt.hour);
-    Expect.equals(13, dt.minute);
-    Expect.equals(19, dt.second);
-    Expect.equals(999, dt.millisecond);
-    // Same with local zone.
-    dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
-    Expect.equals(33658, dt.year);
-    Expect.equals(9, dt.month);
-    Expect.equals(true, dt.day == 27 || dt.day == 26);
-    // Not much we can test for local hour.
-    Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-    // Timezones can have offsets down to 15 minute.
-    Expect.equals(true, dt.minute % 15 == 46 % 15);
-    Expect.equals(40, dt.second);
-    Expect.equals(1, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
-    Expect.equals(-29719, dt.year);
-    Expect.equals(4, dt.month);
-    Expect.equals(true, 5 == dt.day || 6 == dt.day);
-    // Not much we can test for local hour.
-    Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-    // Timezones can have offsets down to 15 minute.
-    Expect.equals(true, dt.minute % 15 == 13);
-    Expect.equals(19, dt.second);
-    Expect.equals(999, dt.millisecond);
-  }
-
-  static void testEquivalentYears() {
-    // All hardcoded values come from V8. This means that the values are not
-    // necessarily correct (see limitations of DateTime object in
-    // EcmaScript 15.9.1 and in particular 15.9.1.8/9).
-    DateTime dt = new DateTime.fromMillisecondsSinceEpoch(-31485600000, isUtc: true);
-    Expect.equals(1969, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-63108000000, isUtc: true);
-    Expect.equals(1968, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-94644000000, isUtc: true);
-    Expect.equals(1967, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-126180000000, isUtc: true);
-    Expect.equals(1966, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-157716000000, isUtc: true);
-    Expect.equals(1965, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-2177402400000, isUtc: true);
-    Expect.equals(1901, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-5333076000000, isUtc: true);
-    Expect.equals(1801, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-8520285600000, isUtc: true);
-    Expect.equals(1700, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-14831719200000, isUtc: true);
-    Expect.equals(1500, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-59011408800000, isUtc: true);
-    Expect.equals(100, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(14, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-62011408800000, isUtc: true);
-    Expect.equals(4, dt.year);
-    Expect.equals(12, dt.month);
-    Expect.equals(8, dt.day);
-    Expect.equals(8, dt.hour);
-    Expect.equals(40, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-64011408800000, isUtc: true);
-    Expect.equals(-59, dt.year);
-    Expect.equals(7, dt.month);
-    Expect.equals(24, dt.day);
-    Expect.equals(5, dt.hour);
-    Expect.equals(6, dt.minute);
-    Expect.equals(40, dt.second);
-    Expect.equals(0, dt.millisecond);
-    final int SECONDS_YEAR_2035 = 2051222400;
-    dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1,
-                                             isUtc: true);
-    Expect.equals(2035, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(0, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(1, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1,
-                                             isUtc: true);
-    Expect.equals(2034, dt.year);
-    Expect.equals(12, dt.month);
-    Expect.equals(31, dt.day);
-    Expect.equals(23, dt.hour);
-    Expect.equals(59, dt.minute);
-    Expect.equals(59, dt.second);
-    Expect.equals(999, dt.millisecond);
-    dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 1);
-    Expect.equals(SECONDS_YEAR_2035 * 1000 + 1, dt.millisecondsSinceEpoch);
-    dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999);
-    Expect.equals(SECONDS_YEAR_2035 * 1000 - 1, dt.millisecondsSinceEpoch);
-    dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1);
-    Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
-                        (2034 == dt.year && 12 == dt.month && 31 == dt.day));
-    Expect.equals(0, dt.second);
-    Expect.equals(1, dt.millisecond);
-    DateTime dt2 = new DateTime(
-        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
-        dt.millisecond);
-    Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
-    dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1);
-    Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
-                        (2034 == dt.year && 12 == dt.month && 31 == dt.day));
-    Expect.equals(59, dt.second);
-    Expect.equals(999, dt.millisecond);
-    dt2 = new DateTime(
-        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
-        dt.millisecond);
-    Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
-    dt = new DateTime.fromMillisecondsSinceEpoch(2100000000 * 1000, isUtc: true);
-    Expect.equals(2036, dt.year);
-    Expect.equals(7, dt.month);
-    Expect.equals(18, dt.day);
-    Expect.equals(13, dt.hour);
-    Expect.equals(20, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    // Internally this will use the maximum value for the native calls.
-    dt = new DateTime(2036, 7, 18, 13, 20);
-    Expect.equals(2036, dt.year);
-    Expect.equals(7, dt.month);
-    Expect.equals(18, dt.day);
-    Expect.equals(13, dt.hour);
-    Expect.equals(20, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    Expect.equals("2036-07-18 13:20:00.000", dt.toString());
-  }
-
-  static void testExtremes() {
-    var dt =
-        new DateTime.fromMillisecondsSinceEpoch(8640000000000000, isUtc: true);
-    Expect.equals(275760, dt.year);
-    Expect.equals(9, dt.month);
-    Expect.equals(13, dt.day);
-    Expect.equals(0, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000, isUtc: true);
-    Expect.equals(-271821, dt.year);
-    Expect.equals(4, dt.month);
-    Expect.equals(20, dt.day);
-    Expect.equals(0, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(0, dt.millisecond);
-    // Make sure that we can build the extreme dates in local too.
-    dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000);
-    dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-    Expect.equals(8640000000000000, dt.millisecondsSinceEpoch);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000);
-    dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-    Expect.equals(-8640000000000000, dt.millisecondsSinceEpoch);
-    Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(8640000000000001,
-                                                            isUtc: true));
-    Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(-8640000000000001,
-                                                            isUtc: true));
-    Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(8640000000000001));
-    Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(-8640000000000001));
-    dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000);
-    Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
-                                 dt.hour, dt.minute, 0, 1));
-    dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000, isUtc: true);
-    Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
-                                     dt.hour, dt.minute, 0, 1));
-    dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000);
-    Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
-                                 dt.hour, dt.minute, 0, -1));
-    dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000, isUtc: true);
-    Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
-                                     dt.hour, dt.minute, 0, -1));
-  }
-
-  static void testUTCGetters() {
-    var dt = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
-    Expect.equals(2011, dt.year);
-    Expect.equals(5, dt.month);
-    Expect.equals(11, dt.day);
-    Expect.equals(18, dt.hour);
-    Expect.equals(58, dt.minute);
-    Expect.equals(35, dt.second);
-    Expect.equals(0, dt.millisecond);
-    Expect.equals(true, dt.isUtc);
-    Expect.equals(1305140315000, dt.millisecondsSinceEpoch);
-    dt = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
-    Expect.equals(1969, dt.year);
-    Expect.equals(12, dt.month);
-    Expect.equals(31, dt.day);
-    Expect.equals(21, dt.hour);
-    Expect.equals(13, dt.minute);
-    Expect.equals(20, dt.second);
-    Expect.equals(1, dt.millisecond);
-  }
-
-  static void testLocalGetters() {
-    var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
-    var dt2 = new DateTime.utc(dt1.year, dt1.month, dt1.day,
-                           dt1.hour, dt1.minute, dt1.second, dt1.millisecond);
-    Duration zoneOffset = dt1.difference(dt2);
-    Expect.equals(true, zoneOffset.inDays == 0);
-    Expect.equals(true, zoneOffset.inHours.abs() <= 12);
-    Expect.equals(dt1.year, dt2.year);
-    Expect.equals(dt1.month, dt2.month);
-    Expect.equals(true, (dt1.day - dt2.day).abs() <= 1);
-    Expect.equals(true, dt1.hour < 24);
-    // There are timezones with 0.5 or 0.25 hour offsets.
-    Expect.equals(true,
-                  (dt1.minute == dt2.minute) ||
-                  ((dt1.minute - dt2.minute).abs() == 30) ||
-                  ((dt1.minute - dt2.minute).abs() == 15));
-    Expect.equals(dt1.second, dt2.second);
-    Expect.equals(dt1.millisecond, dt2.millisecond);
-  }
-
-  static void testConstructors() {
-    var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
-    var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
-    Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
-    var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
-    Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
-    Expect.equals(false, dt1 == dt0);
-    Expect.equals(true, dt1 == dt0b);
-    var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-                       dt1.second, dt1.millisecond);
-    Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
-    Expect.equals(false, dt3 == dt0);
-    Expect.equals(true, dt1 == dt3);
-    dt3 = new DateTime(
-        dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-        dt1.second, dt1.millisecond);
-    Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
-    Expect.equals(true, dt1 == dt3);
-    var dt2 = dt1.toLocal();
-    dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0);
-    Expect.equals(dt2.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
-    Expect.equals(true, dt2 == dt3);
-    dt1 = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
-    dt3 = new DateTime.utc(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-                       dt1.second, dt1.millisecond);
-    Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
-    dt3 = new DateTime.utc(99, 1, 2, 10, 11, 12, 0);
-    Expect.equals(99, dt3.year);
-    Expect.equals(1, dt3.month);
-    Expect.equals(2, dt3.day);
-    Expect.equals(10, dt3.hour);
-    Expect.equals(11, dt3.minute);
-    Expect.equals(12, dt3.second);
-    Expect.equals(0, dt3.millisecond);
-    Expect.equals(true, dt3.isUtc);
-    var dt4 = new DateTime(99, 1, 2);
-    Expect.equals(99, dt4.year);
-    Expect.equals(1, dt4.month);
-    Expect.equals(2, dt4.day);
-    Expect.equals(0, dt4.hour);
-    Expect.equals(0, dt4.minute);
-    Expect.equals(0, dt4.second);
-    Expect.equals(0, dt4.millisecond);
-    Expect.isFalse(dt4.isUtc);
-    var dt5 = new DateTime.utc(99, 1, 2);
-    Expect.equals(99, dt5.year);
-    Expect.equals(1, dt5.month);
-    Expect.equals(2, dt5.day);
-    Expect.equals(0, dt5.hour);
-    Expect.equals(0, dt5.minute);
-    Expect.equals(0, dt5.second);
-    Expect.equals(0, dt5.millisecond);
-    Expect.isTrue(dt5.isUtc);
-    var dt6 = new DateTime(2012, 2, 27, 13, 27, 0);
-    Expect.equals(2012, dt6.year);
-    Expect.equals(2, dt6.month);
-    Expect.equals(27, dt6.day);
-    Expect.equals(13, dt6.hour);
-    Expect.equals(27, dt6.minute);
-    Expect.equals(0, dt6.second);
-    Expect.equals(0, dt6.millisecond);
-    Expect.isFalse(dt6.isUtc);
-    var dt7 = new DateTime.utc(2012, 2, 27, 13, 27, 0);
-    Expect.equals(2012, dt7.year);
-    Expect.equals(2, dt7.month);
-    Expect.equals(27, dt7.day);
-    Expect.equals(13, dt7.hour);
-    Expect.equals(27, dt7.minute);
-    Expect.equals(0, dt7.second);
-    Expect.equals(0, dt7.millisecond);
-    Expect.isTrue(dt7.isUtc);
-  }
-
-  static void testChangeTimeZone() {
-    var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
-    var dt2 = dt1.toUtc();
-    Expect.equals(dt1.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
-    var dt3 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
-    Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
-    Expect.equals(dt2.year, dt3.year);
-    Expect.equals(dt2.month, dt3.month);
-    Expect.equals(dt2.day, dt3.day);
-    Expect.equals(dt2.hour, dt3.hour);
-    Expect.equals(dt2.minute, dt3.minute);
-    Expect.equals(dt2.second, dt3.second);
-    Expect.equals(dt2.millisecond, dt3.millisecond);
-    var dt4 = dt3.toLocal();
-    Expect.equals(dt1.year, dt4.year);
-    Expect.equals(dt1.month, dt4.month);
-    Expect.equals(dt1.day, dt4.day);
-    Expect.equals(dt1.hour, dt4.hour);
-    Expect.equals(dt1.minute, dt4.minute);
-    Expect.equals(dt1.second, dt4.second);
-    Expect.equals(dt1.millisecond, dt4.millisecond);
-  }
-
-  static void testSubAdd() {
-    var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
-    var dt2 = dt1.add(new Duration(milliseconds:
-        3 * Duration.MILLISECONDS_PER_SECOND + 5));
-    Expect.equals(dt1.year, dt2.year);
-    Expect.equals(dt1.month, dt2.month);
-    Expect.equals(dt1.day, dt2.day);
-    Expect.equals(dt1.hour, dt2.hour);
-    Expect.equals(dt1.minute, dt2.minute);
-    Expect.equals(dt1.second + 3, dt2.second);
-    Expect.equals(dt1.millisecond + 5, dt2.millisecond);
-    var dt3 = dt2.subtract(new Duration(milliseconds:
-        3 * Duration.MILLISECONDS_PER_SECOND + 5));
-    Expect.equals(true, dt1 == dt3);
-    Expect.equals(false, dt1 == dt2);
-  }
-
-  static void testUnderflowAndOverflow() {
-    final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500);
-
-    // Millisecond
-    print("  >>> Millisecond+");
-    var dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                      dtBase.minute, dtBase.second, 1000);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second + 1, dt.second);
-    Expect.equals(0, dt.millisecond);
-
-    print("  >>> Millisecond-");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                  dtBase.minute, dtBase.second, -1000);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second - 1, dt.second);
-    Expect.equals(0, dt.millisecond);
-
-    // Second
-    print("  >>> Second+");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                  dtBase.minute, 60, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute + 1, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    print("  >>> Second-");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                  dtBase.minute, -60, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute - 1, dt.minute);
-    Expect.equals(0, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    // Minute
-    print("  >>> Minute+");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, 60,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour + 1, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    print("  >>> Minute-");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, -60,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour - 1, dt.hour);
-    Expect.equals(0, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    // Hour
-    print("  >>> Hour+");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, 24, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day + 1, dt.day);
-    Expect.equals(0, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    print("  >>> Hour-");
-    dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, -24, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month, dt.month);
-    Expect.equals(dtBase.day - 1, dt.day);
-    Expect.equals(0, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    // Day
-    print("  >>> Day+");
-    dt = new DateTime(dtBase.year, dtBase.month, 31, dtBase.hour, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month + 1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    print("  >>> Day-");
-    dt = new DateTime(dtBase.year, dtBase.month, -30, dtBase.hour, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year, dt.year);
-    Expect.equals(dtBase.month - 1, dt.month);
-    Expect.equals(1, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    // Month
-    print("  >>> Month+");
-    dt = new DateTime(dtBase.year, 13, dtBase.day, dtBase.hour, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year + 1, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    print("  >>> Month-");
-    dt = new DateTime(dtBase.year, -11, dtBase.day, dtBase.hour, dtBase.minute,
-                  dtBase.second, dtBase.millisecond);
-    Expect.equals(dtBase.year - 1, dt.year);
-    Expect.equals(1, dt.month);
-    Expect.equals(dtBase.day, dt.day);
-    Expect.equals(dtBase.hour, dt.hour);
-    Expect.equals(dtBase.minute, dt.minute);
-    Expect.equals(dtBase.second, dt.second);
-    Expect.equals(dtBase.millisecond, dt.millisecond);
-
-    // Flowing all the way up the chain.
-    print("  >>> Flow+");
-    var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999);
-    var dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
-                          dtBase1.hour, dtBase1.minute, dtBase1.second,
-                          dtBase1.millisecond + 1);
-    Expect.equals(dtBase1.year + 1, dtTick.year);
-    Expect.equals(1, dtTick.month);
-    Expect.equals(1, dtTick.day);
-    Expect.equals(0, dtTick.hour);
-    Expect.equals(0, dtTick.minute);
-    Expect.equals(0, dtTick.second);
-    Expect.equals(0, dtTick.millisecond);
-
-    print("  >>> Flow-");
-    dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0);
-    dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
-                      dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1);
-    Expect.equals(dtBase1.year - 1, dtTick.year);
-    Expect.equals(12, dtTick.month);
-    Expect.equals(31, dtTick.day);
-    Expect.equals(23, dtTick.hour);
-    Expect.equals(59, dtTick.minute);
-    Expect.equals(59, dtTick.second);
-    Expect.equals(999, dtTick.millisecond);
-
-    print("  >>> extra underflow");
-    dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, -17520,
-                      dtBase1.minute, dtBase1.second, dtBase1.millisecond);
-    Expect.equals(dtBase1.year - 2, dtTick.year);
-    Expect.equals(dtBase1.month, dtTick.month);
-    Expect.equals(dtBase1.day, dtTick.day);
-    Expect.equals(dtBase1.hour, dtTick.hour);
-    Expect.equals(dtBase1.minute, dtTick.minute);
-    Expect.equals(dtBase1.second, dtTick.second);
-    Expect.equals(dtBase1.millisecond, dtTick.millisecond);
-  }
-
-  static void testDateStrings() {
-    // TODO(floitsch): Clean up the DateTime API that deals with strings.
-    var dt1 = DateTime.parse("2011-05-11 18:58:35Z");
-    Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
-    Expect.isTrue(dt1.isUtc);
-    dt1 = DateTime.parse("20110511 18:58:35z");
-    Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
-    Expect.isTrue(dt1.isUtc);
-    dt1 = DateTime.parse("+20110511 18:58:35z");
-    Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
-    Expect.isTrue(dt1.isUtc);
-    var str = dt1.toString();
-    var dt2 = DateTime.parse(str);
-    Expect.equals(true, dt1 == dt2);
-    var dt3 = dt1.toUtc();
-    str = dt3.toString();
-    Expect.equals("2011-05-11 18:58:35.000Z", str);
-    var dt4 = DateTime.parse("-1234-01-01 00:00:00Z");
-    Expect.equals(-1234, dt4.year);
-    Expect.equals(1, dt4.month);
-    Expect.equals(1, dt4.day);
-    Expect.equals(0, dt4.hour);
-    Expect.equals(0, dt4.minute);
-    Expect.equals(0, dt4.second);
-    Expect.equals(0, dt4.millisecond);
-    Expect.isTrue(dt4.isUtc);
-    var dt5 = DateTime.parse("0099-01-02");
-    Expect.equals(99, dt5.year);
-    Expect.equals(1, dt5.month);
-    Expect.equals(2, dt5.day);
-    Expect.equals(0, dt5.hour);
-    Expect.equals(0, dt5.minute);
-    Expect.equals(0, dt5.second);
-    Expect.equals(0, dt5.millisecond);
-    Expect.isFalse(dt5.isUtc);
-    var dt6 = DateTime.parse("2012-01-01 00:00:10.012");
-    Expect.equals(12, dt6.millisecond);
-    dt6 = DateTime.parse("2012-01-01 00:00:10.003");
-    Expect.equals(3, dt6.millisecond);
-    dt6 = DateTime.parse("2012-01-01 00:00:10.5");
-    Expect.equals(500, dt6.millisecond);
-    dt6 = DateTime.parse("2012-01-01 00:00:10.003Z");
-    Expect.equals(3, dt6.millisecond);
-    dt6 = DateTime.parse("2012-01-01 00:00:10.5z");
-    Expect.equals(500, dt6.millisecond);
-    var dt7 = DateTime.parse("2011-05-11T18:58:35Z");
-    Expect.equals(1305140315000, dt7.millisecondsSinceEpoch);
-    var dt8 = DateTime.parse("-1234-01-01T00:00:00Z");
-    Expect.equals(-1234, dt8.year);
-    Expect.equals(1, dt8.month);
-    Expect.equals(1, dt8.day);
-    Expect.equals(0, dt8.hour);
-    Expect.equals(0, dt8.minute);
-    Expect.equals(0, dt8.second);
-    Expect.equals(0, dt8.millisecond);
-    Expect.isTrue(dt8.isUtc);
-    var dt9 = DateTime.parse("-1234-01-01T00:00:00");
-    Expect.equals(-1234, dt9.year);
-    Expect.equals(1, dt9.month);
-    Expect.equals(1, dt9.day);
-    Expect.equals(0, dt9.hour);
-    Expect.equals(0, dt9.minute);
-    Expect.equals(0, dt9.second);
-    Expect.equals(0, dt9.millisecond);
-    Expect.isFalse(dt9.isUtc);
-    var dt10 = DateTime.parse("-12340101");
-    Expect.equals(-1234, dt10.year);
-    Expect.equals(1, dt10.month);
-    Expect.equals(1, dt10.day);
-    Expect.equals(0, dt10.hour);
-    Expect.equals(0, dt10.minute);
-    Expect.equals(0, dt10.second);
-    Expect.equals(0, dt10.millisecond);
-    Expect.isFalse(dt10.isUtc);
-    dt1 = DateTime.parse("2012-02-27 13:27:00");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(13, dt1.hour);
-    Expect.equals(27, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(false, dt1.isUtc);
-    dt1 = DateTime.parse("2012-02-27 13:27:00.423z");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(13, dt1.hour);
-    Expect.equals(27, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(423, dt1.millisecond);
-    Expect.equals(true, dt1.isUtc);
-    dt1 = DateTime.parse("20120227 13:27:00");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(13, dt1.hour);
-    Expect.equals(27, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(false, dt1.isUtc);
-    dt1 = DateTime.parse("20120227T132700");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(13, dt1.hour);
-    Expect.equals(27, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(false, dt1.isUtc);
-    dt1 = DateTime.parse("20120227");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(0, dt1.hour);
-    Expect.equals(0, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(false, dt1.isUtc);
-    dt1 = DateTime.parse("2012-02-27T14Z");
-    Expect.equals(2012, dt1.year);
-    Expect.equals(2, dt1.month);
-    Expect.equals(27, dt1.day);
-    Expect.equals(14, dt1.hour);
-    Expect.equals(0, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(true, dt1.isUtc);
-    dt1 = DateTime.parse("-123450101 00:00:00 Z");
-    Expect.equals(-12345, dt1.year);
-    Expect.equals(1, dt1.month);
-    Expect.equals(1, dt1.day);
-    Expect.equals(0, dt1.hour);
-    Expect.equals(0, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(true, dt1.isUtc);
-    // We only support millisecond. If the user supplies more data (the "51"
-    // here), we round.
-    // If (eventually) we support more than just millisecond this test could
-    // fail. Please update the test in this case.
-    dt1 = DateTime.parse("1999-01-02 23:59:59.99951");
-    Expect.equals(1999, dt1.year);
-    Expect.equals(1, dt1.month);
-    Expect.equals(3, dt1.day);
-    Expect.equals(0, dt1.hour);
-    Expect.equals(0, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(false, dt1.isUtc);
-    dt1 = DateTime.parse("1999-01-02 23:58:59.99951Z");
-    Expect.equals(1999, dt1.year);
-    Expect.equals(1, dt1.month);
-    Expect.equals(2, dt1.day);
-    Expect.equals(23, dt1.hour);
-    Expect.equals(59, dt1.minute);
-    Expect.equals(0, dt1.second);
-    Expect.equals(0, dt1.millisecond);
-    Expect.equals(true, dt1.isUtc);
-    dt1 = DateTime.parse("0009-09-09 09:09:09.009Z");
-    Expect.equals(9, dt1.year);
-    Expect.equals(9, dt1.month);
-    Expect.equals(9, dt1.day);
-    Expect.equals(9, dt1.hour);
-    Expect.equals(9, dt1.minute);
-    Expect.equals(9, dt1.second);
-    Expect.equals(9, dt1.millisecond);
-    Expect.equals(true, dt1.isUtc);
-  }
-
-  static void testWeekday() {
-    // 2011-10-06 is Summertime.
-    var d = new DateTime(2011, 10, 6, 0, 45, 37, 0);
-    Expect.equals(DateTime.THURSDAY, d.weekday);
-    d = new DateTime.utc(2011, 10, 6, 0, 45, 37, 0);
-    Expect.equals(DateTime.THURSDAY, d.weekday);
-    d = new DateTime(2011, 10, 5, 23, 45, 37, 0);
-    Expect.equals(DateTime.WEDNESDAY, d.weekday);
-    d = new DateTime.utc(2011, 10, 5, 23, 45, 37, 0);
-    Expect.equals(DateTime.WEDNESDAY, d.weekday);
-    // 1970-01-01 is Wintertime.
-    d = new DateTime(1970, 1, 1, 0, 0, 0, 1);
-    Expect.equals(DateTime.THURSDAY, d.weekday);
-    d = new DateTime.utc(1970, 1, 1, 0, 0, 0, 1);
-    Expect.equals(DateTime.THURSDAY, d.weekday);
-    d = new DateTime.utc(1969, 12, 31, 23, 59, 59, 999);
-    Expect.equals(DateTime.WEDNESDAY, d.weekday);
-    d = new DateTime(1969, 12, 31, 23, 59, 59, 999);
-    Expect.equals(DateTime.WEDNESDAY, d.weekday);
-    d = new DateTime(2011, 10, 4, 23, 45, 37, 0);
-    Expect.equals(DateTime.TUESDAY, d.weekday);
-    d = new DateTime(2011, 10, 3, 23, 45, 37, 0);
-    Expect.equals(DateTime.MONDAY, d.weekday);
-    d = new DateTime(2011, 10, 2, 23, 45, 37, 0);
-    Expect.equals(DateTime.SUNDAY, d.weekday);
-    d = new DateTime(2011, 10, 1, 23, 45, 37, 0);
-    Expect.equals(DateTime.SATURDAY, d.weekday);
-    d = new DateTime(2011, 9, 30, 23, 45, 37, 0);
-    Expect.equals(DateTime.FRIDAY, d.weekday);
-  }
-
-  static void testMain() {
-    testNow();
-    testValue();
-    testConstructors();
-    testUTCGetters();
-    testLocalGetters();
-    testChangeTimeZone();
-    testSubAdd();
-    testUnderflowAndOverflow();
-    testDateStrings();
-    testEquivalentYears();
-    testExtremes();
-    testFarAwayDates();
-    testWeekday();
-  }
+  Expect.equals(true, timeMovedForward);
+  Expect.isFalse(t1.isUtc);
 }
 
-main() {
-  DateTest.testMain();
+void testValue() {
+  var dt1 = new DateTime.now();
+  var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch;
+  var dt2 = new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
+  Expect.equals(millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+}
+
+void testFarAwayDates() {
+  DateTime dt =
+      new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(27, dt.day);
+  Expect.equals(1, dt.hour);
+  Expect.equals(46, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(1, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(5, dt.day);
+  Expect.equals(22, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  // Same with local zone.
+  dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(true, dt.day == 27 || dt.day == 26);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 46 % 15);
+  Expect.equals(40, dt.second);
+  Expect.equals(1, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(true, 5 == dt.day || 6 == dt.day);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 13);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+}
+
+void testEquivalentYears() {
+  // All hardcoded values come from V8. This means that the values are not
+  // necessarily correct (see limitations of DateTime object in
+  // EcmaScript 15.9.1 and in particular 15.9.1.8/9).
+  DateTime dt = new DateTime.fromMillisecondsSinceEpoch(-31485600000, isUtc: true);
+  Expect.equals(1969, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-63108000000, isUtc: true);
+  Expect.equals(1968, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-94644000000, isUtc: true);
+  Expect.equals(1967, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-126180000000, isUtc: true);
+  Expect.equals(1966, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-157716000000, isUtc: true);
+  Expect.equals(1965, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-2177402400000, isUtc: true);
+  Expect.equals(1901, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-5333076000000, isUtc: true);
+  Expect.equals(1801, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-8520285600000, isUtc: true);
+  Expect.equals(1700, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-14831719200000, isUtc: true);
+  Expect.equals(1500, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-59011408800000, isUtc: true);
+  Expect.equals(100, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(14, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-62011408800000, isUtc: true);
+  Expect.equals(4, dt.year);
+  Expect.equals(12, dt.month);
+  Expect.equals(8, dt.day);
+  Expect.equals(8, dt.hour);
+  Expect.equals(40, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-64011408800000, isUtc: true);
+  Expect.equals(-59, dt.year);
+  Expect.equals(7, dt.month);
+  Expect.equals(24, dt.day);
+  Expect.equals(5, dt.hour);
+  Expect.equals(6, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  final int SECONDS_YEAR_2035 = 2051222400;
+  dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1,
+                                           isUtc: true);
+  Expect.equals(2035, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(1, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1,
+                                           isUtc: true);
+  Expect.equals(2034, dt.year);
+  Expect.equals(12, dt.month);
+  Expect.equals(31, dt.day);
+  Expect.equals(23, dt.hour);
+  Expect.equals(59, dt.minute);
+  Expect.equals(59, dt.second);
+  Expect.equals(999, dt.millisecond);
+  dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 1);
+  Expect.equals(SECONDS_YEAR_2035 * 1000 + 1, dt.millisecondsSinceEpoch);
+  dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999);
+  Expect.equals(SECONDS_YEAR_2035 * 1000 - 1, dt.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(0, dt.second);
+  Expect.equals(1, dt.millisecond);
+  DateTime dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond);
+  Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(59, dt.second);
+  Expect.equals(999, dt.millisecond);
+  dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond);
+  Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(2100000000 * 1000, isUtc: true);
+  Expect.equals(2036, dt.year);
+  Expect.equals(7, dt.month);
+  Expect.equals(18, dt.day);
+  Expect.equals(13, dt.hour);
+  Expect.equals(20, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  // Internally this will use the maximum value for the native calls.
+  dt = new DateTime(2036, 7, 18, 13, 20);
+  Expect.equals(2036, dt.year);
+  Expect.equals(7, dt.month);
+  Expect.equals(18, dt.day);
+  Expect.equals(13, dt.hour);
+  Expect.equals(20, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals("2036-07-18 13:20:00.000", dt.toString());
+}
+
+void testExtremes() {
+  var dt =
+      new DateTime.fromMillisecondsSinceEpoch(8640000000000000, isUtc: true);
+  Expect.equals(275760, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(13, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000, isUtc: true);
+  Expect.equals(-271821, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(20, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  // Make sure that we can build the extreme dates in local too.
+  dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(8640000000000000, dt.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(-8640000000000000, dt.millisecondsSinceEpoch);
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(8640000000000001,
+                                                          isUtc: true));
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(-8640000000000001,
+                                                          isUtc: true));
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(8640000000000001));
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(-8640000000000001));
+  dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(8640000000000000, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, -1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-8640000000000000, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, -1));
+}
+
+void testUTCGetters() {
+  var dt = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+  Expect.equals(2011, dt.year);
+  Expect.equals(5, dt.month);
+  Expect.equals(11, dt.day);
+  Expect.equals(18, dt.hour);
+  Expect.equals(58, dt.minute);
+  Expect.equals(35, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(true, dt.isUtc);
+  Expect.equals(1305140315000, dt.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
+  Expect.equals(1969, dt.year);
+  Expect.equals(12, dt.month);
+  Expect.equals(31, dt.day);
+  Expect.equals(21, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(20, dt.second);
+  Expect.equals(1, dt.millisecond);
+}
+
+void testLocalGetters() {
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
+  var dt2 = new DateTime.utc(dt1.year, dt1.month, dt1.day,
+                         dt1.hour, dt1.minute, dt1.second, dt1.millisecond);
+  Duration zoneOffset = dt1.difference(dt2);
+  Expect.equals(true, zoneOffset.inDays == 0);
+  Expect.equals(true, zoneOffset.inHours.abs() <= 12);
+  Expect.equals(dt1.year, dt2.year);
+  Expect.equals(dt1.month, dt2.month);
+  Expect.equals(true, (dt1.day - dt2.day).abs() <= 1);
+  Expect.equals(true, dt1.hour < 24);
+  // There are timezones with 0.5 or 0.25 hour offsets.
+  Expect.equals(true,
+                (dt1.minute == dt2.minute) ||
+                ((dt1.minute - dt2.minute).abs() == 30) ||
+                ((dt1.minute - dt2.minute).abs() == 15));
+  Expect.equals(dt1.second, dt2.second);
+  Expect.equals(dt1.millisecond, dt2.millisecond);
+}
+
+void testConstructors() {
+  var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
+  var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
+  Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
+  Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
+  Expect.equals(false, dt1 == dt0);
+  Expect.equals(true, dt1 == dt0b);
+  var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
+                     dt1.second, dt1.millisecond);
+  Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(false, dt3 == dt0);
+  Expect.equals(true, dt1 == dt3);
+  dt3 = new DateTime(
+      dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
+      dt1.second, dt1.millisecond);
+  Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(true, dt1 == dt3);
+  var dt2 = dt1.toLocal();
+  dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0);
+  Expect.equals(dt2.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(true, dt2 == dt3);
+  dt1 = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
+  dt3 = new DateTime.utc(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
+                     dt1.second, dt1.millisecond);
+  Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  dt3 = new DateTime.utc(99, 1, 2, 10, 11, 12, 0);
+  Expect.equals(99, dt3.year);
+  Expect.equals(1, dt3.month);
+  Expect.equals(2, dt3.day);
+  Expect.equals(10, dt3.hour);
+  Expect.equals(11, dt3.minute);
+  Expect.equals(12, dt3.second);
+  Expect.equals(0, dt3.millisecond);
+  Expect.equals(true, dt3.isUtc);
+  var dt4 = new DateTime(99, 1, 2);
+  Expect.equals(99, dt4.year);
+  Expect.equals(1, dt4.month);
+  Expect.equals(2, dt4.day);
+  Expect.equals(0, dt4.hour);
+  Expect.equals(0, dt4.minute);
+  Expect.equals(0, dt4.second);
+  Expect.equals(0, dt4.millisecond);
+  Expect.isFalse(dt4.isUtc);
+  var dt5 = new DateTime.utc(99, 1, 2);
+  Expect.equals(99, dt5.year);
+  Expect.equals(1, dt5.month);
+  Expect.equals(2, dt5.day);
+  Expect.equals(0, dt5.hour);
+  Expect.equals(0, dt5.minute);
+  Expect.equals(0, dt5.second);
+  Expect.equals(0, dt5.millisecond);
+  Expect.isTrue(dt5.isUtc);
+  var dt6 = new DateTime(2012, 2, 27, 13, 27, 0);
+  Expect.equals(2012, dt6.year);
+  Expect.equals(2, dt6.month);
+  Expect.equals(27, dt6.day);
+  Expect.equals(13, dt6.hour);
+  Expect.equals(27, dt6.minute);
+  Expect.equals(0, dt6.second);
+  Expect.equals(0, dt6.millisecond);
+  Expect.isFalse(dt6.isUtc);
+  var dt7 = new DateTime.utc(2012, 2, 27, 13, 27, 0);
+  Expect.equals(2012, dt7.year);
+  Expect.equals(2, dt7.month);
+  Expect.equals(27, dt7.day);
+  Expect.equals(13, dt7.hour);
+  Expect.equals(27, dt7.minute);
+  Expect.equals(0, dt7.second);
+  Expect.equals(0, dt7.millisecond);
+  Expect.isTrue(dt7.isUtc);
+}
+
+void testChangeTimeZone() {
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
+  var dt2 = dt1.toUtc();
+  Expect.equals(dt1.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+  var dt3 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+  Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt2.year, dt3.year);
+  Expect.equals(dt2.month, dt3.month);
+  Expect.equals(dt2.day, dt3.day);
+  Expect.equals(dt2.hour, dt3.hour);
+  Expect.equals(dt2.minute, dt3.minute);
+  Expect.equals(dt2.second, dt3.second);
+  Expect.equals(dt2.millisecond, dt3.millisecond);
+  var dt4 = dt3.toLocal();
+  Expect.equals(dt1.year, dt4.year);
+  Expect.equals(dt1.month, dt4.month);
+  Expect.equals(dt1.day, dt4.day);
+  Expect.equals(dt1.hour, dt4.hour);
+  Expect.equals(dt1.minute, dt4.minute);
+  Expect.equals(dt1.second, dt4.second);
+  Expect.equals(dt1.millisecond, dt4.millisecond);
+}
+
+void testSubAdd() {
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+  var dt2 = dt1.add(new Duration(milliseconds:
+      3 * Duration.MILLISECONDS_PER_SECOND + 5));
+  Expect.equals(dt1.year, dt2.year);
+  Expect.equals(dt1.month, dt2.month);
+  Expect.equals(dt1.day, dt2.day);
+  Expect.equals(dt1.hour, dt2.hour);
+  Expect.equals(dt1.minute, dt2.minute);
+  Expect.equals(dt1.second + 3, dt2.second);
+  Expect.equals(dt1.millisecond + 5, dt2.millisecond);
+  var dt3 = dt2.subtract(new Duration(milliseconds:
+      3 * Duration.MILLISECONDS_PER_SECOND + 5));
+  Expect.equals(true, dt1 == dt3);
+  Expect.equals(false, dt1 == dt2);
+}
+
+void testUnderflowAndOverflow() {
+  final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500);
+
+  // Millisecond
+  print("  >>> Millisecond+");
+  var dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                    dtBase.minute, dtBase.second, 1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second + 1, dt.second);
+  Expect.equals(0, dt.millisecond);
+
+  print("  >>> Millisecond-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                dtBase.minute, dtBase.second, -1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second - 1, dt.second);
+  Expect.equals(0, dt.millisecond);
+
+  // Second
+  print("  >>> Second+");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                dtBase.minute, 60, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute + 1, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  print("  >>> Second-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                dtBase.minute, -60, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute - 1, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  // Minute
+  print("  >>> Minute+");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, 60,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour + 1, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  print("  >>> Minute-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, -60,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour - 1, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  // Hour
+  print("  >>> Hour+");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, 24, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day + 1, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  print("  >>> Hour-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, -24, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day - 1, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  // Day
+  print("  >>> Day+");
+  dt = new DateTime(dtBase.year, dtBase.month, 31, dtBase.hour, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month + 1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  print("  >>> Day-");
+  dt = new DateTime(dtBase.year, dtBase.month, -30, dtBase.hour, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month - 1, dt.month);
+  Expect.equals(1, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  // Month
+  print("  >>> Month+");
+  dt = new DateTime(dtBase.year, 13, dtBase.day, dtBase.hour, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year + 1, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  print("  >>> Month-");
+  dt = new DateTime(dtBase.year, -11, dtBase.day, dtBase.hour, dtBase.minute,
+                dtBase.second, dtBase.millisecond);
+  Expect.equals(dtBase.year - 1, dt.year);
+  Expect.equals(1, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond, dt.millisecond);
+
+  // Flowing all the way up the chain.
+  print("  >>> Flow+");
+  var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999);
+  var dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
+                        dtBase1.hour, dtBase1.minute, dtBase1.second,
+                        dtBase1.millisecond + 1);
+  Expect.equals(dtBase1.year + 1, dtTick.year);
+  Expect.equals(1, dtTick.month);
+  Expect.equals(1, dtTick.day);
+  Expect.equals(0, dtTick.hour);
+  Expect.equals(0, dtTick.minute);
+  Expect.equals(0, dtTick.second);
+  Expect.equals(0, dtTick.millisecond);
+
+  print("  >>> Flow-");
+  dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0);
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1);
+  Expect.equals(dtBase1.year - 1, dtTick.year);
+  Expect.equals(12, dtTick.month);
+  Expect.equals(31, dtTick.day);
+  Expect.equals(23, dtTick.hour);
+  Expect.equals(59, dtTick.minute);
+  Expect.equals(59, dtTick.second);
+  Expect.equals(999, dtTick.millisecond);
+
+  print("  >>> extra underflow");
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, -17520,
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond);
+  Expect.equals(dtBase1.year - 2, dtTick.year);
+  Expect.equals(dtBase1.month, dtTick.month);
+  Expect.equals(dtBase1.day, dtTick.day);
+  Expect.equals(dtBase1.hour, dtTick.hour);
+  Expect.equals(dtBase1.minute, dtTick.minute);
+  Expect.equals(dtBase1.second, dtTick.second);
+  Expect.equals(dtBase1.millisecond, dtTick.millisecond);
+}
+
+void testDateStrings() {
+  // TODO(floitsch): Clean up the DateTime API that deals with strings.
+  var dt1 = DateTime.parse("2011-05-11 18:58:35Z");
+  Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
+  Expect.isTrue(dt1.isUtc);
+  dt1 = DateTime.parse("20110511 18:58:35z");
+  Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
+  Expect.isTrue(dt1.isUtc);
+  dt1 = DateTime.parse("+20110511 18:58:35z");
+  Expect.equals(1305140315000, dt1.millisecondsSinceEpoch);
+  Expect.isTrue(dt1.isUtc);
+  var str = dt1.toString();
+  var dt2 = DateTime.parse(str);
+  Expect.equals(true, dt1 == dt2);
+  var dt3 = dt1.toUtc();
+  str = dt3.toString();
+  Expect.equals("2011-05-11 18:58:35.000Z", str);
+  var dt4 = DateTime.parse("-1234-01-01 00:00:00Z");
+  Expect.equals(-1234, dt4.year);
+  Expect.equals(1, dt4.month);
+  Expect.equals(1, dt4.day);
+  Expect.equals(0, dt4.hour);
+  Expect.equals(0, dt4.minute);
+  Expect.equals(0, dt4.second);
+  Expect.equals(0, dt4.millisecond);
+  Expect.isTrue(dt4.isUtc);
+  var dt5 = DateTime.parse("0099-01-02");
+  Expect.equals(99, dt5.year);
+  Expect.equals(1, dt5.month);
+  Expect.equals(2, dt5.day);
+  Expect.equals(0, dt5.hour);
+  Expect.equals(0, dt5.minute);
+  Expect.equals(0, dt5.second);
+  Expect.equals(0, dt5.millisecond);
+  Expect.isFalse(dt5.isUtc);
+  var dt6 = DateTime.parse("2012-01-01 00:00:10.012");
+  Expect.equals(12, dt6.millisecond);
+  dt6 = DateTime.parse("2012-01-01 00:00:10.003");
+  Expect.equals(3, dt6.millisecond);
+  dt6 = DateTime.parse("2012-01-01 00:00:10.5");
+  Expect.equals(500, dt6.millisecond);
+  dt6 = DateTime.parse("2012-01-01 00:00:10.003Z");
+  Expect.equals(3, dt6.millisecond);
+  dt6 = DateTime.parse("2012-01-01 00:00:10.5z");
+  Expect.equals(500, dt6.millisecond);
+  var dt7 = DateTime.parse("2011-05-11T18:58:35Z");
+  Expect.equals(1305140315000, dt7.millisecondsSinceEpoch);
+  var dt8 = DateTime.parse("-1234-01-01T00:00:00Z");
+  Expect.equals(-1234, dt8.year);
+  Expect.equals(1, dt8.month);
+  Expect.equals(1, dt8.day);
+  Expect.equals(0, dt8.hour);
+  Expect.equals(0, dt8.minute);
+  Expect.equals(0, dt8.second);
+  Expect.equals(0, dt8.millisecond);
+  Expect.isTrue(dt8.isUtc);
+  var dt9 = DateTime.parse("-1234-01-01T00:00:00");
+  Expect.equals(-1234, dt9.year);
+  Expect.equals(1, dt9.month);
+  Expect.equals(1, dt9.day);
+  Expect.equals(0, dt9.hour);
+  Expect.equals(0, dt9.minute);
+  Expect.equals(0, dt9.second);
+  Expect.equals(0, dt9.millisecond);
+  Expect.isFalse(dt9.isUtc);
+  var dt10 = DateTime.parse("-12340101");
+  Expect.equals(-1234, dt10.year);
+  Expect.equals(1, dt10.month);
+  Expect.equals(1, dt10.day);
+  Expect.equals(0, dt10.hour);
+  Expect.equals(0, dt10.minute);
+  Expect.equals(0, dt10.second);
+  Expect.equals(0, dt10.millisecond);
+  Expect.isFalse(dt10.isUtc);
+  dt1 = DateTime.parse("2012-02-27 13:27:00");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(13, dt1.hour);
+  Expect.equals(27, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("2012-02-27 13:27:00.423z");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(13, dt1.hour);
+  Expect.equals(27, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(423, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("20120227 13:27:00");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(13, dt1.hour);
+  Expect.equals(27, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("20120227T132700");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(13, dt1.hour);
+  Expect.equals(27, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("20120227");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(0, dt1.hour);
+  Expect.equals(0, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("2012-02-27T14Z");
+  Expect.equals(2012, dt1.year);
+  Expect.equals(2, dt1.month);
+  Expect.equals(27, dt1.day);
+  Expect.equals(14, dt1.hour);
+  Expect.equals(0, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("-123450101 00:00:00 Z");
+  Expect.equals(-12345, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(1, dt1.day);
+  Expect.equals(0, dt1.hour);
+  Expect.equals(0, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  // We only support millisecond. If the user supplies more data (the "51"
+  // here), we round.
+  // If (eventually) we support more than just millisecond this test could
+  // fail. Please update the test in this case.
+  dt1 = DateTime.parse("1999-01-02 23:59:59.99951");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(3, dt1.day);
+  Expect.equals(0, dt1.hour);
+  Expect.equals(0, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("1999-01-02 23:58:59.99951Z");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(2, dt1.day);
+  Expect.equals(23, dt1.hour);
+  Expect.equals(59, dt1.minute);
+  Expect.equals(0, dt1.second);
+  Expect.equals(0, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009Z");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(9, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-00");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(9, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-0000");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(9, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-02");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(11, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009+0200");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(7, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009+1200");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(8, dt1.day);
+  Expect.equals(21, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-1200");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(21, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-0230");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(11, dt1.hour);
+  Expect.equals(39, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009-2134");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(10, dt1.day);
+  Expect.equals(6, dt1.hour);
+  Expect.equals(43, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(true, dt1.isUtc);
+}
+
+void testWeekday() {
+  // 2011-10-06 is Summertime.
+  var d = new DateTime(2011, 10, 6, 0, 45, 37, 0);
+  Expect.equals(DateTime.THURSDAY, d.weekday);
+  d = new DateTime.utc(2011, 10, 6, 0, 45, 37, 0);
+  Expect.equals(DateTime.THURSDAY, d.weekday);
+  d = new DateTime(2011, 10, 5, 23, 45, 37, 0);
+  Expect.equals(DateTime.WEDNESDAY, d.weekday);
+  d = new DateTime.utc(2011, 10, 5, 23, 45, 37, 0);
+  Expect.equals(DateTime.WEDNESDAY, d.weekday);
+  // 1970-01-01 is Wintertime.
+  d = new DateTime(1970, 1, 1, 0, 0, 0, 1);
+  Expect.equals(DateTime.THURSDAY, d.weekday);
+  d = new DateTime.utc(1970, 1, 1, 0, 0, 0, 1);
+  Expect.equals(DateTime.THURSDAY, d.weekday);
+  d = new DateTime.utc(1969, 12, 31, 23, 59, 59, 999);
+  Expect.equals(DateTime.WEDNESDAY, d.weekday);
+  d = new DateTime(1969, 12, 31, 23, 59, 59, 999);
+  Expect.equals(DateTime.WEDNESDAY, d.weekday);
+  d = new DateTime(2011, 10, 4, 23, 45, 37, 0);
+  Expect.equals(DateTime.TUESDAY, d.weekday);
+  d = new DateTime(2011, 10, 3, 23, 45, 37, 0);
+  Expect.equals(DateTime.MONDAY, d.weekday);
+  d = new DateTime(2011, 10, 2, 23, 45, 37, 0);
+  Expect.equals(DateTime.SUNDAY, d.weekday);
+  d = new DateTime(2011, 10, 1, 23, 45, 37, 0);
+  Expect.equals(DateTime.SATURDAY, d.weekday);
+  d = new DateTime(2011, 9, 30, 23, 45, 37, 0);
+  Expect.equals(DateTime.FRIDAY, d.weekday);
+}
+
+void testToStrings() {
+  void test(date, time) {
+    { // UTC time.
+      String source1 = "$date ${time}Z";
+      String source2 = "${date}T${time}Z";
+      var utcTime1 = DateTime.parse(source1);
+      var utcTime2 = DateTime.parse(source1);
+      Expect.isTrue(utcTime1.isUtc);
+      Expect.equals(utcTime1, utcTime2);
+      Expect.equals(source1, utcTime1.toString());
+      Expect.equals(source2, utcTime1.toIso8601String());
+    }
+    {  // Local time
+      String source1 = "$date $time";
+      String source2 = "${date}T$time";
+      var utcTime1 = DateTime.parse(source1);
+      var utcTime2 = DateTime.parse(source1);
+      Expect.isFalse(utcTime1.isUtc);
+      Expect.equals(utcTime1, utcTime2);
+      Expect.equals(source1, utcTime1.toString());
+      Expect.equals(source2, utcTime1.toIso8601String());
+    }
+  }
+  test("2000-01-01", "12:00:00.000");
+  test("-2000-01-01", "12:00:00.000");
+  test("1970-01-01", "00:00:00.000");
+  test("1969-12-31", "23:59:59.999");
+}
+
+void main() {
+  testNow();
+  testValue();
+  testConstructors();
+  testUTCGetters();
+  testLocalGetters();
+  testChangeTimeZone();
+  testSubAdd();
+  testUnderflowAndOverflow();
+  testDateStrings();
+  testEquivalentYears();
+  testExtremes();
+  testFarAwayDates();
+  testWeekday();
+  testToStrings();
 }
diff --git a/tests/corelib/string_test.dart b/tests/corelib/string_test.dart
index 2d34c063..cbcc445 100644
--- a/tests/corelib/string_test.dart
+++ b/tests/corelib/string_test.dart
@@ -4,387 +4,387 @@
 
 import "package:expect/expect.dart";
 
-class StringTest {
+void main() {
+  testOutOfRange();
+  testIllegalArgument();
+  testConcat();
+  testIndex();
+  testCodeUnitAt();
+  testEquals();
+  testEndsWith();
+  testStartsWith();
+  testIndexOf();
+  testLastIndexOf();
+  testContains();
+  testReplaceAll();
+  testCompareTo();
+  testCharCodes();
+  testRepeat();
+  testPadLeft();
+  testPadRight();
+}
 
-  static testMain() {
-    testOutOfRange();
-    testIllegalArgument();
-    testConcat();
-    testIndex();
-    testCodeUnitAt();
-    testEquals();
-    testEndsWith();
-    testStartsWith();
-    testIndexOf();
-    testLastIndexOf();
-    testContains();
-    testReplaceAll();
-    testCompareTo();
-    testCharCodes();
+void testLength() {
+  String str = "";
+  for (var i = 0; i < 20; i++) {
+    testStringLength(i, str);
+    str += " ";
   }
+}
 
-  static void testLength() {
-    String str = "";
-    for (var i = 0; i < 20; i++) {
-      testStringLength(i, str);
-      str += " ";
+void testOutOfRange() {
+  String a = "Hello";
+  bool exception_caught = false;
+  try {
+    var c = a[20];  // Throw exception.
+  } on RangeError catch (e) {
+    exception_caught = true;
+  }
+  Expect.isTrue(exception_caught);
+}
+
+void testIllegalArgument() {
+  String a = "Hello";
+  bool exception_caught = false;
+  try {
+    var c = a[2.2];  // Throw exception.
+    Expect.fail("Accepting double as index");
+  } on ArgumentError catch (e) {
+    exception_caught = true;
+  } on TypeError catch (e) {  // Thrown in checked mode only.
+    exception_caught = true;
+  }
+  Expect.isTrue(exception_caught);
+}
+
+void testIndex() {
+  String str = "string";
+  for (int i = 0; i < str.length; i++) {
+    Expect.isTrue(str[i] is String);
+    testStringLength(1, str[i]);
+  }
+}
+
+void testCodeUnitAt() {
+  String str = "string";
+  for (int i = 0; i < str.length; i++) {
+    Expect.isTrue(str.codeUnitAt(i) is int);
+  }
+}
+
+void testConcat() {
+  var a = "One";
+  var b = "Four";
+  var c = a + b;
+  testStringLength(7, c);
+  Expect.equals("OneFour", c);
+}
+
+void testEquals() {
+  Expect.equals("str", "str");
+
+  Expect.equals("str", "s" + "t" + "r");
+  Expect.equals("s" + "t" + "r", "str");
+
+  Expect.isFalse("str" == "s");
+  Expect.isFalse("str" == "r");
+  Expect.isFalse("str" == "st");
+  Expect.isFalse("str" == "tr");
+
+  Expect.isFalse("s" == "str");
+  Expect.isFalse("r" == "str");
+  Expect.isFalse("st" == "str");
+  Expect.isFalse("tr" == "str");
+
+  Expect.isFalse("" == "s");
+  Expect.equals("", "");
+}
+
+void testEndsWith() {
+  Expect.isTrue("str".endsWith("r"));
+  Expect.isTrue("str".endsWith("tr"));
+  Expect.isTrue("str".endsWith("str"));
+
+  Expect.isFalse("str".endsWith("stri"));
+  Expect.isFalse("str".endsWith("t"));
+  Expect.isFalse("str".endsWith("st"));
+  Expect.isFalse("str".endsWith("s"));
+
+  Expect.isTrue("".endsWith(""));
+  Expect.isFalse("".endsWith("s"));
+}
+
+void testStartsWith() {
+  Expect.isTrue("str".startsWith("s"));
+  Expect.isTrue("str".startsWith("st"));
+  Expect.isTrue("str".startsWith("str"));
+
+  Expect.isFalse("str".startsWith("stri"));
+  Expect.isFalse("str".startsWith("r"));
+  Expect.isFalse("str".startsWith("tr"));
+  Expect.isFalse("str".startsWith("t"));
+
+  Expect.isTrue("".startsWith(""));
+  Expect.isFalse("".startsWith("s"));
+
+  Expect.isFalse("strstr".startsWith("s", 1));
+  Expect.isFalse("strstr".startsWith("s", 2));
+  Expect.isTrue("strstr".startsWith("s", 3));
+  Expect.isFalse("strstr".startsWith("s", 4));
+
+  Expect.isFalse("strstr".startsWith("st", 1));
+  Expect.isFalse("strstr".startsWith("st", 2));
+  Expect.isTrue("strstr".startsWith("st", 3));
+  Expect.isFalse("strstr".startsWith("st", 4));
+
+  Expect.isFalse("strstr".startsWith("str", 1));
+  Expect.isFalse("strstr".startsWith("str", 2));
+  Expect.isTrue("strstr".startsWith("str", 3));
+  Expect.isFalse("strstr".startsWith("str", 4));
+
+  Expect.isTrue("str".startsWith("", 0));
+  Expect.isTrue("str".startsWith("", 1));
+  Expect.isTrue("str".startsWith("", 2));
+  Expect.isTrue("str".startsWith("", 3));
+
+  Expect.throws(() => "str".startsWith("", -1));
+  Expect.throws(() => "str".startsWith("", 4));
+
+  var regexp = new RegExp("s(?:tr?)?");
+  Expect.isTrue("s".startsWith(regexp));
+  Expect.isTrue("st".startsWith(regexp));
+  Expect.isTrue("str".startsWith(regexp));
+  Expect.isTrue("sX".startsWith(regexp));
+  Expect.isTrue("stX".startsWith(regexp));
+  Expect.isTrue("strX".startsWith(regexp));
+
+  Expect.isFalse("".startsWith(regexp));
+  Expect.isFalse("astr".startsWith(regexp));
+
+  Expect.isTrue("".startsWith(new RegExp("")));
+  Expect.isTrue("".startsWith(new RegExp("a?")));
+
+  Expect.isFalse("strstr".startsWith(regexp, 1));
+  Expect.isFalse("strstr".startsWith(regexp, 2));
+  Expect.isTrue("strstr".startsWith(regexp, 3));
+  Expect.isFalse("strstr".startsWith(regexp, 4));
+
+  Expect.isTrue("str".startsWith(new RegExp(""), 0));
+  Expect.isTrue("str".startsWith(new RegExp(""), 1));
+  Expect.isTrue("str".startsWith(new RegExp(""), 2));
+  Expect.isTrue("str".startsWith(new RegExp(""), 3));
+  Expect.isTrue("str".startsWith(new RegExp("a?"), 0));
+  Expect.isTrue("str".startsWith(new RegExp("a?"), 1));
+  Expect.isTrue("str".startsWith(new RegExp("a?"), 2));
+  Expect.isTrue("str".startsWith(new RegExp("a?"), 3));
+
+  Expect.throws(() => "str".startsWith(regexp, -1));
+  Expect.throws(() => "str".startsWith(regexp, 4));
+
+  regexp = new RegExp("^str");
+  Expect.isTrue("strstr".startsWith(regexp));
+  Expect.isTrue("strstr".startsWith(regexp, 0));
+  Expect.isFalse("strstr".startsWith(regexp, 1));
+  Expect.isFalse("strstr".startsWith(regexp, 2));
+  Expect.isFalse("strstr".startsWith(regexp, 3));  // Second "str" isn't at ^.
+}
+
+void testIndexOf() {
+  Expect.equals(0, "str".indexOf("", 0));
+  Expect.equals(0, "".indexOf("", 0));
+  Expect.equals(-1, "".indexOf("a", 0));
+
+  Expect.equals(1, "str".indexOf("t", 0));
+  Expect.equals(1, "str".indexOf("tr", 0));
+  Expect.equals(0, "str".indexOf("str", 0));
+  Expect.equals(0, "str".indexOf("st", 0));
+  Expect.equals(0, "str".indexOf("s", 0));
+  Expect.equals(2, "str".indexOf("r", 0));
+  Expect.equals(-1, "str".indexOf("string", 0));
+
+  Expect.equals(1, "strstr".indexOf("t", 0));
+  Expect.equals(1, "strstr".indexOf("tr", 0));
+  Expect.equals(0, "strstr".indexOf("str", 0));
+  Expect.equals(0, "strstr".indexOf("st", 0));
+  Expect.equals(0, "strstr".indexOf("s", 0));
+  Expect.equals(2, "strstr".indexOf("r", 0));
+  Expect.equals(-1, "str".indexOf("string", 0));
+
+  Expect.equals(4, "strstr".indexOf("t", 2));
+  Expect.equals(4, "strstr".indexOf("tr", 2));
+  Expect.equals(3, "strstr".indexOf("str", 1));
+  Expect.equals(3, "strstr".indexOf("str", 2));
+  Expect.equals(3, "strstr".indexOf("str", 3));
+  Expect.equals(3, "strstr".indexOf("st", 1));
+  Expect.equals(3, "strstr".indexOf("s", 3));
+  Expect.equals(5, "strstr".indexOf("r", 3));
+  Expect.equals(5, "strstr".indexOf("r", 4));
+  Expect.equals(5, "strstr".indexOf("r", 5));
+
+  String str = "hello";
+  for (int i = 0; i < 10; i++) {
+    if (i > str.length) {
+      Expect.throws(() => str.indexOf("", i));
+    } else {
+      int result = str.indexOf("", i);
+      Expect.equals(i, result);
     }
   }
 
-  static void testOutOfRange() {
-    String a = "Hello";
-    bool exception_caught = false;
-    try {
-      var c = a[20];  // Throw exception.
-    } on RangeError catch (e) {
-      exception_caught = true;
+  var re = new RegExp("an?");
+  Expect.equals(1, "banana".indexOf(re));
+  Expect.equals(1, "banana".indexOf(re, 0));
+  Expect.equals(1, "banana".indexOf(re, 1));
+  Expect.equals(3, "banana".indexOf(re, 2));
+  Expect.equals(3, "banana".indexOf(re, 3));
+  Expect.equals(5, "banana".indexOf(re, 4));
+  Expect.equals(5, "banana".indexOf(re, 5));
+  Expect.equals(-1, "banana".indexOf(re, 6));
+  Expect.throws(() => "banana".indexOf(re, -1));
+  Expect.throws(() => "banana".indexOf(re, 7));
+  re = new RegExp("x?");
+  for (int i = 0; i <= str.length; i++) {
+    Expect.equals(i, str.indexOf(re, i));
+  }
+}
+
+void testLastIndexOf() {
+  Expect.equals(2, "str".lastIndexOf("", 2));
+  Expect.equals(0, "".lastIndexOf("", 0));
+  Expect.equals(-1, "".lastIndexOf("a", 0));
+
+  Expect.equals(1, "str".lastIndexOf("t", 2));
+  Expect.equals(1, "str".lastIndexOf("tr", 2));
+  Expect.equals(0, "str".lastIndexOf("str", 2));
+  Expect.equals(0, "str".lastIndexOf("st", 2));
+  Expect.equals(0, "str".lastIndexOf("s", 2));
+  Expect.equals(2, "str".lastIndexOf("r", 2));
+  Expect.equals(-1, "str".lastIndexOf("string", 2));
+
+  Expect.equals(4, "strstr".lastIndexOf("t", 5));
+  Expect.equals(4, "strstr".lastIndexOf("tr", 5));
+  Expect.equals(3, "strstr".lastIndexOf("str", 5));
+  Expect.equals(3, "strstr".lastIndexOf("st", 5));
+  Expect.equals(3, "strstr".lastIndexOf("s", 5));
+  Expect.equals(5, "strstr".lastIndexOf("r", 5));
+  Expect.throws(() {
+      "str".lastIndexOf("string", 5);
+  });
+  Expect.equals(4, "strstr".lastIndexOf("t", 5));
+  Expect.equals(4, "strstr".lastIndexOf("tr", 5));
+  Expect.equals(3, "strstr".lastIndexOf("str", 5));
+  Expect.equals(3, "strstr".lastIndexOf("str", 5));
+  Expect.equals(3, "strstr".lastIndexOf("str", 5));
+  Expect.equals(3, "strstr".lastIndexOf("st", 5));
+  Expect.equals(3, "strstr".lastIndexOf("s", 5));
+  Expect.equals(5, "strstr".lastIndexOf("r", 5));
+  Expect.equals(2, "strstr".lastIndexOf("r", 4));
+  Expect.equals(2, "strstr".lastIndexOf("r", 3));
+  Expect.equals(5, "strstr".lastIndexOf("r"));
+  Expect.equals(5, "strstr".lastIndexOf("r", null));
+
+  String str = "hello";
+  for (int i = 0; i < 10; i++) {
+    if (i > str.length) {
+      Expect.throws(() => str.indexOf("", i));
+    } else {
+      int result = str.lastIndexOf("", i);
+      Expect.equals(i, result);
     }
-    Expect.isTrue(exception_caught);
   }
 
-  static testIllegalArgument() {
-    String a = "Hello";
-    bool exception_caught = false;
-    try {
-      var c = a[2.2];  // Throw exception.
-      Expect.fail("Accepting double as index");
-    } on ArgumentError catch (e) {
-      exception_caught = true;
-    } on TypeError catch (e) {  // Thrown in checked mode only.
-      exception_caught = true;
-    }
-    Expect.isTrue(exception_caught);
+  var re = new RegExp("an?");
+  Expect.equals(5, "banana".lastIndexOf(re));
+  Expect.equals(5, "banana".lastIndexOf(re, 6));
+  Expect.equals(5, "banana".lastIndexOf(re, 5));
+  Expect.equals(3, "banana".lastIndexOf(re, 4));
+  Expect.equals(3, "banana".lastIndexOf(re, 3));
+  Expect.equals(1, "banana".lastIndexOf(re, 2));
+  Expect.equals(1, "banana".lastIndexOf(re, 1));
+  Expect.equals(-1, "banana".lastIndexOf(re, 0));
+  Expect.throws(() => "banana".lastIndexOf(re, -1));
+  Expect.throws(() => "banana".lastIndexOf(re, 7));
+  re = new RegExp("x?");
+  for (int i = 0; i <= str.length; i++) {
+    Expect.equals(i, str.indexOf(re, i));
   }
+}
 
-  static testIndex() {
-    String str = "string";
+void testContains() {
+  Expect.isTrue("str".contains("s", 0));
+  Expect.isTrue("str".contains("st", 0));
+  Expect.isTrue("str".contains("str", 0));
+  Expect.isTrue("str".contains("t", 0));
+  Expect.isTrue("str".contains("r", 0));
+  Expect.isTrue("str".contains("tr", 0));
+
+  Expect.isFalse("str".contains("sr", 0));
+  Expect.isFalse("str".contains("string", 0));
+
+  Expect.isTrue("str".contains("", 0));
+  Expect.isTrue("".contains("", 0));
+  Expect.isFalse("".contains("s", 0));
+}
+
+void testReplaceAll() {
+  Expect.equals(
+      "AtoBtoCDtoE", "AfromBfromCDfromE".replaceAll("from", "to"));
+
+  // Test with the replaced string at the begining.
+  Expect.equals(
+      "toABtoCDtoE", "fromABfromCDfromE".replaceAll("from", "to"));
+
+  // Test with the replaced string at the end.
+  Expect.equals(
+      "toABtoCDtoEto", "fromABfromCDfromEfrom".replaceAll("from", "to"));
+
+  // Test when there are no occurence of the string to replace.
+  Expect.equals("ABC", "ABC".replaceAll("from", "to"));
+
+  // Test when the string to change is the empty string.
+  Expect.equals("", "".replaceAll("from", "to"));
+
+  // Test when the string to change is a substring of the string to
+  // replace.
+  Expect.equals("fro", "fro".replaceAll("from", "to"));
+
+  // Test when the string to change is the replaced string.
+  Expect.equals("to", "from".replaceAll("from", "to"));
+
+  // Test when the string to change is the replacement string.
+  Expect.equals("to", "to".replaceAll("from", "to"));
+
+  // Test replacing by the empty string.
+  Expect.equals("", "from".replaceAll("from", ""));
+  Expect.equals("AB", "AfromB".replaceAll("from", ""));
+
+  // Test changing the empty string.
+  Expect.equals("to", "".replaceAll("", "to"));
+
+  // Test replacing the empty string.
+  Expect.equals("toAtoBtoCto", "ABC".replaceAll("", "to"));
+}
+
+void testCompareTo() {
+  Expect.equals(0, "".compareTo(""));
+  Expect.equals(0, "str".compareTo("str"));
+  Expect.equals(-1, "str".compareTo("string"));
+  Expect.equals(1, "string".compareTo("str"));
+  Expect.equals(1, "string".compareTo(""));
+  Expect.equals(-1, "".compareTo("string"));
+}
+
+void testCharCodes() {
+  test(str) {
+    var list = str.codeUnits;
+    Expect.equals(str.length, list.length);
     for (int i = 0; i < str.length; i++) {
-      Expect.isTrue(str[i] is String);
-      testStringLength(1, str[i]);
+      Expect.equals(str.codeUnitAt(i), list[i]);
     }
   }
-
-  static testCodeUnitAt() {
-    String str = "string";
-    for (int i = 0; i < str.length; i++) {
-      Expect.isTrue(str.codeUnitAt(i) is int);
-    }
-  }
-
-  static testConcat() {
-    var a = "One";
-    var b = "Four";
-    var c = a + b;
-    testStringLength(7, c);
-    Expect.equals("OneFour", c);
-  }
-
-  static testEquals() {
-    Expect.equals("str", "str");
-
-    Expect.equals("str", "s" + "t" + "r");
-    Expect.equals("s" + "t" + "r", "str");
-
-    Expect.isFalse("str" == "s");
-    Expect.isFalse("str" == "r");
-    Expect.isFalse("str" == "st");
-    Expect.isFalse("str" == "tr");
-
-    Expect.isFalse("s" == "str");
-    Expect.isFalse("r" == "str");
-    Expect.isFalse("st" == "str");
-    Expect.isFalse("tr" == "str");
-
-    Expect.isFalse("" == "s");
-    Expect.equals("", "");
-  }
-
-  static testEndsWith() {
-    Expect.isTrue("str".endsWith("r"));
-    Expect.isTrue("str".endsWith("tr"));
-    Expect.isTrue("str".endsWith("str"));
-
-    Expect.isFalse("str".endsWith("stri"));
-    Expect.isFalse("str".endsWith("t"));
-    Expect.isFalse("str".endsWith("st"));
-    Expect.isFalse("str".endsWith("s"));
-
-    Expect.isTrue("".endsWith(""));
-    Expect.isFalse("".endsWith("s"));
-  }
-
-  static testStartsWith() {
-    Expect.isTrue("str".startsWith("s"));
-    Expect.isTrue("str".startsWith("st"));
-    Expect.isTrue("str".startsWith("str"));
-
-    Expect.isFalse("str".startsWith("stri"));
-    Expect.isFalse("str".startsWith("r"));
-    Expect.isFalse("str".startsWith("tr"));
-    Expect.isFalse("str".startsWith("t"));
-
-    Expect.isTrue("".startsWith(""));
-    Expect.isFalse("".startsWith("s"));
-
-    Expect.isFalse("strstr".startsWith("s", 1));
-    Expect.isFalse("strstr".startsWith("s", 2));
-    Expect.isTrue("strstr".startsWith("s", 3));
-    Expect.isFalse("strstr".startsWith("s", 4));
-
-    Expect.isFalse("strstr".startsWith("st", 1));
-    Expect.isFalse("strstr".startsWith("st", 2));
-    Expect.isTrue("strstr".startsWith("st", 3));
-    Expect.isFalse("strstr".startsWith("st", 4));
-
-    Expect.isFalse("strstr".startsWith("str", 1));
-    Expect.isFalse("strstr".startsWith("str", 2));
-    Expect.isTrue("strstr".startsWith("str", 3));
-    Expect.isFalse("strstr".startsWith("str", 4));
-
-    Expect.isTrue("str".startsWith("", 0));
-    Expect.isTrue("str".startsWith("", 1));
-    Expect.isTrue("str".startsWith("", 2));
-    Expect.isTrue("str".startsWith("", 3));
-
-    Expect.throws(() => "str".startsWith("", -1));
-    Expect.throws(() => "str".startsWith("", 4));
-
-    var regexp = new RegExp("s(?:tr?)?");
-    Expect.isTrue("s".startsWith(regexp));
-    Expect.isTrue("st".startsWith(regexp));
-    Expect.isTrue("str".startsWith(regexp));
-    Expect.isTrue("sX".startsWith(regexp));
-    Expect.isTrue("stX".startsWith(regexp));
-    Expect.isTrue("strX".startsWith(regexp));
-
-    Expect.isFalse("".startsWith(regexp));
-    Expect.isFalse("astr".startsWith(regexp));
-
-    Expect.isTrue("".startsWith(new RegExp("")));
-    Expect.isTrue("".startsWith(new RegExp("a?")));
-
-    Expect.isFalse("strstr".startsWith(regexp, 1));
-    Expect.isFalse("strstr".startsWith(regexp, 2));
-    Expect.isTrue("strstr".startsWith(regexp, 3));
-    Expect.isFalse("strstr".startsWith(regexp, 4));
-
-    Expect.isTrue("str".startsWith(new RegExp(""), 0));
-    Expect.isTrue("str".startsWith(new RegExp(""), 1));
-    Expect.isTrue("str".startsWith(new RegExp(""), 2));
-    Expect.isTrue("str".startsWith(new RegExp(""), 3));
-    Expect.isTrue("str".startsWith(new RegExp("a?"), 0));
-    Expect.isTrue("str".startsWith(new RegExp("a?"), 1));
-    Expect.isTrue("str".startsWith(new RegExp("a?"), 2));
-    Expect.isTrue("str".startsWith(new RegExp("a?"), 3));
-
-    Expect.throws(() => "str".startsWith(regexp, -1));
-    Expect.throws(() => "str".startsWith(regexp, 4));
-
-    regexp = new RegExp("^str");
-    Expect.isTrue("strstr".startsWith(regexp));
-    Expect.isTrue("strstr".startsWith(regexp, 0));
-    Expect.isFalse("strstr".startsWith(regexp, 1));
-    Expect.isFalse("strstr".startsWith(regexp, 2));
-    Expect.isFalse("strstr".startsWith(regexp, 3));  // Second "str" isn't at ^.
-  }
-
-  static testIndexOf() {
-    Expect.equals(0, "str".indexOf("", 0));
-    Expect.equals(0, "".indexOf("", 0));
-    Expect.equals(-1, "".indexOf("a", 0));
-
-    Expect.equals(1, "str".indexOf("t", 0));
-    Expect.equals(1, "str".indexOf("tr", 0));
-    Expect.equals(0, "str".indexOf("str", 0));
-    Expect.equals(0, "str".indexOf("st", 0));
-    Expect.equals(0, "str".indexOf("s", 0));
-    Expect.equals(2, "str".indexOf("r", 0));
-    Expect.equals(-1, "str".indexOf("string", 0));
-
-    Expect.equals(1, "strstr".indexOf("t", 0));
-    Expect.equals(1, "strstr".indexOf("tr", 0));
-    Expect.equals(0, "strstr".indexOf("str", 0));
-    Expect.equals(0, "strstr".indexOf("st", 0));
-    Expect.equals(0, "strstr".indexOf("s", 0));
-    Expect.equals(2, "strstr".indexOf("r", 0));
-    Expect.equals(-1, "str".indexOf("string", 0));
-
-    Expect.equals(4, "strstr".indexOf("t", 2));
-    Expect.equals(4, "strstr".indexOf("tr", 2));
-    Expect.equals(3, "strstr".indexOf("str", 1));
-    Expect.equals(3, "strstr".indexOf("str", 2));
-    Expect.equals(3, "strstr".indexOf("str", 3));
-    Expect.equals(3, "strstr".indexOf("st", 1));
-    Expect.equals(3, "strstr".indexOf("s", 3));
-    Expect.equals(5, "strstr".indexOf("r", 3));
-    Expect.equals(5, "strstr".indexOf("r", 4));
-    Expect.equals(5, "strstr".indexOf("r", 5));
-
-    String str = "hello";
-    for (int i = 0; i < 10; i++) {
-      if (i > str.length) {
-        Expect.throws(() => str.indexOf("", i));
-      } else {
-        int result = str.indexOf("", i);
-        Expect.equals(i, result);
-      }
-    }
-
-    var re = new RegExp("an?");
-    Expect.equals(1, "banana".indexOf(re));
-    Expect.equals(1, "banana".indexOf(re, 0));
-    Expect.equals(1, "banana".indexOf(re, 1));
-    Expect.equals(3, "banana".indexOf(re, 2));
-    Expect.equals(3, "banana".indexOf(re, 3));
-    Expect.equals(5, "banana".indexOf(re, 4));
-    Expect.equals(5, "banana".indexOf(re, 5));
-    Expect.equals(-1, "banana".indexOf(re, 6));
-    Expect.throws(() => "banana".indexOf(re, -1));
-    Expect.throws(() => "banana".indexOf(re, 7));
-    re = new RegExp("x?");
-    for (int i = 0; i <= str.length; i++) {
-      Expect.equals(i, str.indexOf(re, i));
-    }
-  }
-
-  static testLastIndexOf() {
-    Expect.equals(2, "str".lastIndexOf("", 2));
-    Expect.equals(0, "".lastIndexOf("", 0));
-    Expect.equals(-1, "".lastIndexOf("a", 0));
-
-    Expect.equals(1, "str".lastIndexOf("t", 2));
-    Expect.equals(1, "str".lastIndexOf("tr", 2));
-    Expect.equals(0, "str".lastIndexOf("str", 2));
-    Expect.equals(0, "str".lastIndexOf("st", 2));
-    Expect.equals(0, "str".lastIndexOf("s", 2));
-    Expect.equals(2, "str".lastIndexOf("r", 2));
-    Expect.equals(-1, "str".lastIndexOf("string", 2));
-
-    Expect.equals(4, "strstr".lastIndexOf("t", 5));
-    Expect.equals(4, "strstr".lastIndexOf("tr", 5));
-    Expect.equals(3, "strstr".lastIndexOf("str", 5));
-    Expect.equals(3, "strstr".lastIndexOf("st", 5));
-    Expect.equals(3, "strstr".lastIndexOf("s", 5));
-    Expect.equals(5, "strstr".lastIndexOf("r", 5));
-    Expect.throws(() {
-        "str".lastIndexOf("string", 5);
-    });
-    Expect.equals(4, "strstr".lastIndexOf("t", 5));
-    Expect.equals(4, "strstr".lastIndexOf("tr", 5));
-    Expect.equals(3, "strstr".lastIndexOf("str", 5));
-    Expect.equals(3, "strstr".lastIndexOf("str", 5));
-    Expect.equals(3, "strstr".lastIndexOf("str", 5));
-    Expect.equals(3, "strstr".lastIndexOf("st", 5));
-    Expect.equals(3, "strstr".lastIndexOf("s", 5));
-    Expect.equals(5, "strstr".lastIndexOf("r", 5));
-    Expect.equals(2, "strstr".lastIndexOf("r", 4));
-    Expect.equals(2, "strstr".lastIndexOf("r", 3));
-    Expect.equals(5, "strstr".lastIndexOf("r"));
-    Expect.equals(5, "strstr".lastIndexOf("r", null));
-
-    String str = "hello";
-    for (int i = 0; i < 10; i++) {
-      if (i > str.length) {
-        Expect.throws(() => str.indexOf("", i));
-      } else {
-        int result = str.lastIndexOf("", i);
-        Expect.equals(i, result);
-      }
-    }
-
-    var re = new RegExp("an?");
-    Expect.equals(5, "banana".lastIndexOf(re));
-    Expect.equals(5, "banana".lastIndexOf(re, 6));
-    Expect.equals(5, "banana".lastIndexOf(re, 5));
-    Expect.equals(3, "banana".lastIndexOf(re, 4));
-    Expect.equals(3, "banana".lastIndexOf(re, 3));
-    Expect.equals(1, "banana".lastIndexOf(re, 2));
-    Expect.equals(1, "banana".lastIndexOf(re, 1));
-    Expect.equals(-1, "banana".lastIndexOf(re, 0));
-    Expect.throws(() => "banana".lastIndexOf(re, -1));
-    Expect.throws(() => "banana".lastIndexOf(re, 7));
-    re = new RegExp("x?");
-    for (int i = 0; i <= str.length; i++) {
-      Expect.equals(i, str.indexOf(re, i));
-    }
-  }
-
-  static testContains() {
-    Expect.isTrue("str".contains("s", 0));
-    Expect.isTrue("str".contains("st", 0));
-    Expect.isTrue("str".contains("str", 0));
-    Expect.isTrue("str".contains("t", 0));
-    Expect.isTrue("str".contains("r", 0));
-    Expect.isTrue("str".contains("tr", 0));
-
-    Expect.isFalse("str".contains("sr", 0));
-    Expect.isFalse("str".contains("string", 0));
-
-    Expect.isTrue("str".contains("", 0));
-    Expect.isTrue("".contains("", 0));
-    Expect.isFalse("".contains("s", 0));
-  }
-
-  static testReplaceAll() {
-    Expect.equals(
-        "AtoBtoCDtoE", "AfromBfromCDfromE".replaceAll("from", "to"));
-
-    // Test with the replaced string at the begining.
-    Expect.equals(
-        "toABtoCDtoE", "fromABfromCDfromE".replaceAll("from", "to"));
-
-    // Test with the replaced string at the end.
-    Expect.equals(
-        "toABtoCDtoEto", "fromABfromCDfromEfrom".replaceAll("from", "to"));
-
-    // Test when there are no occurence of the string to replace.
-    Expect.equals("ABC", "ABC".replaceAll("from", "to"));
-
-    // Test when the string to change is the empty string.
-    Expect.equals("", "".replaceAll("from", "to"));
-
-    // Test when the string to change is a substring of the string to
-    // replace.
-    Expect.equals("fro", "fro".replaceAll("from", "to"));
-
-    // Test when the string to change is the replaced string.
-    Expect.equals("to", "from".replaceAll("from", "to"));
-
-    // Test when the string to change is the replacement string.
-    Expect.equals("to", "to".replaceAll("from", "to"));
-
-    // Test replacing by the empty string.
-    Expect.equals("", "from".replaceAll("from", ""));
-    Expect.equals("AB", "AfromB".replaceAll("from", ""));
-
-    // Test changing the empty string.
-    Expect.equals("to", "".replaceAll("", "to"));
-
-    // Test replacing the empty string.
-    Expect.equals("toAtoBtoCto", "ABC".replaceAll("", "to"));
-  }
-
-  static testCompareTo() {
-    Expect.equals(0, "".compareTo(""));
-    Expect.equals(0, "str".compareTo("str"));
-    Expect.equals(-1, "str".compareTo("string"));
-    Expect.equals(1, "string".compareTo("str"));
-    Expect.equals(1, "string".compareTo(""));
-    Expect.equals(-1, "".compareTo("string"));
-  }
-
-  static testCharCodes() {
-    test(str) {
-      var list = str.codeUnits;
-      Expect.equals(str.length, list.length);
-      for (int i = 0; i < str.length; i++) {
-        Expect.equals(str.codeUnitAt(i), list[i]);
-      }
-    }
-    test("abc");
-    test("");
-    test(" ");
-  }
+  test("abc");
+  test("");
+  test(" ");
 }
 
 void testStringLength(int length, String str) {
@@ -393,6 +393,102 @@
   (length != 0 ? Expect.isTrue : Expect.isFalse)(str.isNotEmpty);
 }
 
-main() {
-  StringTest.testMain();
+void testRepeat() {
+  List<String> testStrings = [
+    "",
+    "\x00",
+    "a",
+    "ab",
+    "\x80",
+    "\xff",
+    "\u2028",
+    "abcdef\u2028",
+    "\u{10002}",
+    "abcdef\u{10002}"
+  ];
+  List<int> counts = [
+    0,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9,
+    10,
+    11,
+    12,
+    13,
+    14,
+    15,
+    16,
+    17,
+    127,
+    128,
+    129
+  ];
+  void testRepeat(str, repeat) {
+    String expect;
+    if (repeat <= 0) {
+      expect = "";
+    } else if (repeat == 1) {
+      expect = str;
+    } else {
+      StringBuffer buf = new StringBuffer();
+      for (int i = 0; i < repeat; i++) {
+        buf.write(str);
+      }
+      expect = buf.toString();
+    }
+    String actual = str * repeat;
+    Expect.equals(expect, actual,
+                  "$str#${str.length} * $repeat");
+  }
+  for (String str in testStrings) {
+    for (int repeat in counts) {
+      testRepeat(str, repeat);
+    }
+  }
+}
+
+void testPadLeft() {
+  Expect.equals("    1", "1".padLeft(5, ' '));
+  Expect.equals("   11", "11".padLeft(5, ' '));
+  Expect.equals("  111", "111".padLeft(5, ' '));
+  Expect.equals(" 1111", "1111".padLeft(5, ' '));
+  Expect.equals("11111", "11111".padLeft(5, ' '));
+  Expect.equals("111111", "111111".padLeft(5, ' '));
+  Expect.equals("   \u{10002}", "\u{10002}".padLeft(5, ' '));
+  Expect.equals('', ''.padLeft(0, 'a'));
+  Expect.equals('a', ''.padLeft(1, 'a'));
+  Expect.equals('aaaaa', ''.padLeft(5, 'a'));
+  Expect.equals('', ''.padLeft(-2, 'a'));
+
+  Expect.equals('xyzxyzxyzxyzxyz', ''.padLeft(5, 'xyz'));
+  Expect.equals('xyzxyzxyzxyza', 'a'.padLeft(5, 'xyz'));
+  Expect.equals('xyzxyzxyzaa', 'aa'.padLeft(5, 'xyz'));
+  Expect.equals('\u{10002}\u{10002}\u{10002}aa', 'aa'.padLeft(5, '\u{10002}'));
+  Expect.equals('a', 'a'.padLeft(10, ''));
+}
+
+void testPadRight() {
+  Expect.equals("1    ", "1".padRight(5, ' '));
+  Expect.equals("11   ", "11".padRight(5, ' '));
+  Expect.equals("111  ", "111".padRight(5, ' '));
+  Expect.equals("1111 ", "1111".padRight(5, ' '));
+  Expect.equals("11111", "11111".padRight(5, ' '));
+  Expect.equals("111111", "111111".padRight(5, ' '));
+  Expect.equals("\u{10002}   ", "\u{10002}".padRight(5, ' '));
+  Expect.equals('', ''.padRight(0, 'a'));
+  Expect.equals('a', ''.padRight(1, 'a'));
+  Expect.equals('aaaaa', ''.padRight(5, 'a'));
+  Expect.equals('', ''.padRight(-2, 'a'));
+
+  Expect.equals('xyzxyzxyzxyzxyz', ''.padRight(5, 'xyz'));
+  Expect.equals('axyzxyzxyzxyz', 'a'.padRight(5, 'xyz'));
+  Expect.equals('aaxyzxyzxyz', 'aa'.padRight(5, 'xyz'));
+  Expect.equals('aa\u{10002}\u{10002}\u{10002}', 'aa'.padRight(5, '\u{10002}'));
+  Expect.equals('a', 'a'.padRight(10, ''));
 }
diff --git a/tests/corelib/uri_file_test.dart b/tests/corelib/uri_file_test.dart
index d0e30a7..194fd9d 100644
--- a/tests/corelib/uri_file_test.dart
+++ b/tests/corelib/uri_file_test.dart
@@ -258,7 +258,7 @@
   check("file:///path#fragment");
   check("file:///path?query#fragment");
   check("file://host/path", windowsOk: true);
-  check("file://user@password:host/path");
+  check("file://user:password@host/path", windowsOk: true);
 }
 
 main() {
diff --git a/tests/corelib/uri_parse_test.dart b/tests/corelib/uri_parse_test.dart
new file mode 100644
index 0000000..2a0c980
--- /dev/null
+++ b/tests/corelib/uri_parse_test.dart
@@ -0,0 +1,61 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+
+void testUriCombi() {
+  var schemes = ["", "file", "ws", "ftp"];
+  var fragments = ["", "#", "#f", "#fragment", "#l:?/"];
+  var queries = ["", "?", "?q", "?query", "?q:/"];
+  var paths = ["/", "/x", "/x/y", "/x/y/", "/x:y"];
+  var userInfos = ["", "x", "xxx", "x:4", "xxx:444", "x:4:x"];
+  var hosts = ["", "h", "hhh", "h:4", "hhh:444", "[::1.2.3.4]"];
+
+  void check(uriString, scheme, fragment, query, path, user, host) {
+    var uri = Uri.parse(uriString);
+    Expect.equals(scheme, uri.scheme);
+    var uriFragment = uri.fragment;
+    if (fragment.startsWith('#')) uriFragment = "#$uriFragment";
+    Expect.equals(fragment, uriFragment);
+    var uriQuery = uri.query;
+    if (query.startsWith('?')) uriQuery = "?$uriQuery";
+    Expect.equals(query, uriQuery);
+    Expect.equals(path, uri.path);
+    Expect.equals(user, uri.userInfo);
+    var uriHost = uri.host;
+    if (host.startsWith("[")) uriHost = "[$uriHost]";
+    if (uri.port != 0) uriHost += ":${uri.port}";
+    Expect.equals(host, uriHost);
+  }
+
+  for (var scheme in schemes) {
+    for (var fragment in fragments) {
+      for (var query in queries) {
+        for (var path in paths) {
+          for (var user in userInfos) {
+            for (var host in hosts) {
+              var auth = host;
+              var s = scheme;
+              if (user.isNotEmpty) auth = "$user@$auth";
+              if (auth.isNotEmpty) auth = "//$auth";
+              check("$scheme${scheme.isEmpty ? "" : ":"}"
+                        "$auth$path$query$fragment",
+                    scheme,
+                    fragment,
+                    query,
+                    path,
+                    user,
+                    host);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void main() {
+  testUriCombi();
+}
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index 3e66ac9..19d4019 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -256,4 +256,9 @@
   testEncodeDecodeQueryComponent("A + B", "A+%2B+B", "A+%2B+B", "A+%2B+B");
   testEncodeDecodeQueryComponent(
       "æ ø å", "%C3%A6+%C3%B8+%C3%A5", "%E6+%F8+%E5", null);
+
+  // Invalid URI - : and @ is swapped, port ("host") should be numeric.
+  Expect.throws(
+      () => Uri.parse("file://user@password:host/path"),
+      (e) => e is FormatException);
 }
diff --git a/tests/html/custom/template_wrappers_test.dart b/tests/html/custom/template_wrappers_test.dart
index 4953d33..5b9ff64 100644
--- a/tests/html/custom/template_wrappers_test.dart
+++ b/tests/html/custom/template_wrappers_test.dart
@@ -25,12 +25,15 @@
 main() {
   useHtmlConfiguration();
 
-  setUp(customElementsReady);
+  setUp(() => customElementsReady);
 
   test('element is upgraded once', () {
 
     expect(createdCount, 0);
     document.register('x-custom', CustomElement);
+    expect(createdCount, 0);
+
+    var element = document.createElement('x-custom');
     expect(createdCount, 1);
 
     forceGC();
@@ -40,7 +43,7 @@
 
       var fragment = t.content;
 
-      fragment.querySelector('x-custom').checkCreated();
+      fragment.querySelector('x-custom').attributes['foo'] = 'true';
       expect(createdCount, 1);
     });
   });
diff --git a/tests/html/custom/template_wrappers_test.html b/tests/html/custom/template_wrappers_test.html
index c0844b6..ae80497 100644
--- a/tests/html/custom/template_wrappers_test.html
+++ b/tests/html/custom/template_wrappers_test.html
@@ -12,6 +12,7 @@
   </style>
   <script src="/packages/web_components/platform.concat.js"></script>
   <script src="/packages/web_components/dart_support.js"></script>
+  <script src="/packages/browser/interop.js"></script>
 </head>
 <body>
   <h1> Running template_wrappers_test </h1>
diff --git a/tests/html/filereader_test.dart b/tests/html/filereader_test.dart
new file mode 100644
index 0000000..9eb8a23
--- /dev/null
+++ b/tests/html/filereader_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library filereader_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+import 'dart:typed_data';
+
+main() {
+  useHtmlConfiguration();
+
+  test('readAsText', () {
+      var reader = new FileReader();
+      reader.onLoad.listen(expectAsync1((event) {
+        var result = reader.result;
+        expect(result, equals('hello world'));
+      }));
+      reader.readAsText(new Blob(['hello ', 'world']));
+  });
+
+  test('readAsArrayBuffer', () {
+      var reader = new FileReader();
+      reader.onLoad.listen(expectAsync1((event) {
+        var result = reader.result;
+        expect(result is Uint8List, isTrue);
+        expect(result, orderedEquals([65, 66, 67]));
+      }));
+      reader.readAsArrayBuffer(new Blob(['ABC']));
+  });
+
+  test('readDataUrl', () {
+      var reader = new FileReader();
+      reader.onLoad.listen(expectAsync1((event) {
+        var result = reader.result;
+        expect(result is String, isTrue);
+        expect(result.startsWith('data:'), isTrue);
+      }));
+      reader.readAsDataUrl(new Blob(['ABC']));
+  });
+
+}
diff --git a/tests/html/html.status b/tests/html/html.status
index 5688fe5..a45c1e1 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -6,14 +6,13 @@
 interactive_test: Skip # Must be run manually.
 dromaeo_smoke_test: Skip # Issue 14521, 8257
 custom/template_wrappers_test: Pass, Fail # Issue 16656 (Chrome 33 regression)
+[ $runtime == drt || $runtime == dartium ]
+custom/template_wrappers_test: Pass # Issue 16656 Override others
 
 [ $compiler == dart2js && $csp ]
 custom/js_custom_test: Fail # Issue 14643
 
 [ $compiler == dart2js && $browser ]
-custom/template_wrappers_test: RuntimeError # Test is for Dartium GC issues
-
-[ $compiler == dart2js && $browser ]
 custom/created_callback_test: Fail # Support for created constructor.
 
 [ $compiler == dart2js && ($runtime == safari || $runtime == ff || $runtime == chrome || $runtime == ie9 || $runtime == ie10) ]
@@ -38,6 +37,7 @@
 
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
+touchevent_test/supported: Pass, Fail # Issue 17061
 
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
@@ -71,8 +71,9 @@
 worker_api_test: Fail # IE does not support URL.createObjectURL in web workers.
 
 [ $runtime == chrome ]
-xhr_test: Pass, Fail # Issue 11884
+touchevent_test/supported: Pass, Fail # Issue 17061
 xhr_cross_origin_test: Pass, Fail # Issue 11884
+xhr_test: Pass, Fail # Issue 11884
 
 [$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid]
 webgl_1_test: Pass, Fail # Issue 8219
@@ -154,6 +155,7 @@
 custom/document_register_type_extensions_test/namespaces: Fail # Issue 13193
 dom_constructors_test: Fail
 element_test/click: Fail                # IE does not support firing this event.
+filereader_test: Fail   # Not supported.
 form_element_test: Fail # Issue 4793.
 localstorage_test: Fail
 postmessage_structured_test: Skip   # BUG(5685): times out.
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index b2d32ba..319fe98 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -10,8 +10,9 @@
 serialization_test: SkipByDesign # Tests dart2js-specific serialization code
 isolate_throws_test/01: Skip # Issue 12587
 compile_time_error_test/01: Skip # Issue 12587
-capability_test: Fail  # Not implemented yet
-pause_test: Fail       # Not implemented yet
+capability_test: Fail   # Not implemented yet
+pause_test: Fail        # Not implemented yet
+start_paused_test: Fail # Not implemented yet
 
 [ $compiler == dart2js && $jscl ]
 browser/*: SkipByDesign  # Browser specific tests
diff --git a/tests/isolate/start_paused_test.dart b/tests/isolate/start_paused_test.dart
new file mode 100644
index 0000000..7bcaba5
--- /dev/null
+++ b/tests/isolate/start_paused_test.dart
@@ -0,0 +1,81 @@
+// 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 start_paused_test;
+
+import "dart:isolate";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+void isomain(SendPort p) {
+  p.send("DONE");
+}
+
+void notyet(_) {
+  throw "NOT YET";
+}
+
+void main() {
+  asyncStart();
+  test1();
+  test2();
+  asyncEnd();
+}
+
+void test1() {
+  // Test that a paused isolate doesn't send events.
+  // We start two isolates, one paused and one not.
+  // The unpaused one must send an event, after which
+  // we resume that paused isolate, and expect the second event.
+  // This is not a guaranteed test, since it can succeede even if the
+  // paused isolate isn't really paused.
+  // However, it must never fail, since that would mean that a paused
+  // isolate sends a message.
+  asyncStart();
+  RawReceivePort p1 = new RawReceivePort(notyet);
+  Isolate.spawn(isomain, p1.sendPort, paused: true)
+         .then((isolate) {
+    RawReceivePort p2;
+    p2 = new RawReceivePort((x) {
+      Expect.equals("DONE", x);
+      p2.close();
+      p1.handler = (x) {
+        Expect.equals("DONE", x);
+        p1.close();
+        asyncEnd();
+      };
+      isolate.resume(isolate.pauseCapability);
+    });
+    Isolate.spawn(isomain, p2.sendPort);
+  });
+}
+
+void test2() {
+  // Test that a paused isolate doesn't send events.
+  // Like the test above, except that we change the pause capability
+  // of the paused isolate by pausing it using another capability and
+  // then resuming the initial pause. This must not cause it to send
+  // a message before the second pause is resumed as well.
+  asyncStart();
+  RawReceivePort p1 = new RawReceivePort(notyet);
+  Isolate.spawn(isomain, p1.sendPort, paused: true)
+         .then((isolate) {
+    RawReceivePort p2;
+    Capability c2 = new Capability();
+    // Switch to another pause capability.
+    isolate.pause(c2);
+    isolate.resume(isolate.pauseCapability);
+    p2 = new RawReceivePort((x) {
+      Expect.equals("DONE", x);
+      p2.close();
+      p1.handler = (x) {
+        Expect.equals("DONE", x);
+        p1.close();
+        asyncEnd();
+      };
+      isolate.resume(c2);
+    });
+    Isolate.spawn(isomain, p2.sendPort);
+  });
+}
diff --git a/tests/language/abstract_exact_selector_test.dart b/tests/language/abstract_exact_selector_test.dart
index fd61a10..8932dc3 100644
--- a/tests/language/abstract_exact_selector_test.dart
+++ b/tests/language/abstract_exact_selector_test.dart
@@ -8,7 +8,8 @@
 import "package:expect/expect.dart";
 import "compiler_annotations.dart";
 
-abstract class Foo {
+abstract /// 01: static type warning
+class Foo {
   noSuchMethod(im) => 42;
 }
 
diff --git a/tests/language/abstract_factory_constructor_test.dart b/tests/language/abstract_factory_constructor_test.dart
index d2e3a6f..d20401a 100644
--- a/tests/language/abstract_factory_constructor_test.dart
+++ b/tests/language/abstract_factory_constructor_test.dart
@@ -11,18 +11,19 @@
   method() {}
 }
 
-class A1 {
+abstract class A1 {
   A1() {}
   method();  // Abstract.
   factory A1.make() { return new B(); }
 }
 
 class A2 {
-  method();  // Abstract.
+  // Intentionally abstract method.
+  method();  /// 00: static type warning
   A2.make() {}
 }
 
 main() {
   new A1.make();
-  new A2.make();              /// 00: static type warning
+  new A2.make();              /// 00: continued
 }
diff --git a/tests/language/abstract_getter_test.dart b/tests/language/abstract_getter_test.dart
index 7befb6c..6a699f4 100644
--- a/tests/language/abstract_getter_test.dart
+++ b/tests/language/abstract_getter_test.dart
@@ -7,7 +7,8 @@
 // Test to ensure that an abstract getter is not mistaken for a field.
 
 class Foo {
-  get i;  // Abstract.
+  // Intentionally abstract:
+  get i;  /// 01: static type warning
 }
 
 class Bar {
@@ -16,9 +17,9 @@
 noMethod(e) => e is NoSuchMethodError;
 
 checkIt(f) {
-  Expect.throws(() { f.i = 'hi'; }, noMethod);
-  Expect.throws(() { print(f.i); }, noMethod);
-  Expect.throws(() { print(f.i()); }, noMethod);
+  Expect.throws(() { f.i = 'hi'; }, noMethod);  /// 01: continued
+  Expect.throws(() { print(f.i); }, noMethod);  /// 01: continued
+  Expect.throws(() { print(f.i()); }, noMethod);  /// 01: continued
 }
 
 main() {
diff --git a/tests/language/abstract_runtime_error_test.dart b/tests/language/abstract_runtime_error_test.dart
index c408ec8..eb6a0ea 100644
--- a/tests/language/abstract_runtime_error_test.dart
+++ b/tests/language/abstract_runtime_error_test.dart
@@ -12,7 +12,7 @@
 
 
 abstract class Interface {
-  void foo();
+  void foo(); /// 03: static type warning
 }
 
 abstract class AbstractClass {
@@ -27,19 +27,19 @@
   toString() => 'NonAbstractClass';
 }
 
-Interface interface() => new Interface();
+Interface interface() => new Interface(); /// 01: static type warning
 
-AbstractClass abstractClass() => new AbstractClass();
+AbstractClass abstractClass() => new AbstractClass(); /// 02: static type warning
 
 bool isAbstractClassInstantiationError(e) {
   return e is AbstractClassInstantiationError;
 }
 
 void main() {
-  Expect.throws(interface, isAbstractClassInstantiationError,
-                "expected AbstractClassInstantiationError");
-  Expect.throws(abstractClass, isAbstractClassInstantiationError,
-                "expected AbstractClassInstantiationError");
+  Expect.throws(interface, isAbstractClassInstantiationError, /// 01: continued
+                "expected AbstractClassInstantiationError");  /// 01: continued
+  Expect.throws(abstractClass, isAbstractClassInstantiationError, /// 02: continued
+                "expected AbstractClassInstantiationError");      /// 02: continued
   Expect.stringEquals('ConcreteSubclass', '${new ConcreteSubclass()}');
   Expect.stringEquals('NonAbstractClass', '${new NonAbstractClass()}');
 }
diff --git a/tests/language/assign_top_method_test.dart b/tests/language/assign_top_method_test.dart
index 923d9e0..c4f9e0d 100644
--- a/tests/language/assign_top_method_test.dart
+++ b/tests/language/assign_top_method_test.dart
@@ -8,6 +8,6 @@
 
 main() {
   // Illegal, can't change a top level method
-  Expect.throws(() { method = () { return 1; }; },
-                (e) => e is NoSuchMethodError);
+  Expect.throws(() { method = () { return 1; }; }, /// 01: static type warning
+                (e) => e is NoSuchMethodError);    /// 01: continued
 }
diff --git a/tests/language/bad_named_parameters2_test.dart b/tests/language/bad_named_parameters2_test.dart
index 1d0a273..65d9bf8 100644
--- a/tests/language/bad_named_parameters2_test.dart
+++ b/tests/language/bad_named_parameters2_test.dart
@@ -22,11 +22,11 @@
     try {
       caught = false;
       // No formal parameter named b.
-      np.foo(b:25);  /// static type warning
+      np.foo(b:25);  /// 01: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 01: continued
   }
 }
 
diff --git a/tests/language/bad_named_parameters_test.dart b/tests/language/bad_named_parameters_test.dart
index bbe9b28..06510e0 100644
--- a/tests/language/bad_named_parameters_test.dart
+++ b/tests/language/bad_named_parameters_test.dart
@@ -24,43 +24,43 @@
     try {
       caught = false;
       // Parameter b passed twice.
-      np.f42(10, 25, b:25);  /// static type warning
+      np.f42(10, 25, b:25); /// 01: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 01: continued
     try {
       caught = false;
       // Parameter x does not exist.
-      np.f42(10, 25, x:99);  /// static type warning
+      np.f42(10, 25, x:99); /// 02: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 02: continued
     try {
       caught = false;
       // Parameter b1 does not exist.
-      np.f52(10, b:25, b1:99, c:35);  /// static type warning
+      np.f52(10, b:25, b1:99, c:35); /// 03: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 03: continued
     try {
       caught = false;
       // Too many parameters.
-      np.f42(10, 20, 30, 40); /// static type warning
+      np.f42(10, 20, 30, 40); /// 04: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 04: continued
     try {
       caught = false;
       // Too few parameters.
-      np.f42(b:25);  /// static type warning
+      np.f42(b:25); /// 05: static type warning
     } on NoSuchMethodError catch (e) {
       caught = true;
     }
-    Expect.equals(true, caught);
+    Expect.equals(true, caught); /// 05: continued
   }
 }
 
diff --git a/tests/language/bit_operations_test.dart b/tests/language/bit_operations_test.dart
index 6c7b106..2d46ba7 100644
--- a/tests/language/bit_operations_test.dart
+++ b/tests/language/bit_operations_test.dart
@@ -93,19 +93,19 @@
   Expect.equals(0xffffffff, t << 0);
   Expect.equals(0x1fffffffe, t << 1);
   Expect.equals(0x7fffffff80000000, t << 31);
-  Expect.equals(0x10000000000000000, 2*(t+1) << 31);
-  Expect.equals(0x20000000000000000, 4*(t+1) << 31);
+  Expect.equals(0x10000000000000000, 2*(t+1) << 31); /// 01: static type warning
+  Expect.equals(0x20000000000000000, 4*(t+1) << 31); /// 02: static type warning
   Expect.equals(0x8000000000000000, (t+1) << 31);
 }
 
 void testLeftShift64BitWithOverflow1() {
   var t = 0xffffffff;
-  Expect.equals(0x10000000000000000, 2*(t+1) << 31);
+  Expect.equals(0x10000000000000000, 2*(t+1) << 31); /// 03: static type warning
 }
 
 void testLeftShift64BitWithOverflow2() {
   var t = 0xffffffff;
-  Expect.equals(0x20000000000000000, 4*(t+1) << 31);
+  Expect.equals(0x20000000000000000, 4*(t+1) << 31); /// 04: static type warning
 }
 
 void testLeftShift64BitWithOverflow3() {
diff --git a/tests/language/call_constructor_on_unresolvable_class_test.dart b/tests/language/call_constructor_on_unresolvable_class_test.dart
index 9e02d7d..676114b 100644
--- a/tests/language/call_constructor_on_unresolvable_class_test.dart
+++ b/tests/language/call_constructor_on_unresolvable_class_test.dart
@@ -24,9 +24,9 @@
     new lib.A();     /// 03: static type warning
   }
 
-  new A();         /// 04: runtime error
-  new A.foo();     /// 05: runtime error
-  new lib.A();     /// 06: runtime error
+  new A();         /// 04: static type warning, runtime error
+  new A.foo();     /// 05: static type warning, runtime error
+  new lib.A();     /// 06: static type warning, runtime error
 
   var ex;                    /// 07: static type warning
   try {                      /// 07: continued
diff --git a/tests/language/call_nonexistent_constructor_test.dart b/tests/language/call_nonexistent_constructor_test.dart
index fa8efe5..d3cf60a 100644
--- a/tests/language/call_nonexistent_constructor_test.dart
+++ b/tests/language/call_nonexistent_constructor_test.dart
@@ -19,17 +19,18 @@
   int i = 0;
   new A.foo(42);
   try {
-    new A.bar(foo());  // Args are evaluated before throwing NoSuchMethodError.
+    // Args are evaluated before throwing NoSuchMethodError:
+    new A.bar(foo()); /// 01: static type warning
   } on NoSuchMethodError catch (e) {
     i = -1;
   } on String catch (e) {
     i = 1;
   }
-  Expect.equals(1, i);
+  Expect.equals(1, i); /// 01: continued
   try {
-    new A();
+    new A(); /// 02: static type warning
   } on NoSuchMethodError catch (e) {
     i = 2;
   }
-  Expect.equals(2, i);
+  Expect.equals(2, i); /// 02: continued
 }
diff --git a/tests/language/checked_null_test.dart b/tests/language/checked_null_test.dart
index 0f2a200f..95df12b 100644
--- a/tests/language/checked_null_test.dart
+++ b/tests/language/checked_null_test.dart
@@ -12,8 +12,8 @@
   A() : b = null, a = null;
 }
 
-main() { 
-  Expect.throws(bar);
+main() {
+  Expect.throws(bar); /// 01: continued
 }
 
 bar() {
@@ -21,5 +21,5 @@
   // receiver type is a typedef. Some code in the dart2js backend were
   // not dealing correctly with typedefs and lead the compiler to
   // crash.
-  new A().a.foo();
+  new A().a.foo(); /// 01: static type warning
 }
diff --git a/tests/language/checked_setter2_test.dart b/tests/language/checked_setter2_test.dart
index 370c8d0..f6606bf6 100644
--- a/tests/language/checked_setter2_test.dart
+++ b/tests/language/checked_setter2_test.dart
@@ -22,7 +22,8 @@
   array[0].c = new C();
   bool inCheckedMode = false;
   try {
-    String a = 42;
+    var i = 42;
+    String a = i;
   } catch (e) {
     inCheckedMode = true;
   }
diff --git a/tests/language/checked_setter3_test.dart b/tests/language/checked_setter3_test.dart
index 7a3e697..2af3a0d 100644
--- a/tests/language/checked_setter3_test.dart
+++ b/tests/language/checked_setter3_test.dart
@@ -19,23 +19,25 @@
 }
 
 class B<T> {
-  T field = 42;
+  T field = 42; /// 01: static type warning
 }
 
 class C<T> {
-  T field = 42;
+  T field = 42; /// 02: static type warning
 }
 
 main() {
   var a = new A<String>();
   var c = new C<int>();
+  var i = 42;
+  var s = 'foo';
   if (inCheckedMode) {
-    Expect.throws(() => a.field = 42, (e) => e is TypeError);
-    Expect.throws(() => new B<String>(), (e) => e is TypeError);
-    Expect.throws(() => c.field = 'foo', (e) => e is TypeError);
+    Expect.throws(() => a.field = i, (e) => e is TypeError);
+    Expect.throws(() => new B<String>(), (e) => e is TypeError); /// 01: continued
+    Expect.throws(() => c.field = s, (e) => e is TypeError); /// 02: continued
   } else {
-    a.field = 42;
-    new B<String>();
-    c.field = 'foo';
+    a.field = i;
+    new B<String>(); /// 01: continued
+    c.field = s; /// 02: continued
   }
 }
diff --git a/tests/language/checked_setter_test.dart b/tests/language/checked_setter_test.dart
index 608a472..71af4af 100644
--- a/tests/language/checked_setter_test.dart
+++ b/tests/language/checked_setter_test.dart
@@ -22,7 +22,8 @@
   array[0].c = new C();
   bool inCheckedMode = false;
   try {
-    String a = 42;
+    var i = 42;
+    String a = i;
   } catch (e) {
     inCheckedMode = true;
   }
diff --git a/tests/language/class_literal_test.dart b/tests/language/class_literal_test.dart
index 161073d..58de6dd 100644
--- a/tests/language/class_literal_test.dart
+++ b/tests/language/class_literal_test.dart
@@ -15,7 +15,7 @@
 main() {
   Expect.equals(42, Class.fisk());
   Expect.equals(null, foo(Class.fisk()));
-  
+
   // Verify references to a class literal are allowed.
   Class;
   var x = Class;
@@ -23,38 +23,38 @@
   Expect.isFalse(Class == null);
 
   // Verify that dereferencing a class literal is a runtime error.
-  Expect.throws(() { Class(); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class[0]; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class(); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class[0]; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class[0].field; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class[0].method(); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class()); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class[0]); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class[0].field); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class[0].method()); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class[0] = 91; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class++; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { ++Class; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class[0] += 3; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { ++Class[0]; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class[0]++; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class.method(); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class.field; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class.method(); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { var x = Class.field; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class.method()); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { foo(Class.field); }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class / 3; }, (e) => e is NoSuchMethodError);
-  Expect.throws(() { Class += 3; }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { Class(); }, (e) => e is NoSuchMethodError); /// 01: static type warning
+  Expect.throws(() { Class[0]; }, (e) => e is NoSuchMethodError); /// 02: static type warning
+  Expect.throws(() { var x = Class(); }, (e) => e is NoSuchMethodError); /// 03: static type warning
+  Expect.throws(() { var x = Class[0]; }, (e) => e is NoSuchMethodError); /// 04: static type warning
+  Expect.throws(() { var x = Class[0].field; }, (e) => e is NoSuchMethodError); /// 05: static type warning
+  Expect.throws(() { var x = Class[0].method(); }, (e) => e is NoSuchMethodError); /// 06: static type warning
+  Expect.throws(() { foo(Class()); }, (e) => e is NoSuchMethodError); /// 07: static type warning
+  Expect.throws(() { foo(Class[0]); }, (e) => e is NoSuchMethodError); /// 08: static type warning
+  Expect.throws(() { foo(Class[0].field); }, (e) => e is NoSuchMethodError); /// 09: static type warning
+  Expect.throws(() { foo(Class[0].method()); }, (e) => e is NoSuchMethodError); /// 10: static type warning
+  Expect.throws(() { Class[0] = 91; }, (e) => e is NoSuchMethodError); /// 11: static type warning
+  Expect.throws(() { Class++; }, (e) => e is NoSuchMethodError); /// 12: static type warning
+  Expect.throws(() { ++Class; }, (e) => e is NoSuchMethodError); /// 13: static type warning
+  Expect.throws(() { Class[0] += 3; }, (e) => e is NoSuchMethodError); /// 14: static type warning
+  Expect.throws(() { ++Class[0]; }, (e) => e is NoSuchMethodError); /// 15: static type warning
+  Expect.throws(() { Class[0]++; }, (e) => e is NoSuchMethodError); /// 16: static type warning
+  Expect.throws(() { Class.method(); }, (e) => e is NoSuchMethodError); /// 17: static type warning
+  Expect.throws(() { Class.field; }, (e) => e is NoSuchMethodError); /// 18: static type warning
+  Expect.throws(() { var x = Class.method(); }, (e) => e is NoSuchMethodError); /// 19: static type warning
+  Expect.throws(() { var x = Class.field; }, (e) => e is NoSuchMethodError); /// 20: static type warning
+  Expect.throws(() { foo(Class.method()); }, (e) => e is NoSuchMethodError); /// 21: static type warning
+  Expect.throws(() { foo(Class.field); }, (e) => e is NoSuchMethodError); /// 22: static type warning
+  Expect.throws(() { Class / 3; }, (e) => e is NoSuchMethodError); /// 23: static type warning
+  Expect.throws(() { Class += 3; }, (e) => e is NoSuchMethodError); /// 24: static type warning
 
   // Verify that a class literal isn't a string literal.
   Expect.notEquals(Class, "Class");
-   
+
   // Verify toString() works for class literals.
   Expect.isTrue((Class).toString() is String);
   var y = Class;
   Expect.isTrue(y.toString() is String);
-  
-  Expect.throws(() { Class.toString(); }, (e) => e is NoSuchMethodError);
+
+  Expect.throws(() { Class.toString(); }, (e) => e is NoSuchMethodError); /// 25: static type warning
 }
diff --git a/tests/language/closure_type_test.dart b/tests/language/closure_type_test.dart
index 59d11de..5b8eea2 100644
--- a/tests/language/closure_type_test.dart
+++ b/tests/language/closure_type_test.dart
@@ -1,6 +1,7 @@
 // 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.
+
 // Dart test for a closure result type test that cannot be eliminated at compile
 // time.
 
@@ -9,7 +10,9 @@
 import 'dart:math' as math;
 
 class Math {
-  static int sqrt(x) => math.sqrt(x);
+  static
+  int  /// 01: static type warning
+  sqrt(x) => math.sqrt(x);
 }
 
 isCheckedMode() {
diff --git a/tests/language/compile_time_constant_k_test.dart b/tests/language/compile_time_constant_k_test.dart
index f4260a3..645d22d 100644
--- a/tests/language/compile_time_constant_k_test.dart
+++ b/tests/language/compile_time_constant_k_test.dart
@@ -4,11 +4,15 @@
 
 import "package:expect/expect.dart";
 
-const x = const { 'a': 3, 'a': 4 };
-const y = const { 'a': 10, 'b': 11, 'a': 12, 'b': 13, 'a': 14 };
-const z = const { '__proto__': 496,
-                  '__proto__': 497,
-                  '__proto__': 498,
+const x = const {
+                  'a': 3,  /// 01: static type warning
+                  'a': 4 };
+const y = const { 'a': 10, 'b': 11, 'a': 12,  /// 02: static type warning
+                  'b': 13, 'a': 14 };         /// 02: continued
+const z = const {
+                  '__proto__': 496,  /// 03: static type warning
+                  '__proto__': 497,  /// 03: continued
+                  '__proto__': 498,  /// 03: continued
                   '__proto__': 499 };
 
 const x2 = const { 'a': 4 };
@@ -17,6 +21,6 @@
 
 main() {
   Expect.identical(x2, x);
-  Expect.identical(y2, y);
+  Expect.identical(y2, y);  /// 02: continued
   Expect.identical(z2, z);
 }
diff --git a/tests/language/compile_time_constant_o_test.dart b/tests/language/compile_time_constant_o_test.dart
index 6af0826..2438881 100644
--- a/tests/language/compile_time_constant_o_test.dart
+++ b/tests/language/compile_time_constant_o_test.dart
@@ -8,8 +8,12 @@
 const str = "foo";
 const m1 = const { "foo": 499 };
 const m2 = const { "$str": 499 };
-const m3 = const { "$str": 42, "foo": 499 };
-const m4 = const { "foo": 42, "$str": 499 };
+const m3 = const {
+                   "$str": 42, /// 01: static type warning
+                   "foo": 499 };
+const m4 = const {
+                   "foo": 42, /// 02: static type warning
+                   "$str": 499 };
 const m5 = const { "f" "o" "o": 499 };
 
 const mm1 = const { "afoo#foo": 499 };
diff --git a/tests/language/const_objects_are_immutable_test.dart b/tests/language/const_objects_are_immutable_test.dart
index c3f6d21..eb32b40 100644
--- a/tests/language/const_objects_are_immutable_test.dart
+++ b/tests/language/const_objects_are_immutable_test.dart
@@ -24,6 +24,6 @@
   Expect.equals(1, a1.x);
 
   A a2 = const A(1, 2);
-  Expect.throws(() => a2.x = 499);
+  Expect.throws(() => a2.x = 499); /// 01: static type warning
   Expect.equals(1, a2.x);
 }
diff --git a/tests/language/constructor_named_arguments_test.dart b/tests/language/constructor_named_arguments_test.dart
index 63e5e34..063a881 100644
--- a/tests/language/constructor_named_arguments_test.dart
+++ b/tests/language/constructor_named_arguments_test.dart
@@ -23,7 +23,7 @@
   X({a: 'defa', b: 'defb'}) : this.i = a, this.j = b;
   X.foo() : this(b: 1, a: 2);
   X.bar() : this(
-                     1,  /// 01: runtime error
+                     1,  /// 01: static type warning, runtime error
                      a: 2);
   X.baz() : this(a: 1, b: 2);
   X.qux() : this(b: 2);
diff --git a/tests/language/constructor_test.dart b/tests/language/constructor_test.dart
index eb7239c..54923f0 100644
--- a/tests/language/constructor_test.dart
+++ b/tests/language/constructor_test.dart
@@ -23,10 +23,11 @@
 
 // Test the order of initialization: first the instance variable then
 // the super constructor.
-class Alpha {
+abstract class Alpha {
   Alpha(v) {
     this.foo(v);
   }
+  foo(v) => throw 'Alpha.foo should never be called.';
 }
 
 class Beta extends Alpha {
diff --git a/tests/language/core_type_check_test.dart b/tests/language/core_type_check_test.dart
index 86f525b..4af2590 100644
--- a/tests/language/core_type_check_test.dart
+++ b/tests/language/core_type_check_test.dart
@@ -12,15 +12,21 @@
 int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
 
 class A implements Comparable {
+  int compareTo(o) => 0;
 }
 
 class B {
 }
 
 class C implements Pattern {
+  matchAsPrefix(String s, [int start = 0]) => null;
+  allMatches(String s) => null;
 }
 
 class D implements Pattern, Comparable {
+  int compareTo(o) => 0;
+  matchAsPrefix(String s, [int start = 0]) => null;
+  allMatches(String s) => null;
 }
 
 main() {
diff --git a/tests/language/crash_6725_part.dart b/tests/language/crash_6725_part.dart
new file mode 100644
index 0000000..8687837
--- /dev/null
+++ b/tests/language/crash_6725_part.dart
@@ -0,0 +1,73 @@
+// 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.
+
+// Regression test for a crash in dart2js.
+
+part of crash_6725;
+
+class Fisk {
+  it1(x) {
+    // "key" is unresolved and caused a crash in dart2js.
+    // This is the original example the user reported.
+    for (key in x) {
+      print(key);
+    }
+  }
+
+  it2(x) {
+    // "length" is "intercepted" and handled differently from other
+    // names when an instance of list is observed.
+    for (length in x) {
+      print(length);
+    }
+  }
+
+  it3(x) {
+    // We're pretty sure that there's no "fisk" that is "intercepted".
+    for (fisk in x) {
+      print(fisk);
+    }
+  }
+}
+
+class SubFisk extends Fisk {
+  var key;
+  var length;
+  var fisk;
+}
+
+test() {
+  Fisk f = new SubFisk();
+  var m = (x) {
+    for (undeclared in x) {
+      print(undeclared);
+    }
+  };
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    f = null;
+    m = (x) {};
+  }
+
+  f.it1([87, 42]);
+  if (f.key != 42) {
+    throw 'f.key != 42 (${f.key})';
+  }
+
+  f.it2([87, 42]);
+  if (f.length != 42) {
+    throw 'f.length != 42 (${f.length})';
+  }
+
+  f.it3([87, 42]);
+  if (f.fisk != 42) {
+    throw 'f.fisk != 42 (${f.fisk})';
+  }
+
+  try {
+    m([87, 42]);
+    throw 'NoSuchMethodError expected';
+  } on NoSuchMethodError {
+    // Expected.
+  }
+}
diff --git a/tests/language/crash_6725_test.dart b/tests/language/crash_6725_test.dart
index f9cbb18..420111f 100644
--- a/tests/language/crash_6725_test.dart
+++ b/tests/language/crash_6725_test.dart
@@ -4,68 +4,10 @@
 
 // Regression test for a crash in dart2js.
 
-class Fisk {
-  it1(x) {
-    // "key" is unresolved and caused a crash in dart2js.
-    // This is the original example the user reported.
-    for (key in x) {
-      print(key);
-    }
-  }
+library crash_6725;
 
-  it2(x) {
-    // "length" is "intercepted" and handled differently from other
-    // names when an instance of list is observed.
-    for (length in x) {
-      print(length);
-    }
-  }
-
-  it3(x) {
-    // We're pretty sure that there's no "fisk" that is "intercepted".
-    for (fisk in x) {
-      print(fisk);
-    }
-  }
-}
-
-class SubFisk extends Fisk {
-  var key;
-  var length;
-  var fisk;
-}
+part 'crash_6725_part.dart'; /// 01: static type warning
 
 main() {
-  Fisk f = new SubFisk();
-  var m = (x) {
-    for (undeclared in x) {
-      print(undeclared);
-    }
-  };
-  if (new DateTime.now().millisecondsSinceEpoch == 42) {
-    f = null;
-    m = (x) {};
-  }
-
-  f.it1([87, 42]);
-  if (f.key != 42) {
-    throw 'f.key != 42 (${f.key})';
-  }
-
-  f.it2([87, 42]);
-  if (f.length != 42) {
-    throw 'f.length != 42 (${f.length})';
-  }
-
-  f.it3([87, 42]);
-  if (f.fisk != 42) {
-    throw 'f.fisk != 42 (${f.fisk})';
-  }
-
-  try {
-    m([87, 42]);
-    throw 'NoSuchMethodError expected';
-  } on NoSuchMethodError {
-    // Expected.
-  }
+  test(); /// 01: continued
 }
diff --git a/tests/language/default_factory_library_test.dart b/tests/language/default_factory_library_test.dart
index 92a44f4..ad7291b 100644
--- a/tests/language/default_factory_library_test.dart
+++ b/tests/language/default_factory_library_test.dart
@@ -13,7 +13,7 @@
   int methodB() { return 2; }
 }
 
-class C {
+abstract class C implements lib.A {
   // Referenced from an abstract class in another library
   factory C.A () { return new B(); }
 }
diff --git a/tests/language/default_factory_test.dart b/tests/language/default_factory_test.dart
index bc4ce60..bac3a04 100644
--- a/tests/language/default_factory_test.dart
+++ b/tests/language/default_factory_test.dart
@@ -7,7 +7,7 @@
 // Dart test program for testing default factories.
 
 abstract class Vehicle {
-  factory Vehicle() = GoogleOne.Vehicle;
+  factory Vehicle() = GoogleOne.Vehicle; /// 01: static type warning
 }
 
 
@@ -31,5 +31,5 @@
 main() {
   Expect.equals(true, (new Bike.redOne()) is Bike);
   Expect.equals(true, (new SpaceShip()) is GoogleOne);
-  Expect.equals(true, (new Vehicle()) is Bike);
+  Expect.equals(true, (new Vehicle()) is Bike); /// 01: continued
 }
diff --git a/tests/language/deferred_constraints_lib.dart b/tests/language/deferred_constraints_lib.dart
new file mode 100644
index 0000000..cdc9d4d
--- /dev/null
+++ b/tests/language/deferred_constraints_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+class C {}
+
+class Const {
+  const Const();
+}
+
+const constantInstance = const Const();
\ No newline at end of file
diff --git a/tests/language/deferred_constraints_lib2.dart b/tests/language/deferred_constraints_lib2.dart
new file mode 100644
index 0000000..7352126
--- /dev/null
+++ b/tests/language/deferred_constraints_lib2.dart
@@ -0,0 +1,5 @@
+// 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.
+
+foo () => 42;
\ No newline at end of file
diff --git a/tests/language/deferred_duplicate_prefix1_test.dart b/tests/language/deferred_duplicate_prefix1_test.dart
new file mode 100644
index 0000000..495d061
--- /dev/null
+++ b/tests/language/deferred_duplicate_prefix1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+
+import "deferred_constraints_lib2.dart" as lib;
+@lazy import "deferred_constraints_lib.dart" as lib; /// 01: compile-time error
+
+const lazy = const DeferredLibrary('lib');
+
+void main() {}
diff --git a/tests/language/deferred_duplicate_prefix2_test.dart b/tests/language/deferred_duplicate_prefix2_test.dart
new file mode 100644
index 0000000..06af454
--- /dev/null
+++ b/tests/language/deferred_duplicate_prefix2_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+
+@lazy import "deferred_constraints_lib.dart" as lib;  /// 01: compile-time error
+import "deferred_constraints_lib2.dart" as lib;
+
+const lazy = const DeferredLibrary('lib');
+
+void main() {}
diff --git a/tests/language/deferred_duplicate_prefix3_test.dart b/tests/language/deferred_duplicate_prefix3_test.dart
new file mode 100644
index 0000000..15d5e6d
--- /dev/null
+++ b/tests/language/deferred_duplicate_prefix3_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+
+@lazy import "deferred_constraints_lib.dart" as lib;
+@lazy2 import "deferred_constraints_lib2.dart" as lib; /// 01: compile-time error
+
+const lazy = const DeferredLibrary('lib');
+const lazy2 = const DeferredLibrary('lib2');
+
+void main() {}
diff --git a/tests/language/deferred_no_prefix_test.dart b/tests/language/deferred_no_prefix_test.dart
new file mode 100644
index 0000000..3fed27b
--- /dev/null
+++ b/tests/language/deferred_no_prefix_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+
+// Loading a deferred library without prefix is not allowed.
+@lazy import "deferred_constraints_lib2.dart"; /// 01: compile-time error
+
+const lazy = const DeferredLibrary('lib');
+
+void main() {}
diff --git a/tests/language/double_to_string_as_exponential2_test.dart b/tests/language/double_to_string_as_exponential2_test.dart
index f5030ca..e296762 100644
--- a/tests/language/double_to_string_as_exponential2_test.dart
+++ b/tests/language/double_to_string_as_exponential2_test.dart
@@ -6,14 +6,15 @@
 import "package:expect/expect.dart";
 
 main() {
-  Expect.throws(() => (1.0).toStringAsExponential(-1),
+  var v = 1.0;
+  Expect.throws(() => v.toStringAsExponential(-1),
                 (e) => e is RangeError);
-  Expect.throws(() => (1.0).toStringAsExponential(21),
+  Expect.throws(() => v.toStringAsExponential(21),
                 (e) => e is RangeError);
-  Expect.throws(() => (1.0).toStringAsExponential(1.5),
+  Expect.throws(() => v.toStringAsExponential(1.5),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => (1.0).toStringAsExponential("string"),
+  Expect.throws(() => v.toStringAsExponential("string"),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => (1.0).toStringAsExponential("3"),
+  Expect.throws(() => v.toStringAsExponential("3"),
                 (e) => e is ArgumentError || e is TypeError);
 }
diff --git a/tests/language/double_to_string_as_fixed2_test.dart b/tests/language/double_to_string_as_fixed2_test.dart
index 4da08a4..d3f9742 100644
--- a/tests/language/double_to_string_as_fixed2_test.dart
+++ b/tests/language/double_to_string_as_fixed2_test.dart
@@ -6,16 +6,17 @@
 import "package:expect/expect.dart";
 
 main() {
-  Expect.throws(() => 0.0.toStringAsFixed(-1),
+  var v = 0.0;
+  Expect.throws(() => v.toStringAsFixed(-1),
                 (e) => e is RangeError);
-  Expect.throws(() => 0.0.toStringAsFixed(21),
+  Expect.throws(() => v.toStringAsFixed(21),
                 (e) => e is RangeError);
-  Expect.throws(() => 0.0.toStringAsFixed(null),
+  Expect.throws(() => v.toStringAsFixed(null),
                 (e) => e is ArgumentError);
-  Expect.throws(() => 0.0.toStringAsFixed(1.5),
+  Expect.throws(() => v.toStringAsFixed(1.5),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => 0.0.toStringAsFixed("string"),
+  Expect.throws(() => v.toStringAsFixed("string"),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => 0.0.toStringAsFixed("3"),
+  Expect.throws(() => v.toStringAsFixed("3"),
                 (e) => e is ArgumentError || e is TypeError);
 }
diff --git a/tests/language/double_to_string_as_precision2_test.dart b/tests/language/double_to_string_as_precision2_test.dart
index a2f78f0..81520f76 100644
--- a/tests/language/double_to_string_as_precision2_test.dart
+++ b/tests/language/double_to_string_as_precision2_test.dart
@@ -6,17 +6,18 @@
 import "package:expect/expect.dart";
 
 main() {
-  Expect.throws(() => 0.0.toStringAsPrecision(0),
+  var v = 0.0;
+  Expect.throws(() => v.toStringAsPrecision(0),
                 (e) => e is RangeError);
-  Expect.throws(() => 0.0.toStringAsPrecision(22),
+  Expect.throws(() => v.toStringAsPrecision(22),
                 (e) => e is RangeError);
-  Expect.throws(() => 0.0.toStringAsPrecision(null),
+  Expect.throws(() => v.toStringAsPrecision(null),
                 (e) => e is ArgumentError);
-  Expect.throws(() => 0.0.toStringAsPrecision(1.5),
+  Expect.throws(() => v.toStringAsPrecision(1.5),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => 0.0.toStringAsPrecision("string"),
+  Expect.throws(() => v.toStringAsPrecision("string"),
                 (e) => e is ArgumentError || e is TypeError);
-  Expect.throws(() => 0.0.toStringAsPrecision("3"),
+  Expect.throws(() => v.toStringAsPrecision("3"),
                 (e) => e is ArgumentError || e is TypeError);
 
 }
diff --git a/tests/language/duplicate_import_prefix_test.dart b/tests/language/duplicate_import_prefix_test.dart
new file mode 100644
index 0000000..9c28802
--- /dev/null
+++ b/tests/language/duplicate_import_prefix_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+// Importing with a duplicate prefix is allowed.
+
+import "duplicate_import_liba.dart" as a;
+import "duplicate_import_libb.dart" as a;
+
+void main() {}
diff --git a/tests/language/dynamic_field_test.dart b/tests/language/dynamic_field_test.dart
index db77ea3..5328471 100644
--- a/tests/language/dynamic_field_test.dart
+++ b/tests/language/dynamic_field_test.dart
@@ -13,12 +13,12 @@
 
 class C {
   foo() {
-    print(a); /// static type warning
-    return a; /// static type warning
+    print(a); /// 01: static type warning
+    return a; /// 01: continued
   }
   bar() {
-    print(b.a); /// static type warning
-    return b.a; /// static type warning
+    print(b.a); /// 02: static type warning
+    return b.a; /// 02: continued
   }
 }
 
@@ -26,6 +26,6 @@
   var a = new A();
   a.a = 1;
   a.b = a;
-  Expect.equals(1, a.foo());
-  Expect.equals(1, a.bar());
+  Expect.equals(1, a.foo()); /// 01: continued
+  Expect.equals(1, a.bar()); /// 02: continued
 }
diff --git a/tests/language/dynamic_prefix_core_test.dart b/tests/language/dynamic_prefix_core_test.dart
index 4a5362a..464ed2612 100644
--- a/tests/language/dynamic_prefix_core_test.dart
+++ b/tests/language/dynamic_prefix_core_test.dart
@@ -11,7 +11,7 @@
   // Should still be available because it is not a member of dart:core.
   Expect.isTrue(dynamic is mycore.Type);
 
-  Expect.throws(() => mycore.dynamic is mycore.Type,
-                (e) => e is mycore.NoSuchMethodError,
-                'dynamic is not a member of dart:core');
+  Expect.throws(() => mycore.dynamic is mycore.Type,     /// 01: static type warning
+                (e) => e is mycore.NoSuchMethodError,    /// 01: continued
+                'dynamic is not a member of dart:core'); /// 01: continued
 }
diff --git a/tests/language/generic_closure_test.dart b/tests/language/generic_closure_test.dart
new file mode 100644
index 0000000..a2313e6
--- /dev/null
+++ b/tests/language/generic_closure_test.dart
@@ -0,0 +1,62 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check that generic closures are properly instantiated.
+
+import 'package:expect/expect.dart';
+
+typedef T F<T>(T x);
+typedef R G<T, R>(T x);
+
+class C<T> {
+  get f => (T x) => 2*x;
+  T g(T x) => 3*x;
+}
+
+main() {
+  var c = new C<int>();
+  var f = c.f;
+  var g = c.g;
+  Expect.equals(42, f(21));
+  Expect.equals(42, g(14));
+  Expect.isTrue(f is Function);
+  Expect.isTrue(g is Function);
+  Expect.isTrue(f is F);
+  Expect.isTrue(g is F);
+  Expect.isTrue(f is F<int>);
+  Expect.isTrue(g is F<int>);
+  Expect.isTrue(f is! F<bool>);
+  Expect.isTrue(g is! F<bool>);
+  Expect.isTrue(f is G<int, int>);
+  Expect.isTrue(g is G<int, int>);
+  Expect.isTrue(f is G<int, bool>);
+  Expect.isTrue(g is! G<int, bool>);
+  Expect.equals("(int) => dynamic", f.runtimeType.toString());
+  Expect.equals("(int) => int", g.runtimeType.toString());
+
+  c = new C<bool>();
+  f = c.f;
+  g = c.g;
+  Expect.isTrue(f is F);
+  Expect.isTrue(g is F);
+  Expect.isTrue(f is! F<int>);
+  Expect.isTrue(g is! F<int>);
+  Expect.isTrue(f is F<bool>);
+  Expect.isTrue(g is F<bool>);
+  Expect.equals("(bool) => dynamic", f.runtimeType.toString());
+  Expect.equals("(bool) => bool", g.runtimeType.toString());
+
+  c = new C();
+  f = c.f;
+  g = c.g;
+  Expect.isTrue(f is F);
+  Expect.isTrue(g is F);
+  Expect.isTrue(f is F<int>);
+  Expect.isTrue(g is F<int>);
+  Expect.isTrue(f is F<bool>);
+  Expect.isTrue(g is F<bool>);
+  Expect.equals("(dynamic) => dynamic", f.runtimeType.toString());
+  Expect.equals("(dynamic) => dynamic", g.runtimeType.toString());
+}
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index 70b57c5..ca70884e 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -20,6 +20,13 @@
 duplicate_export_negative_test: Fail # Issue 6134
 mixin_forwarding_constructor2_test: Fail # Issue 13641
 
+[ $compiler == none || $compiler == dartanalyzer || $compiler == dart2analyzer ]
+# The vm and analyzer do not support deferred loading.
+deferred_no_prefix_test/01: Fail
+deferred_duplicate_prefix1_test/01: Fail
+deferred_duplicate_prefix2_test/01: Fail
+deferred_duplicate_prefix3_test/01: Fail
+
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16137
@@ -51,9 +58,10 @@
 
 [ $runtime == vm || (($runtime == drt || $runtime == dartium) && $compiler == none) ]
 call_test: Fail # Issue 12602
-dynamic_prefix_core_test: Fail # Issue 12478
+dynamic_prefix_core_test/01: Fail # Issue 12478
 
 [ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium) ]
+dynamic_prefix_core_test/none: Fail # Issue 12478
 export_ambiguous_main_negative_test: Fail # Issue 14763
 
 [ $compiler == none && $runtime == drt ]
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index b28f529..1c18d7b 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -10,7 +10,9 @@
 built_in_identifier_prefix_test: CompileTimeError # Issue 12694
 
 # Issue 15315
-class_literal_test: fail
+class_literal_test/01: CompileTimeError
+class_literal_test/03: CompileTimeError
+class_literal_test/07: CompileTimeError
 constructor_call_as_function_test/01: fail
 call_type_literal_test/01: fail
 
@@ -41,7 +43,6 @@
 metadata_test: fail
 
 # test issue 11575, classes with abstrac members are not marked as abstract
-abstract_factory_constructor_test/none: fail # Issue 11575
 get_set_syntax_test/none: fail # Issue 11575
 implicit_this_test/none: fail # Issue 11575
 interface_test/none: fail # Issue 11575
@@ -174,9 +175,6 @@
 proxy_test/05: StaticWarning # Issue 15467
 proxy_test/06: StaticWarning # Issue 15467
 
-# test issue 15714
-typevariable_substitution2_test/01: StaticWarning # Issue 15714
-
 # analyzer does not handle @proxy and noSuchMethod correctly
 override_inheritance_no_such_method_test/03: StaticWarning # Issue 16132
 override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132
@@ -191,7 +189,6 @@
 override_inheritance_generic_test/03: StaticWarning # Issue 16134
 
 # missing warning for override
-override_inheritance_field_test/10: MissingStaticWarning # Issue 16135
 override_inheritance_generic_test/04: MissingStaticWarning # Issue 16135
 override_inheritance_generic_test/06: MissingStaticWarning # Issue 16135
 override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135
@@ -206,27 +203,19 @@
 override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
 override_inheritance_generic_test/09: MissingStaticWarning, Pass # Issue 16498
 
+# missing warning for assignment to method
+assign_top_method_test/01: MissingStaticWarning # Issue 16672
 
-abstract_exact_selector_test: StaticWarning
-abstract_getter_test: StaticWarning
+# missing warning for assignment to type variable
+checked_setter3_test/01: MissingStaticWarning # Issue 16673
+checked_setter3_test/02: MissingStaticWarning # Issue 16673
+
 abstract_object_method_test: StaticWarning
-abstract_runtime_error_test: StaticWarning
 application_negative_test: CompileTimeError
 bad_constructor_test/05: CompileTimeError
 bad_initializer1_negative_test: CompileTimeError
 bad_named_constructor_negative_test: CompileTimeError
-bad_named_parameters2_test: StaticWarning
-bad_named_parameters_test: StaticWarning
-bit_operations_test: StaticWarning
 body_less_constructor_wrong_arg_negative_test: CompileTimeError
-call_constructor_on_unresolvable_class_test/04: StaticWarning
-call_constructor_on_unresolvable_class_test/05: StaticWarning
-call_constructor_on_unresolvable_class_test/06: StaticWarning
-call_nonexistent_constructor_test: StaticWarning
-checked_null_test: StaticWarning
-checked_setter2_test: StaticWarning
-checked_setter_test: StaticWarning
-closure_type_test: StaticWarning
 compile_time_constant_checked2_test/02: MissingCompileTimeError
 compile_time_constant_checked2_test/03: MissingCompileTimeError
 compile_time_constant_checked2_test/04: MissingCompileTimeError
@@ -236,27 +225,13 @@
 compile_time_constant_checked3_test/04: MissingCompileTimeError
 compile_time_constant_checked3_test/06: MissingCompileTimeError
 compile_time_constant_checked_test/02: MissingCompileTimeError
-compile_time_constant_k_test: StaticWarning
-compile_time_constant_o_test: StaticWarning
 const_counter_negative_test: CompileTimeError
-const_objects_are_immutable_test: StaticWarning
 const_optional_args_negative_test: CompileTimeError
-constructor_named_arguments_test/01: StaticWarning
 constructor_redirect1_negative_test: CompileTimeError
 constructor_redirect2_negative_test: CompileTimeError
 constructor_setter_negative_test: CompileTimeError
-constructor_test: StaticWarning
-core_type_check_test: StaticWarning
-crash_6725_test: StaticWarning
-default_factory_library_test: StaticWarning
-default_factory_test: StaticWarning
-double_to_string_as_exponential2_test: StaticWarning
-double_to_string_as_fixed2_test: StaticWarning
-double_to_string_as_precision2_test: StaticWarning
 duplicate_export_negative_test: CompileTimeError
 duplicate_interface_negative_test: CompileTimeError
-dynamic_field_test: StaticWarning
-dynamic_prefix_core_test: StaticWarning
 empty_block_case_test: StaticWarning
 error_stacktrace_test: StaticWarning
 export_ambiguous_main_negative_test: CompileTimeError
@@ -357,14 +332,11 @@
 method_override_test: StaticWarning
 mixin_illegal_static_access_test: StaticWarning
 mixin_illegal_syntax_test/13: CompileTimeError
-mixin_typedef_constructor_test: StaticWarning
-mixin_type_parameter2_test: StaticWarning
 mixin_type_parameters_mixin_extends_test: StaticWarning
 mixin_type_parameters_mixin_test: StaticWarning
 mixin_type_parameters_super_extends_test: StaticWarning
 mixin_type_parameters_super_test: StaticWarning
 mixin_with_two_implicit_constructors_test: StaticWarning
-mixin_bound_test: StaticWarning
 mixin_invalid_bound_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
 mixin_invalid_bound2_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
 named_constructor_test/01: StaticWarning
@@ -498,4 +470,3 @@
 vm/type_cast_vm_test: StaticWarning
 vm/type_vm_test: StaticWarning
 void_type_test: StaticWarning
-
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 3f0c39d..cf3aeb9 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -10,7 +10,9 @@
 built_in_identifier_prefix_test: CompileTimeError # Issue 12694
 
 # Issue 15315
-class_literal_test: fail
+class_literal_test/01: CompileTimeError
+class_literal_test/03: CompileTimeError
+class_literal_test/07: CompileTimeError
 constructor_call_as_function_test/01: fail
 call_type_literal_test/01: fail
 
@@ -47,7 +49,6 @@
 metadata_test: fail
 
 # test issue 11575, classes with abstrac members are not marked as abstract
-abstract_factory_constructor_test/none: fail # Issue 11575
 get_set_syntax_test/none: fail # Issue 11575
 implicit_this_test/none: fail # Issue 11575
 interface_test/none: fail # Issue 11575
@@ -212,27 +213,19 @@
 override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
 override_inheritance_generic_test/09: MissingStaticWarning, Pass # Issue 16498
 
+# missing warning for assignment to method
+assign_top_method_test/01: MissingStaticWarning # Issue 16672
 
-abstract_exact_selector_test: StaticWarning
-abstract_getter_test: StaticWarning
+# missing warning for assignment to type variable
+checked_setter3_test/01: MissingStaticWarning # Issue 16673
+checked_setter3_test/02: MissingStaticWarning # Issue 16673
+
 abstract_object_method_test: StaticWarning
-abstract_runtime_error_test: StaticWarning
 application_negative_test: CompileTimeError
 bad_constructor_test/05: CompileTimeError
 bad_initializer1_negative_test: CompileTimeError
 bad_named_constructor_negative_test: CompileTimeError
-bad_named_parameters2_test: StaticWarning
-bad_named_parameters_test: StaticWarning
-bit_operations_test: StaticWarning
 body_less_constructor_wrong_arg_negative_test: CompileTimeError
-call_constructor_on_unresolvable_class_test/04: StaticWarning
-call_constructor_on_unresolvable_class_test/05: StaticWarning
-call_constructor_on_unresolvable_class_test/06: StaticWarning
-call_nonexistent_constructor_test: StaticWarning
-checked_null_test: StaticWarning
-checked_setter2_test: StaticWarning
-checked_setter_test: StaticWarning
-closure_type_test: StaticWarning
 compile_time_constant_checked2_test/02: MissingCompileTimeError
 compile_time_constant_checked2_test/03: MissingCompileTimeError
 compile_time_constant_checked2_test/04: MissingCompileTimeError
@@ -242,27 +235,13 @@
 compile_time_constant_checked3_test/04: MissingCompileTimeError
 compile_time_constant_checked3_test/06: MissingCompileTimeError
 compile_time_constant_checked_test/02: MissingCompileTimeError
-compile_time_constant_k_test: StaticWarning
-compile_time_constant_o_test: StaticWarning
 const_counter_negative_test: CompileTimeError
-const_objects_are_immutable_test: StaticWarning
 const_optional_args_negative_test: CompileTimeError
-constructor_named_arguments_test/01: StaticWarning
 constructor_redirect1_negative_test: CompileTimeError
 constructor_redirect2_negative_test: CompileTimeError
 constructor_setter_negative_test: CompileTimeError
-constructor_test: StaticWarning
-core_type_check_test: StaticWarning
-crash_6725_test: StaticWarning
-default_factory_library_test: StaticWarning
-default_factory_test: StaticWarning
-double_to_string_as_exponential2_test: StaticWarning
-double_to_string_as_fixed2_test: StaticWarning
-double_to_string_as_precision2_test: StaticWarning
 duplicate_export_negative_test: CompileTimeError
 duplicate_interface_negative_test: CompileTimeError
-dynamic_field_test: StaticWarning
-dynamic_prefix_core_test: StaticWarning
 empty_block_case_test: StaticWarning
 error_stacktrace_test: StaticWarning
 export_ambiguous_main_negative_test: CompileTimeError
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 38b41b7..48b3140 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -129,6 +129,7 @@
 modulo_test: RuntimeError # Issue 15246
 truncdiv_test: RuntimeError # Issue 15246
 invocation_mirror2_test: RuntimeError # Issue 6490 (wrong retval).
+generic_closure_test: RuntimeError # Issue 12605
 
 # Compilation errors.
 const_var_test: CompileTimeError # Issue 12793
@@ -211,7 +212,8 @@
 prefix22_test: Fail # Issue 13081
 
 # Calling unresolved class constructor:
-call_nonexistent_constructor_test: Fail # Issue 13082
+call_nonexistent_constructor_test/01: Fail # Issue 13082
+call_nonexistent_constructor_test/02: Fail # Issue 13082
 
 bad_override_test/01: Fail # Issue 11496
 bad_override_test/02: Fail # Issue 11496
diff --git a/tests/language/vm/regress_16873_test.dart b/tests/language/vm/regress_16873_test.dart
new file mode 100644
index 0000000..4080f5c
--- /dev/null
+++ b/tests/language/vm/regress_16873_test.dart
@@ -0,0 +1,21 @@
+// 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=--new_gen_heap_size=1 --no_inline_alloc
+
+// Regression test for slow-path allocation in the allocation stub.
+
+library map_test;
+import 'dart:collection';
+
+void testCollection(var collection, n) {
+  for (int i = 0; i < n; i++) {
+    if (i % 1000 == 0) print(i);
+    collection.add(i);
+  }
+}
+
+main() {
+  const int N = 100000;
+  testCollection(new LinkedHashSet(), N);
+}
diff --git a/tests/language/vm/string_polymorphic_test.dart b/tests/language/vm/string_polymorphic_test.dart
new file mode 100644
index 0000000..e7c6410
--- /dev/null
+++ b/tests/language/vm/string_polymorphic_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Tests that the VM does not crash on weird corner cases of class Math.
+// VMOptions=--optimization_counter_threshold=10
+
+import 'package:expect/expect.dart';
+
+test1(String a, String b) {
+  return a == b;
+}
+
+var LEN = 500;
+
+var ITER = 100000 / LEN;
+
+measure(fn, a, b) {
+  for (var i = 0; i < ITER; i++) {
+    Expect.equals(true, fn(a, b));
+  }
+}
+
+main() {
+  var n = LEN;
+  StringBuffer s = new StringBuffer();
+  for (var i=0; i < n; ++i) s.write("A");
+  String t = s.toString();
+  String u = s.toString();
+  String v = s.toString() + "\u1234";
+  String w = s.toString() + "\u1234";
+  for (var i=0; i<10; i++) measure(test1, t, u);
+  for (var i=0; i<10; i++) measure(test1, v, w);
+}
diff --git a/tests/language/vm/typed_data_polymorphic_view_test.dart b/tests/language/vm/typed_data_polymorphic_view_test.dart
new file mode 100644
index 0000000..94952e2
--- /dev/null
+++ b/tests/language/vm/typed_data_polymorphic_view_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Tests that the VM does not crash on weird corner cases of class Math.
+// VMOptions=--optimization_counter_threshold=10
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+final V = 5;
+
+void runShort(view) {
+  for (int i = 0; i < view.length; i++) {
+    view[i] = V;
+  }
+}
+
+void verifyShort(view) {
+  var sum = 0;
+  for (int i = 0; i < view.length; i++) {
+    sum += view[i];
+  }
+  // 1285 * view.length.
+  Expect.equals(657920, sum);
+}
+
+void testShort() {
+  var int8 = new Uint8List(1024);
+  var int16 = new Uint16List(512);
+
+  var view = new Uint8List.view(int8.buffer);
+  view[0] = V;
+
+  view = new Uint8List.view(int16.buffer);
+  for (int i = 0; i < 1000; i++) {
+    runShort(view);
+  }
+
+  Expect.equals(1285, int16[0]);
+  verifyShort(int16);
+}
+
+
+void runXor(view) {
+  var mask = new Int32x4(0x1, 0x1, 0x1, 0x1);
+  for (var i = 0; i < view.length; i++) {
+    view[i] ^= mask;
+  }
+}
+
+void verifyXor(view) {
+  var sum = 0;
+  for (var i = 0; i < view.length; i++) {
+    sum += view[i];
+  }
+  Expect.equals(256, sum);
+}
+
+void testXor() {
+  var int8 = new Uint8List(1024);
+  var int32x4 = new Int32x4List.view(int8.buffer);
+  Expect.equals(64, int32x4.length);
+  for (var i = 0; i < 1001; i++) {
+    runXor(int32x4);
+  }
+  Expect.equals(1, int8[0]);
+  Expect.equals(0, int8[1]);
+  Expect.equals(0, int8[2]);
+  Expect.equals(0, int8[3]);
+  verifyXor(int8);
+}
+
+void main() {
+  testXor();
+  testShort();
+}
diff --git a/tests/lib/async/deferred/deferred_api_test.dart b/tests/lib/async/deferred/deferred_api_test.dart
index 7c6d390..f138935 100644
--- a/tests/lib/async/deferred/deferred_api_test.dart
+++ b/tests/lib/async/deferred/deferred_api_test.dart
@@ -12,7 +12,7 @@
 import 'dart:async';
 
 @lazy
-import 'deferred_api_library.dart';
+import 'deferred_api_library.dart' as lib;
 
 const lazy = const DeferredLibrary('deferred_api_library');
 
@@ -23,14 +23,14 @@
   lazy.load().then((bool didLoad) {
     Expect.isTrue(didLoad);
     Expect.equals(1, ++counter);
-    Expect.equals(42, foo('b'));
+    Expect.equals(42, lib.foo('b'));
     print('lazy was loaded');
   });
   Expect.equals(0, counter);
   lazy.load().then((bool didLoad) {
     Expect.isFalse(didLoad);
     Expect.equals(2, ++counter);
-    Expect.equals(42, foo('b'));
+    Expect.equals(42, lib.foo('b'));
     print('lazy was loaded');
     print('unittest-suite-success');
   });
diff --git a/tests/lib/async/deferred/deferred_fail_to_load_test.dart b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
new file mode 100644
index 0000000..6ac1406
--- /dev/null
+++ b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
@@ -0,0 +1,24 @@
+import 'dart:isolate';
+import 'dart:async';
+import 'dart:html';
+import '../../../../pkg/unittest/lib/unittest.dart';
+
+@a import 'deferred_in_isolate_lib.dart' as lib1;
+@b import 'deferred_api_library.dart' as lib2;
+
+const a = const DeferredLibrary("lib1");
+const b = const DeferredLibrary("NonExistingFile", uri: "wrong/wrong.js");
+
+main() {
+  test("Deferred loading failing to load", () {
+    a.load().then(expectAsync((_) {
+      expect(lib1.f(), equals("hi"));
+    }));
+    b.load().then((_) {
+      expect(false, true);
+      lib2.foo("");
+    }).catchError(expectAsync((_) {
+      expect(true, true);
+      }), test: (e) => e is DeferredLoadException);
+  });
+}
diff --git a/tests/lib/async/deferred/deferred_in_isolate_lib.dart b/tests/lib/async/deferred/deferred_in_isolate_lib.dart
new file mode 100644
index 0000000..64b38db
--- /dev/null
+++ b/tests/lib/async/deferred/deferred_in_isolate_lib.dart
@@ -0,0 +1 @@
+String f() => "hi";
diff --git a/tests/lib/async/deferred/deferred_in_isolate_test.dart b/tests/lib/async/deferred/deferred_in_isolate_test.dart
new file mode 100644
index 0000000..cfeaabe
--- /dev/null
+++ b/tests/lib/async/deferred/deferred_in_isolate_test.dart
@@ -0,0 +1,34 @@
+import 'dart:isolate';
+import 'dart:async';
+import '../../../../pkg/unittest/lib/unittest.dart';
+
+@a import 'deferred_in_isolate_lib.dart' as lib1;
+@b import 'deferred_api_library.dart' as lib2;
+
+const a = const DeferredLibrary("lib1");
+const b = const DeferredLibrary("NonExistingFile", uri: "wrong/");
+
+loadDeferred(ports) {
+  a.load().then((_) {
+    ports[0].send(lib1.f());
+  });
+  b.load().then((b) {
+    ports[1].send("No error");
+    lib2.foo(20);
+  }).catchError((_) {
+    ports[1].send("Error caught");
+  }, test: (e) => e is DeferredLoadException);
+}
+
+main() {
+  test("Deferred loading in isolate", () {
+    List<ReceivePort> ports = new List.generate(2, (_) => new ReceivePort());
+    ports[0].first.then(expectAsync((msg) {
+       expect(msg, equals("hi"));
+    }));
+    ports[1].first.then(expectAsync((msg) {
+      expect(msg, equals("Error caught"));
+    }));
+    Isolate.spawn(loadDeferred, ports.map((p) => p.sendPort).toList());
+  });
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index bfa79c3..a09fb5c 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -17,6 +17,7 @@
 
 [ $csp ]
 mirrors/delegate_test: RuntimeError # Issue 13864
+async/deferred/deferred_in_isolate_test: RuntimeError #  Issue 16898
 
 [ $compiler == dart2js && $checked && $runtime == drt && $nocsp ]
 async/stream_transform_test: RuntimeError # Issue 16719
@@ -79,7 +80,6 @@
 mirrors/mixin_test: RuntimeError # Issue 12464
 mirrors/mixin_application_test/none: RuntimeError # Issue 12464
 mirrors/parameter_test/none: RuntimeError # Issue 6490
-mirrors/parameter_metadata_test: RuntimeError # Issue 10905
 mirrors/private_symbol_test: CompileTimeError # Issue 13597
 mirrors/proxy_type_test: RuntimeError # Issue 13842
 mirrors/redirecting_factory_test/none: RuntimeError # Issue 6490
@@ -88,7 +88,7 @@
 mirrors/relation_subtype_test: RuntimeError # Issue 6490
 mirrors/relation_subclass_test: RuntimeError # Issue 6490
 mirrors/repeated_private_anon_mixin_app_test: RuntimeError # Issue 14670
-mirrors/symbol_validation_test: RuntimeError # Issue 13597
+mirrors/symbol_validation_test/none: RuntimeError # Issue 13597
 mirrors/static_members_test: RuntimeError # Issue 14633, Issue 12164
 mirrors/synthetic_accessor_properties_test: RuntimeError # Issue 14633
 mirrors/toplevel_members_test: RuntimeError # Issue 14633, Issue 12164
@@ -158,13 +158,12 @@
 async/zone_bind_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/future_timeout_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/stream_timeout_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/stream_asyncexpand_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/stream_asyncmap_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
 
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Pass, Slow # Issue 12029.
 
-[ $compiler == dart2js && $checked && $runtime == d8 ]
-async/stream_transform_test: Fail # https://code.google.com/p/v8/issues/detail?id=3084
-
 [ $compiler == dart2js ]
 convert/chunked_conversion_utf88_test: Slow, Pass
 convert/utf85_test: Slow, Pass
@@ -201,7 +200,7 @@
 typed_data/*: Fail # Issue 11971
 convert/chunked_conversion_utf88_test: Pass, Slow, Timeout  # Issue 12029
 convert/streamed_conversion_json_utf8_decode_test: Pass, Timeout # Issue 12029
-async/deferred/deferred_api_test: Pass, Timeout # http://dartbug.com/12635
+async/deferred/*: Pass, Fail, Timeout # http://dartbug.com/12635
 convert/streamed_conversion_utf8_decode_test: Pass, Timeout # http://dartbug.com/12768
 convert/utf85_test: Skip # Issue 12029.
 convert/json_util_test: Fail # Issue 16109
@@ -271,6 +270,13 @@
 # Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
 async/timer_isolate_test: Fail
 
+[ $compiler == dart2dart || ($compiler == none && ($runtime == drt || $runtime == dartium || $runtime == vm)) ]
+# Deferred loading is not implemented in the VM so the error-handling will never be triggered.
+async/deferred/deferred_fail_to_load_test: Fail
+# Deferred loading is not implemented in the VM so the error-handling will never be triggered.
+# Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
+async/deferred/deferred_in_isolate_test: Fail
+
 [ $compiler == dart2js ]
 async/schedule_microtask_test: Fail # Issue 9002
 
diff --git a/tests/lib/math/rectangle_test.dart b/tests/lib/math/rectangle_test.dart
index 96a0ba1..45052f6 100644
--- a/tests/lib/math/rectangle_test.dart
+++ b/tests/lib/math/rectangle_test.dart
@@ -160,4 +160,22 @@
     expect(r1.width, 1.0);
     expect(r2.width, 2.0);
   });
+
+  test('negative lengths', () {
+    // Constructor allows negative lengths, but clamps them to zero.
+    expect(new Rectangle(4, 4, -2, -2), new Rectangle(4, 4, 0, 0));
+    expect(new MutableRectangle(4, 4, -2, -2), new Rectangle(4, 4, 0, 0));
+
+    // Setters clamp negative lengths to zero.
+    var r = new MutableRectangle(0, 0, 1, 1);
+    r.width = -1;
+    r.height = -1;
+    expect(r, new Rectangle(0, 0, 0, 0));
+
+    // Test that doubles are clamped to double zero.
+    r = new Rectangle(1.5, 1.5, -2.5, -2.5);
+    expect(identical(r.width, 0.0), isTrue);
+    expect(identical(r.height, 0.0), isTrue);
+  });
 }
+
diff --git a/tests/lib/mirrors/parameter_annotation_mirror_test.dart b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
index c0a625a..1b2a451 100644
--- a/tests/lib/mirrors/parameter_annotation_mirror_test.dart
+++ b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
@@ -20,6 +20,8 @@
      {@ParameterAnnotation("hval") p}) {}
   f5(@ParameterAnnotation("fisk") a,
      [@ParameterAnnotation("hval") p]) {}
+  f6({@ParameterAnnotation("fisk") z,
+      @ParameterAnnotation("hval") p}) {}
 }
 
 expectAnnotations(Type type, Symbol method, int parameterIndex,
@@ -45,4 +47,6 @@
   expectAnnotations(Foo, #f4, 1, ["hval"]);
   expectAnnotations(Foo, #f5, 0, ["fisk"]);
   expectAnnotations(Foo, #f5, 1, ["hval"]);
+  expectAnnotations(Foo, #f6, 0, ["fisk"]);
+  expectAnnotations(Foo, #f6, 1, ["hval"]);
 }
diff --git a/tests/lib/mirrors/symbol_validation_test.dart b/tests/lib/mirrors/symbol_validation_test.dart
index 0fe3c45..b0f5ac5 100644
--- a/tests/lib/mirrors/symbol_validation_test.dart
+++ b/tests/lib/mirrors/symbol_validation_test.dart
@@ -11,6 +11,7 @@
   Expect.equals(string,
                 MirrorSystem.getName(new Symbol(string)),
                 'Valid symbol "$string" should be invertable');
+  return;  /// 01: ok
   Expect.equals(string,
                 MirrorSystem.getName(MirrorSystem.getSymbol(string)),
                 'Valid symbol "$string" should be invertable');
@@ -20,20 +21,105 @@
   Expect.throws(() => new Symbol(string),
                 (e) => e is ArgumentError,
                 'Invalid symbol "$string" should be rejected');
+  return;  /// 01: continued
   Expect.throws(() => MirrorSystem.getSymbol(string),
-                (e) => e is ArgumentError,
+               (e) => e is ArgumentError,
                 'Invalid symbol "$string" should be rejected');
 }
 
 main() {
-  ['%', '&', '*', '+', '-', '/', '<', '<<', '<=', '==', '>',
-   '>=', '>>', '[]', '[]=', '^', 'unary-', '|', '~', '~/']
-      .forEach(validSymbol);
+  // Operators that can be declared as class member operators.
+  // These are all valid as symbols.
+  var operators = [
+    '%', '&', '*', '+', '-', '/', '<', '<<', '<=', '==', '>',
+    '>=', '>>', '[]', '[]=', '^', 'unary-', '|', '~', '~/'
+  ];
+  operators.expand((op) => [op, "x.$op"]).forEach(validSymbol);
+  operators.expand((op) => [".$op", "$op.x", "x$op", "_x.$op"])
+           .forEach(invalidSymbol);
+  operators.expand((op) => operators.contains("$op=") ? [] : ["x.$op=", "$op="])
+           .forEach(invalidSymbol);
 
-  ['foo', '_bar', 'baz.quz', 'fisk1', 'hest2fisk', 'a.b.c.d.e',
-   '\$', 'foo\$', 'bar\$bar']
-      .forEach(validSymbol);
+  var simpleSymbols = [
+    'foo', 'bar_', 'baz.quz', 'fisk1', 'hest2fisk', 'a.b.c.d.e',
+    r'$', r'foo$', r'bar$bar', r'$.$', r'x6$_', r'$6_', r'x.$$6_',
+    'x_', 'x_.x_',
+  ];
+  simpleSymbols.expand((s) => [s, "s="]).forEach(validSymbol);
 
-  ['6', '0foo', ',', 'S with M', '_invalid&private']
-      .forEach(invalidSymbol);
+  var nonSymbols = [
+    // Non-identifiers.
+    '6', '0foo', ',', 'S with M', '_invalid&private', "#foo", " foo", "foo ",
+    // Operator variants.
+    '+=', '()', 'operator+', 'unary+', '>>>', "&&", "||", "!", "@", "#", "[",
+    // Private symbols.
+    '_', '_x', 'x._y', 'x._',
+    // Empty parts of "qualified" symbols.
+    '.', 'x.', '.x', 'x..y'
+  ];
+  nonSymbols.forEach(invalidSymbol);
+
+  // Reserved words are not valid identifiers and therefore not valid symbols.
+  var reservedWords = [
+    "assert",
+    "break",
+    "case",
+    "catch",
+    "class",
+    "const",
+    "continue",
+    "default",
+    "do",
+    "else",
+    "enum",
+    "extends",
+    "false",
+    "final",
+    "finally",
+    "for",
+    "if",
+    "in",
+    "is",
+    "new",
+    "null",
+    "rethrow",
+    "return",
+    "super",
+    "switch",
+    "this",
+    "throw",
+    "true",
+    "try",
+    "var",
+    "void",
+    "while",
+    "with"
+  ];
+  reservedWords.expand((w) => [w, "$w=", "x.$w" , "$w.x", "x.$w.x"])
+               .forEach(invalidSymbol);
+  reservedWords.expand((w) => ["${w}_", "${w}\$", "${w}q"])
+               .forEach(validSymbol);
+
+  // Built-in identifiers are valid identifiers that are restricted from being
+  // used in some cases, but they are all valid symbols.
+  var builtInIdentifiers = [
+    "abstract",
+    "as",
+    "dynamic",
+    "export",
+    "external",
+    "factory",
+    "get",
+    "implements",
+    "import",
+    "library",
+    "operator",
+    "part",
+    "set",
+    "static",
+    "typedef"
+  ];
+  builtInIdentifiers.expand((w) => [w, "$w=", "x.$w" , "$w.x", "x.$w.x",
+                                    "$w=", "x.$w="])
+                    .forEach(validSymbol);
 }
diff --git a/tests/lib/typed_data/float64x2_functional_test.dart b/tests/lib/typed_data/float64x2_functional_test.dart
index 642b42b..2f06ccf 100644
--- a/tests/lib/typed_data/float64x2_functional_test.dart
+++ b/tests/lib/typed_data/float64x2_functional_test.dart
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10
 
-// Library tag to be able to run in html test framework.
-library float32x4_test;
+library float64x2_functional_test;
 
 import "package:expect/expect.dart";
 import 'dart:typed_data';
@@ -70,10 +69,10 @@
 }
 
 testSub() {
-  var m = new Float64x2(1.0, -2.0);
+  var m = new Float64x2(1.5, -2.0);
   var n = new Float64x2(1.0, 2.0);
   var o = m - n;
-  Expect.equals(0.0, o.x);
+  Expect.equals(0.5, o.x);
   Expect.equals(-4.0, o.y);
 }
 
@@ -111,11 +110,11 @@
 
 testClamp() {
   var m = new Float64x2(1.0, -2.0);
-  var lo = new Float64x2(0.0, 0.0);
+  var lo = new Float64x2(0.0, 0.5);
   var hi = new Float64x2(2.0, 2.0);
   m = m.clamp(lo, hi);
   Expect.equals(1.0, m.x);
-  Expect.equals(0.0, m.y);
+  Expect.equals(0.5, m.y);
 }
 
 testSignMask() {
@@ -138,10 +137,10 @@
 }
 
 testMax() {
-  var m = new Float64x2(0.0, -99.0);
+  var m = new Float64x2(0.5, -99.0);
   var n = new Float64x2(-1.0, -1.0);
   var o = m.max(n);
-  Expect.equals(0.0, o.x);
+  Expect.equals(0.5, o.x);
   Expect.equals(-1.0, o.y);
 }
 
diff --git a/tests/lib/typed_data/float64x2_typed_list_test.dart b/tests/lib/typed_data/float64x2_typed_list_test.dart
new file mode 100644
index 0000000..b00cfd4
--- /dev/null
+++ b/tests/lib/typed_data/float64x2_typed_list_test.dart
@@ -0,0 +1,33 @@
+// 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=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10
+
+library float64x2_typed_list_test;
+
+import 'dart:typed_data';
+
+void test(Float64x2List l) {
+  var a = l[0];
+  var b = l[1];
+  l[0] = b;
+  l[1] = a;
+}
+
+bool compare(a, b) {
+  return (a.x == b.x) && (a.y == b.y);
+}
+
+main() {
+  var l = new Float64x2List(2);
+  var a = new Float64x2(1.0, 2.0);
+  var b = new Float64x2(3.0, 4.0);
+  l[0] = a;
+  l[1] = b;
+  for (var i = 0; i < 41; i++) {
+    test(l);
+  }
+  if (!compare(l[0], b) || !compare(l[1], a)) {
+    throw 123;
+  }
+}
diff --git a/tests/standalone/io/http_client_exception_test.dart b/tests/standalone/io/http_client_exception_test.dart
index e3e5957..4a5ab98 100644
--- a/tests/standalone/io/http_client_exception_test.dart
+++ b/tests/standalone/io/http_client_exception_test.dart
@@ -20,6 +20,9 @@
       () => client.getUrl(Uri.parse('http://::1')),
       (e) => e.toString().contains("No host specified"));
   Expect.throws(
+      () => client.getUrl(Uri.parse('http://user@:1')),
+      (e) => e.toString().contains("No host specified"));
+  Expect.throws(
       () => client.getUrl(Uri.parse('http:///')),
       (e) => e.toString().contains("No host specified"));
   Expect.throws(
diff --git a/tests/standalone/io/http_no_reason_phrase_test.dart b/tests/standalone/io/http_no_reason_phrase_test.dart
index 9db6a64..9312cd4 100644
--- a/tests/standalone/io/http_no_reason_phrase_test.dart
+++ b/tests/standalone/io/http_no_reason_phrase_test.dart
@@ -17,6 +17,7 @@
   var client = new HttpClient();
   ServerSocket.bind("127.0.0.1", 0).then((server) {
      server.listen((client) {
+        client.listen(null);
         if (includeSpace) {
           client.write("HTTP/1.1 $statusCode \r\n\r\n");
         } else {
@@ -29,6 +30,7 @@
         .then((response) {
           Expect.equals(statusCode, response.statusCode);
           Expect.equals("", response.reasonPhrase);
+          return response.drain();
         })
         .whenComplete(() => server.close());
   });
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index 2c5e508..5321af0 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -70,7 +70,7 @@
       int unparsedBytesReceived;
       bool upgraded;
 
-      controller.stream.pipe(httpParser);
+      httpParser.listenToStream(controller.stream);
       var subscription = httpParser.listen((incoming) {
         method = incoming.method;
         uri = incoming.uri;
@@ -158,7 +158,7 @@
       httpParser = new _HttpParser.requestParser();
       controller = new StreamController(sync: true);
       var port = new ReceivePort();
-      controller.stream.pipe(httpParser);
+      httpParser.listenToStream(controller.stream);
       var subscription = httpParser.listen((incoming) {
         Expect.fail("Expected request");
       });
@@ -221,7 +221,7 @@
       httpParser = new _HttpParser.responseParser();
       controller = new StreamController(sync: true);
       var port = new ReceivePort();
-      controller.stream.pipe(httpParser);
+      httpParser.listenToStream(controller.stream);
       int doneCallCount = 0;
       // Called when done parsing entire message and done parsing body.
       // Only executed when both are done.
@@ -307,7 +307,7 @@
       if (chunkSize == -1) chunkSize = requestData.length;
 
       var port = new ReceivePort();
-      controller.stream.pipe(httpParser);
+      httpParser.listenToStream(controller.stream);
       var subscription = httpParser.listen((incoming) {
         incoming.listen(
           (data) {},
diff --git a/tests/standalone/io/http_response_deadline_test.dart b/tests/standalone/io/http_response_deadline_test.dart
index 5f53793..e10913a 100644
--- a/tests/standalone/io/http_response_deadline_test.dart
+++ b/tests/standalone/io/http_response_deadline_test.dart
@@ -63,6 +63,7 @@
         new Timer(const Duration(milliseconds: 100), () {
           socket.write('stuff');
           socket.close();
+          socket.listen(null);
         });
       });
     });
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index b406f7f..4eb8df5 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -101,6 +101,7 @@
         socket.write('GET / HTTP/1.1\r\nContent-Length: 100\r\n\r\n');
         socket.write('some body');
         socket.close();
+        socket.listen(null);
       });
     });
   }, onError: (e) {
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index ddf5611..bc537f5 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -64,9 +64,10 @@
 void testSimpleConnect() {
   asyncStart();
   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
-    server.listen((_) { });
-    RawSocket.connect("127.0.0.1", server.port).then((_) {
+    server.listen((socket) { socket.close(); });
+    RawSocket.connect("127.0.0.1", server.port).then((socket) {
       server.close();
+      socket.close();
       asyncEnd();
     });
   });
@@ -113,9 +114,11 @@
   asyncStart();
   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     Expect.isTrue(server.port > 0);
-    RawSocket.connect("127.0.0.1", server.port).then((_) {
-      server.listen((_) {
+    RawSocket.connect("127.0.0.1", server.port).then((client) {
+      server.listen((socket) {
+        client.close();
         server.close();
+        socket.close();
         asyncEnd();
       });
     });
@@ -258,7 +261,8 @@
   asyncStart();
   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     Expect.isTrue(server.port > 0);
-    var subscription = server.listen((_) {
+    var subscription = server.listen((socket) {
+      socket.close();
       Expect.isTrue(resumed);
       if (++acceptCount == socketCount) {
         server.close();
@@ -272,14 +276,17 @@
     subscription.pause();
     var connectCount = 0;
     for (int i = 0; i < socketCount / 2; i++) {
-      RawSocket.connect("127.0.0.1", server.port).then((_) {
+      RawSocket.connect("127.0.0.1", server.port).then((socket) {
         if (++connectCount == socketCount / 2) {
           subscription.resume();
           resumed = true;
           for (int i = connectCount; i < socketCount; i++) {
-            RawSocket.connect("127.0.0.1", server.port).then((_) {});
+            RawSocket.connect("127.0.0.1", server.port).then((socket) {
+              socket.close();
+            });
           }
         }
+        socket.close();
       });
     }
   });
diff --git a/tests/standalone/io/secure_builtin_roots_test.dart b/tests/standalone/io/secure_builtin_roots_test.dart
index 025dbe0..875ea09 100644
--- a/tests/standalone/io/secure_builtin_roots_test.dart
+++ b/tests/standalone/io/secure_builtin_roots_test.dart
@@ -41,11 +41,14 @@
   InternetAddress.lookup('www.google.com').then((_) {
     HttpClient client = new HttpClient();
     client.getUrl(Uri.parse('https://www.google.com'))
-      .then((request) => request.close())
+      .then((request) {
+        request.followRedirects = false;
+        return request.close();
+      })
       .then((response) {
         Expect.isTrue(expectSuccess, "Unexpected successful connection");
         print('SUCCESS');
-        return response.last;
+        return response.drain().catchError((_) {});
       })
       .catchError((error) {
         // Allow SocketExceptions if www.google.com is unreachable or down.
diff --git a/tests/standalone/io/signal_test_script.dart b/tests/standalone/io/signal_test_script.dart
new file mode 100644
index 0000000..7f43c5a
--- /dev/null
+++ b/tests/standalone/io/signal_test_script.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.
+
+import "dart:io";
+
+void main(args) {
+  var signal;
+  switch (args[0]) {
+    case 'SIGHUP': signal = ProcessSignal.SIGHUP; break;
+    case 'SIGINT': signal = ProcessSignal.SIGINT; break;
+    case 'SIGTERM': signal = ProcessSignal.SIGTERM; break;
+    case 'SIGUSR1': signal = ProcessSignal.SIGUSR1; break;
+    case 'SIGUSR2': signal = ProcessSignal.SIGUSR2; break;
+    case 'SIGWINCH': signal = ProcessSignal.SIGWINCH; break;
+  }
+  signal.watch().first.then((s) {
+    if (signal != s) exit(1);
+    if (signal.toString() != args[0]) exit(1);
+    print('got signal');
+  });
+  print("ready");
+}
+
diff --git a/tests/standalone/io/signals_test.dart b/tests/standalone/io/signals_test.dart
index 00805a5..d73b01a 100644
--- a/tests/standalone/io/signals_test.dart
+++ b/tests/standalone/io/signals_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:io";
+import "dart:convert";
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
@@ -42,6 +43,32 @@
     });
 }
 
+void testSignal(ProcessSignal signal) {
+  asyncStart();
+  Process.start(Platform.executable,
+      [Platform.script.resolve('signal_test_script.dart').toFilePath(),
+       signal.toString()])
+    .then((process) {
+      process.stdin.close();
+      process.stderr.drain();
+
+      var output = "";
+      process.stdout.transform(UTF8.decoder)
+        .listen((str) {
+          output += str;
+          if (output == 'ready\n') {
+            process.kill(signal);
+          }
+        }, onDone: () {
+          Expect.equals('ready\ngot signal\n', output);
+        });
+      process.exitCode.then((exitCode) {
+        Expect.equals(0, exitCode);
+        asyncEnd();
+      });
+    });
+}
+
 
 void testListenCancel() {
   for (int i = 0; i < 10; i++) {
@@ -61,4 +88,11 @@
   testSignals(1, 10);
   testSignals(1, 0, 0, 1, true);
   testSignals(0, 1, 1, 0, true);
+
+  testSignal(ProcessSignal.SIGHUP);
+  testSignal(ProcessSignal.SIGINT);
+  testSignal(ProcessSignal.SIGTERM);
+  testSignal(ProcessSignal.SIGUSR1);
+  testSignal(ProcessSignal.SIGUSR2);
+  testSignal(ProcessSignal.SIGWINCH);
 }
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index 6381558..58abb85 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -40,6 +40,7 @@
     asyncStart();
     ServerSocket.bind("127.0.0.1", 0).then((server) {
       Socket.connect("127.0.0.1", server.port).then((socket) {
+        socket.destroy();
         server.close();
         server.listen(
           (incoming) => Expect.fail("Unexpected socket"),
@@ -53,8 +54,11 @@
     ServerSocket.bind("127.0.0.1", 0).then((server) {
       Socket.connect("127.0.0.1", server.port).then((socket) {
         server.listen(
-          (incoming) => server.close(),
-          onDone: asyncEnd);
+          (incoming) {
+            incoming.destroy();
+            socket.destroy();
+            server.close();
+          }, onDone: asyncEnd);
       });
     });
   }
diff --git a/tests/standalone/io/socket_info_test.dart b/tests/standalone/io/socket_info_test.dart
index 7a5a20f..eb14246 100644
--- a/tests/standalone/io/socket_info_test.dart
+++ b/tests/standalone/io/socket_info_test.dart
@@ -15,7 +15,8 @@
         Expect.equals(clientSocket.remotePort, socket.port);
         Expect.equals(socket.remoteAddress.address, "127.0.0.1");
         Expect.equals(clientSocket.remoteAddress.address, "127.0.0.1");
-
+        socket.destroy();
+        clientSocket.destroy();
         server.close();
       });
     });
diff --git a/tests/standalone/io/socket_port_test.dart b/tests/standalone/io/socket_port_test.dart
index d9c75d7..e7a24ec 100644
--- a/tests/standalone/io/socket_port_test.dart
+++ b/tests/standalone/io/socket_port_test.dart
@@ -9,9 +9,11 @@
   ServerSocket.bind("127.0.0.1", 0).then((server) {
     Socket.connect("127.0.0.1", server.port).then((clientSocket) {
       server.listen((Socket socket) {
-          Expect.equals(socket.port, server.port);
+        Expect.equals(socket.port, server.port);
         Expect.equals(clientSocket.port, socket.remotePort);
         Expect.equals(clientSocket.remotePort, socket.port);
+        clientSocket.destroy();
+        socket.destroy();
         server.close();
       });
     });
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index 56a76bb..3ebadf8 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -62,17 +62,6 @@
       });
 }
 
-void testConnectNoDestroy() {
-  asyncStart();
-  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
-    server.listen((_) { });
-    Socket.connect("127.0.0.1", server.port).then((_) {
-      server.close();
-      asyncEnd();
-    });
-  });
-}
-
 void testConnectImmediateDestroy() {
   asyncStart();
   ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
@@ -210,26 +199,10 @@
   });
 }
 
-void testCloseWriteNoListen() {
-  asyncStart();
-  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
-    server.listen(
-        (client) {
-          client.close();
-        });
-    Socket.connect("127.0.0.1", server.port).then((socket) {
-      socket.close();
-      server.close();
-      asyncEnd();
-    });
-  });
-}
-
 main() {
   testArguments();
   testSimpleBind();
   testInvalidBind();
-  testConnectNoDestroy();
   testConnectImmediateDestroy();
   testConnectConsumerClose();
   testConnectConsumerWriteClose();
@@ -238,5 +211,4 @@
   testConnectStreamDataClose(false);
   testConnectStreamDataCloseCancel(true);
   testConnectStreamDataCloseCancel(false);
-  testCloseWriteNoListen();
 }
diff --git a/tests/standalone/io/status_file_parser_test.dart b/tests/standalone/io/status_file_parser_test.dart
index d9c2f68..8c120c6 100644
--- a/tests/standalone/io/status_file_parser_test.dart
+++ b/tests/standalone/io/status_file_parser_test.dart
@@ -7,6 +7,7 @@
 import "package:expect/expect.dart";
 import "dart:io";
 import "../../../tools/testing/dart/status_file_parser.dart";
+import "../../../tools/testing/dart/utils.dart";
 
 
 void main() {
@@ -35,7 +36,7 @@
   File file = new File(fixedFilePath(filePath));
   if (file.existsSync()) {
     List<Section> sections = new List<Section>();
-    ReadConfigurationInto(file.path, sections, () {
+    ReadConfigurationInto(new Path(file.path), sections, () {
       Expect.isTrue(sections.length > 0);
     });
   }
diff --git a/tests/standalone/issue14236_source.dart b/tests/standalone/issue14236_source.dart
index d0e9234..a422cae 100644
--- a/tests/standalone/issue14236_source.dart
+++ b/tests/standalone/issue14236_source.dart
@@ -9,9 +9,11 @@
 // test.
 // 
 // When issue14236_test.dart fails, you must regenerate it using the VM 
-// with your changes. Notes on regenerating:
+// with your changes. You should understand what in your change makes
+// regeneration of the snapshot necessary.
+// Steps for regenerating:
 // 1) Swap the test and main functions below.
-// 2) $ dart --snapshot=issue14236_test.dart issue14236_source.dart
+// 2) $ ./xcodebuild/DebugIA32/dart --package-root=./xcodebuild/DebugIA32/packages --snapshot=tests/standalone/issue14236_test.dart tests/standalone/issue14236_source.dart
 // 3) Undo changes in 1.
 
 library test.issue14236;
@@ -19,10 +21,16 @@
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 
+
 /*
 test(SendPort replyTo) {
   replyTo.send("from Isolate");
 }
+*/
+
+test() {
+  Expect.fail("Don't expect this to run at all");
+}
 
 main() {
   asyncStart();
@@ -33,11 +41,3 @@
     asyncEnd();
   });
 }
-*/
-
-test() {
-  Expect.fail("Don't expect this to run at all");
-}
-main() {
-  Expect.fail("Don't expect this to run at all");
-}
diff --git a/tests/standalone/issue14236_test.dart b/tests/standalone/issue14236_test.dart
index d0ea1af..3baeb38 100644
--- a/tests/standalone/issue14236_test.dart
+++ b/tests/standalone/issue14236_test.dart
Binary files differ
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 97c3f5e..e21c3b4 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -9,7 +9,7 @@
 
 package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
 
-issue14236_test: Crash # Issue 14516.
+issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
 
 [ $runtime == vm ]
 package/package_isolate_test: Fail # Issue 12474
@@ -100,9 +100,6 @@
 # Skip until we stabilize language tests.
 *: Skip
 
-[ $arch == arm ]
-io/internet_address_test: Fail  # localhost is an Unknown name?
-
 [ $arch == simarm ]
 out_of_memory_test: Skip # passes on Mac, crashes on Linux
 oom_error_stacktrace_test: Skip # Fails on Linux
diff --git a/tests/standalone/vmservice/websocket_client_test.dart b/tests/standalone/vmservice/websocket_client_test.dart
index 97f4492..d48201b 100644
--- a/tests/standalone/vmservice/websocket_client_test.dart
+++ b/tests/standalone/vmservice/websocket_client_test.dart
@@ -46,4 +46,4 @@
       test.runTest();
     });
   });
-}
\ No newline at end of file
+}
diff --git a/tools/VERSION b/tools/VERSION
index 2d4e26f..059f58b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 1
-MINOR 2
+MINOR 3
 PATCH 0
-PRERELEASE 5
-PRERELEASE_PATCH 15
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/bots/fetch_reference_build.py b/tools/bots/fetch_reference_build.py
new file mode 100755
index 0000000..9ca6f5d
--- /dev/null
+++ b/tools/bots/fetch_reference_build.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 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.
+
+"""Fetches an archived chromium build into
+  src/chrome/tools/test/reference_build unless
+  src/chrome/tools/test/reference_build/REQUESTED_REVISION is the same as
+  src/chrome/tools/test/reference_build/CURRENT_REVISION.
+  Must be run from the root of a Dartium or multivm checkout.
+
+Usage:
+  $ ./src/dart/tools/bots/fetch_reference_build_revision.py
+"""
+
+import os
+import subprocess
+import sys
+
+def main(argv):
+  dirname = os.path.join('src', 'chrome', 'tools',
+                        'test', 'reference_build')
+  request = os.path.join(dirname, 'REQUESTED_REVISION')
+  found = os.path.join(dirname, 'CURRENT_REVISION')
+  if not os.path.exists(request):
+    return
+  with file(request, 'r') as f:
+    request_revision = f.read()
+
+  if os.path.exists(found):
+    with file(found, 'r') as f:
+      found_revision = f.read()
+    if found_revision == request_revision:
+      return
+
+  get_script = os.path.join('src', 'dart', 'tools',
+                            'bots', 'get_chromium_build.py')
+  get_script = os.path.abspath(get_script)
+  exit_code = subprocess.call(['python', get_script,
+                               '-r', request_revision,
+                               '-t', dirname])
+  if exit_code == 0:
+    with file(found, 'w') as f:
+      f.write(request_revision)
+  return exit_code
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/tools/bots/get_chromium_build.py b/tools/bots/get_chromium_build.py
new file mode 100755
index 0000000..c5bbd33
--- /dev/null
+++ b/tools/bots/get_chromium_build.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 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.
+
+"""Gets a Chromium archived build, and unpacks it
+   into a target directory.
+
+  Use -r option to specify the revison number
+  Use -t option to specify the directory to unzip the build into.
+
+Usage:
+  $ get_chromium_build.py -r <revision> -t <target>
+"""
+
+import logging
+import optparse
+import os
+import platform
+import shutil
+import subprocess
+import sys
+import time
+import urllib
+import urllib2
+import zipfile
+
+# Example chromium build location:
+# gs://chromium-browser-snapshots/Linux_x64/228977/chrome-linux.zip
+CHROMIUM_URL_FMT = ('http://commondatastorage.googleapis.com/'
+                    'chromium-browser-snapshots/%s/%s/%s')
+
+class BuildUpdater(object):
+  _PLATFORM_PATHS_MAP = {
+      'Linux': { 'zipfiles': ['chrome-linux.zip'],
+                 'folder': 'chrome_linux',
+                 'archive_path': 'Linux_x64'},
+      'Darwin': {'zipfiles': ['chrome-mac.zip'],
+                 'folder': 'chrome_mac',
+                 'archive_path': 'Mac'},
+      'Windows': {'zipfiles': ['chrome-win32.zip',
+                               'chrome-win32-syms.zip'],
+                 'folder': 'chrome_win',
+                 'archive_path': 'Win'}}
+
+  def __init__(self, options):
+    platform_data = BuildUpdater._PLATFORM_PATHS_MAP[platform.system()]
+    self._zipfiles = platform_data['zipfiles']
+    self._folder = platform_data['folder']
+    self._archive_path = platform_data['archive_path']
+    self._revision = int(options.revision)
+    self._target_dir = options.target_dir
+    self._download_dir = os.path.join(self._target_dir, 'downloads')
+
+  def _GetBuildUrl(self, revision, filename):
+    return CHROMIUM_URL_FMT % (self._archive_path, revision, filename)
+
+  def _FindBuildRevision(self, revision, filename):
+    MAX_REVISIONS_PER_BUILD = 100
+    for revision_guess in xrange(revision, revision + MAX_REVISIONS_PER_BUILD):
+      if self._DoesBuildExist(revision_guess, filename):
+        return revision_guess
+      else:
+        time.sleep(.1)
+    return None
+
+  def _DoesBuildExist(self, revision_guess, filename):
+    url = self._GetBuildUrl(revision_guess, filename)
+
+    r = urllib2.Request(url)
+    r.get_method = lambda: 'HEAD'
+    try:
+      urllib2.urlopen(r)
+      return True
+    except urllib2.HTTPError, err:
+      if err.code == 404:
+        return False
+
+  def _DownloadBuild(self):
+    if not os.path.exists(self._download_dir):
+      os.makedirs(self._download_dir)
+    for zipfile in self._zipfiles:
+      build_revision = self._FindBuildRevision(self._revision, zipfile)
+      if not build_revision:
+        logging.critical('Failed to find %s build for r%s\n',
+                         self._archive_path,
+                         self._revision)
+        sys.exit(1)
+      url = self._GetBuildUrl(build_revision, zipfile)
+      logging.info('Downloading %s', url)
+      r = urllib2.urlopen(url)
+      with file(os.path.join(self._download_dir, zipfile), 'wb') as f:
+        f.write(r.read())
+
+  def _UnzipFile(self, dl_file, dest_dir):
+    if not zipfile.is_zipfile(dl_file):
+      return False
+    logging.info('Unzipping %s', dl_file)
+    with zipfile.ZipFile(dl_file, 'r') as z:
+      for content in z.namelist():
+        dest = os.path.join(dest_dir, content[content.find('/')+1:])
+        # Create dest parent dir if it does not exist.
+        if not os.path.isdir(os.path.dirname(dest)):
+          logging.info('Making %s', dest)
+          os.makedirs(os.path.dirname(dest))
+        # If dest is just a dir listing, do nothing.
+        if not os.path.basename(dest):
+          continue
+        with z.open(content) as unzipped_content:
+          logging.info('Extracting %s to %s (%s)', content, dest, dl_file)
+          with file(dest, 'wb') as dest_file:
+            dest_file.write(unzipped_content.read())
+          permissions = z.getinfo(content).external_attr >> 16
+          if permissions:
+            os.chmod(dest, permissions)
+    return True
+
+  def _ClearDir(self, dir):
+    """Clears all files in |dir| except for hidden files and folders."""
+    for root, dirs, files in os.walk(dir):
+      # Skip hidden files and folders (like .svn and .git).
+      files = [f for f in files if f[0] != '.']
+      dirs[:] = [d for d in dirs if d[0] != '.']
+
+      for f in files:
+        os.remove(os.path.join(root, f))
+
+  def _ExtractBuild(self):
+    dest_dir = os.path.join(self._target_dir, self._folder)
+    self._ClearDir(dest_dir)
+    for root, _, dl_files in os.walk(os.path.join(self._download_dir)):
+      for dl_file in dl_files:
+        dl_file = os.path.join(root, dl_file)
+        if not self._UnzipFile(dl_file, dest_dir):
+          logging.info('Copying %s to %s', dl_file, dest_dir)
+          shutil.copy(dl_file, dest_dir)
+    shutil.rmtree(self._download_dir)
+
+  def DownloadAndUpdateBuild(self):
+    self._DownloadBuild()
+    self._ExtractBuild()
+
+
+def ParseOptions(argv):
+  parser = optparse.OptionParser()
+  usage = 'usage: %prog <options>'
+  parser.set_usage(usage)
+  parser.add_option('-r', dest='revision',
+                    help='Revision to download.')
+  parser.add_option('-t', dest='target_dir',
+                    help='Target directory for unzipped Chromium.')
+
+  (options, _) = parser.parse_args(argv)
+  if not options.revision:
+    logging.critical('Must specify -r.\n')
+    sys.exit(1)
+  if not options.target_dir:
+    logging.critical('Must specify -t.\n')
+    sys.exit(1)
+  return options
+
+def main(argv):
+  logging.getLogger().setLevel(logging.DEBUG)
+  options = ParseOptions(argv)
+  b = BuildUpdater(options)
+  b.DownloadAndUpdateBuild()
+  logging.info('Successfully got archived Chromium build.')
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/tools/bots/set_reference_build_revision.py b/tools/bots/set_reference_build_revision.py
new file mode 100755
index 0000000..d03bb17
--- /dev/null
+++ b/tools/bots/set_reference_build_revision.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 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.
+
+"""Writes a revision number into src/chrome/tools/test/reference_build/REVISON
+   Must be run from the root of a Dartium or multivm checkout.
+
+Usage:
+  $ ./src/dart/tools/bots/set_reference_build_revision.py <revision>
+"""
+
+import os
+import sys
+
+def main(argv):
+  revision = argv[1]
+  output = os.path.join('src', 'chrome', 'tools',
+                        'test', 'reference_build',
+                        'REQUESTED_REVISION')
+  dirname = os.path.dirname(output)
+  if dirname and not os.path.exists(dirname):
+    os.makedirs(dirname)
+  with file(output, 'w') as f:
+    f.write(revision)
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 67d9b57..fee093e 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -109,8 +109,6 @@
       "@Creates('Null')", # JS date object.
     ],
 
-    'FileReader.result': ["@Creates('String|NativeByteBuffer|Null')"],
-
     'FocusEvent.relatedTarget': [
       "@Creates('Null')",
     ],
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 00979ab..612ed7a 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -244,6 +244,7 @@
     self._renamer = renamer
     self._metadata = metadata
     self._template_loader = template_loader
+    self._media_events = None
 
   def EmitStreamProviders(self, interface, custom_events,
       members_emitter, library_name):
@@ -387,8 +388,9 @@
         interface.doc_js_name == 'Document' or
         interface.doc_js_name == 'GlobalEventHandlers'):
       media_interface = self._database.GetInterface('HTMLMediaElement')
-      media_events = self._GetEvents(media_interface, [])
-      if self._HasEvent(media_events, event_name, event_type):
+      if not self._media_events:
+        self._media_events = self._GetEvents(media_interface, [])
+      if self._HasEvent(self._media_events, event_name, event_type):
         return True
 
   def _GetEventRedirection(self, interface, event_name, event_type):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 54ad00d..84d22fe 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -52,6 +52,9 @@
     'ConsoleBase.warn',
     'WebKitCSSKeyframesRule.insertRule',
     'CSSStyleDeclaration.setProperty',
+    'Document.createNodeIterator',
+    'Document.createTreeWalker',
+    'DOMException.name',
     'Element.createShadowRoot',
     'Element.insertAdjacentElement',
     'Element.insertAdjacentHTML',
@@ -61,9 +64,7 @@
     'Element.webkitMatchesSelector',
     'ElementEvents.mouseWheel',
     'ElementEvents.transitionEnd',
-    'Document.createNodeIterator',
-    'Document.createTreeWalker',
-    'DOMException.name',
+    'FileReader.result',
     'HTMLTableElement.createTBody',
     'IDBCursor.next',
     'IDBDatabase.transaction',
diff --git a/tools/dom/src/CssRectangle.dart b/tools/dom/src/CssRectangle.dart
index fe1c562..e82ddd9 100644
--- a/tools/dom/src/CssRectangle.dart
+++ b/tools/dom/src/CssRectangle.dart
@@ -157,7 +157,7 @@
  * animation frame is discouraged. See also:
  * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
  */
-abstract class CssRect extends MutableRectangle<num> implements Rectangle<num> {
+abstract class CssRect extends MutableRectangle<num> {
   Element _element;
 
   CssRect(this._element) : super(0, 0, 0, 0);
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index f3be576..e8124e0 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -6,6 +6,21 @@
  * KeyEvent tries to provide a higher level, more polished keyboard event
  * information on top of the "raw" [KeyboardEvent].
  *
+ * The mechanics of using KeyEvents is a little different from the underlying
+ * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
+ * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
+ * Here's an example usage:
+ *
+ *     // Initialize a stream for the KeyEvents:
+ *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
+ *     // Start listening to the stream of KeyEvents.
+ *     stream.listen((keyEvent) =>
+ *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
+ *     ...
+ *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
+ *     // listeners can know a KeyEvent happened.
+ *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
+ *
  * This class is very much a work in progress, and we'd love to get information
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index d3716b3..1f9659c 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -6,6 +6,21 @@
  * KeyEvent tries to provide a higher level, more polished keyboard event
  * information on top of the "raw" [KeyboardEvent].
  *
+ * The mechanics of using KeyEvents is a little different from the underlying
+ * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
+ * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
+ * Here's an example usage:
+ *
+ *     // Initialize a stream for the KeyEvents:
+ *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
+ *     // Start listening to the stream of KeyEvents.
+ *     stream.listen((keyEvent) =>
+ *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
+ *     ...
+ *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
+ *     // listeners can know a KeyEvent happened.
+ *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
+ *
  * This class is very much a work in progress, and we'd love to get information
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
diff --git a/tools/dom/templates/html/impl/impl_FileReader.darttemplate b/tools/dom/templates/html/impl/impl_FileReader.darttemplate
new file mode 100644
index 0000000..5895c2a
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_FileReader.darttemplate
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+@DocsEditable()
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+$if DART2JS
+  @DomName('FileReader.result')
+  @DocsEditable()
+  Object get result {
+    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
+    if (res is ByteBuffer) {
+      return new Uint8List.view(res);
+    }
+    return res;
+  }
+$endif
+
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_HTMLLinkElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLLinkElement.darttemplate
new file mode 100644
index 0000000..fb38c2c
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_HTMLLinkElement.darttemplate
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+@DocsEditable()
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$MIXINS$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+
+    /// Checks if HTML imports are supported on the current platform.
+  bool get supportsImport {
+$if DART2JS
+    return JS('bool', '("import" in #)', this);
+$else
+    return true;
+$endif
+  }
+}
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index a19ba4d..539e645 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -62,6 +62,17 @@
    * This is similar to [request] but specialized for HTTP GET requests which
    * return text content.
    *
+   * To add query parameters, append them to the [url] following a `?`,
+   * joining each key to its value with `=` and separating key-value pairs with
+   * `&`.
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.getString('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -79,6 +90,20 @@
    * to sending a FormData object with broader browser support but limited to
    * String values.
    *
+   * If [data] is supplied, the key/value pairs are URI encoded with
+   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
+   *
+   * Unless otherwise specified, this method appends the following header:
+   *
+   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
+   *
+   * Here's an example of using this method:
+   *
+   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
+   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
+   *       // Do something with the response.
+   *     });
+   *
    * See also:
    *
    * * [request]
@@ -130,6 +155,24 @@
    * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
    * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    *
+   * The following is equivalent to the [getString] sample above:
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.request('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * Here's an example of submitting an entire form with [FormData].
+   *
+   *     var myForm = querySelector('form#myForm');
+   *     var data = new FormData(myForm);
+   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
    * Note that requests for file:// URIs are only supported by Chrome extensions
    * with appropriate permissions in their manifest. Requests to file:// URIs
    * will also never fail- the Future will always complete successfully, even
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
index 5f3448c..5272396 100755
--- a/tools/line_doc_comments.dart
+++ b/tools/line_doc_comments.dart
@@ -33,18 +33,21 @@
 
 void fixFile(String path) {
   var file = new File(path);
-  file.readAsLines().then(fixContents).then((fixed) {
+  file.readAsLines().then((lines) => fixContents(lines, path)).then((fixed) {
     return new File(path).writeAsString(fixed);
   }).then((file) {
     print(file.path);
   });
 }
 
-String fixContents(List<String> lines) {
+String fixContents(List<String> lines, String path) {
   var buffer = new StringBuffer();
+  var linesOut = 0;
   var inBlock = false;
   var indent;
+
   for (var line in lines) {
+    var oldLine = line;
     if (inBlock) {
       // See if it's the end of the comment.
       if (endBlock.hasMatch(line)) {
@@ -54,11 +57,13 @@
         line = null;
       } else {
         var match = blockLine.firstMatch(line);
-        var comment = match[1];
-        if (comment != '') {
-          line = '$indent/// $comment';
-        } else {
-          line = '$indent///';
+        if (match != null) {
+          var comment = match[1];
+          if (comment != '') {
+            line = '$indent/// $comment';
+          } else {
+            line = '$indent///';
+          }
         }
       }
     } else {
@@ -92,7 +97,21 @@
       }
     }
 
-    if (line != null) buffer.write('$line\n');
+    if (line != null) {
+      linesOut++;
+
+      // Warn about lines that crossed 80 columns as a result of the change.
+      if (line.length > 80 && oldLine.length <= 80) {
+        const _PURPLE = '\u001b[35m';
+        const _RED = '\u001b[31m';
+        const _NO_COLOR = '\u001b[0m';
+
+        print('$_PURPLE$path$_NO_COLOR:$_RED$linesOut$_NO_COLOR: '
+            'line exceeds 80 cols:\n    $line');
+      }
+
+      buffer.write('$line\n');
+    }
   }
 
   return buffer.toString();
diff --git a/tools/status_clean.dart b/tools/status_clean.dart
new file mode 100644
index 0000000..c28b1a3
--- /dev/null
+++ b/tools/status_clean.dart
@@ -0,0 +1,417 @@
+// 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 status_clean;
+
+import "dart:async";
+import "dart:convert" show JSON, UTF8;
+import "dart:io";
+import "testing/dart/multitest.dart";
+import "testing/dart/status_file_parser.dart";
+import "testing/dart/test_suite.dart"
+    show multiHtmlTestGroupRegExp, multiTestRegExp, multiHtmlTestRegExp,
+         TestUtils;
+import "testing/dart/utils.dart" show Path;
+
+// [STATUS_TUPLES] is a list of (suite-name, directory, status-file)-tuples.
+final STATUS_TUPLES = [
+    ["corelib", "tests/corelib", "tests/corelib/corelib.status"],
+    ["html", "tests/html", "tests/html/html.status"],
+    ["isolate", "tests/isolate", "tests/isolate/isolate.status"],
+    ["json", "tests/json", "tests/json/json.status"],
+    ["language", "tests/language", "tests/language/language.status"],
+    ["language", "tests/language", "tests/language/language_analyzer2.status"],
+    ["language","tests/language", "tests/language/language_analyzer.status"],
+    ["language","tests/language", "tests/language/language_dart2js.status"],
+    ["lib", "tests/lib", "tests/lib/lib.status"],
+    ["standalone", "tests/standalone", "tests/standalone/standalone.status"],
+    ["pkg", "pkg", "pkg/pkg.status"],
+    ["pkgbuild", ".", "pkg/pkgbuild.status"],
+    ["utils", "tests/utils", "tests/utils/utils.status"],
+    ["samples", "samples", "samples/samples.status"],
+    ["analyze_library", "sdk", "tests/lib/analyzer/analyze_library.status"],
+    ["dart2js_extra", "tests/compiler/dart2js_extra",
+     "tests/compiler/dart2js_extra/dart2js_extra.status"],
+    ["dart2js_native", "tests/compiler/dart2js_native",
+     "tests/compiler/dart2js_native/dart2js_native.status"],
+    ["dart2js", "tests/compiler/dart2js",
+     "tests/compiler/dart2js/dart2js.status"],
+    ["pub", "sdk/lib/_internal/pub", "sdk/lib/_internal/pub/pub.status"],
+    ["benchmark_smoke", "tests/benchmark_smoke",
+     "tests/benchmark_smoke/benchmark_smoke.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-analyzer2.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-analyzer.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-dart2dart.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-dart2js.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-co19.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-dartium.status"],
+    ["co19", "tests/co19/src", "tests/co19/co19-runtime.status"],
+];
+
+void main(List<String> args) {
+  usage() {
+    print("Usage: ${Platform.executable} <deflake|remove-nonexistent-tests>");
+    exit(1);
+  }
+
+  if (args.length == 0) usage();
+
+  if (args[0] == 'deflake') {
+    run(new StatusFileDeflaker());
+  } else if (args[0] == 'remove-nonexistent-tests') {
+    run(new StatusFileNonExistentTestRemover());
+  } else {
+    usage();
+  }
+}
+
+run(StatusFileProcessor processor) {
+  Future.forEach(STATUS_TUPLES, (List tuple) {
+    String suiteName = tuple[0];
+    String directory = tuple[1];
+    String filePath = tuple[2];
+    print("Processing $filePath");
+    return processor.run(suiteName, directory, filePath);
+  });
+}
+
+abstract class StatusFileProcessor {
+  Future run(String suiteName, String directory, String filePath);
+
+  Future<List<Section>> _readSections(String filePath) {
+    File file = new File(filePath);
+
+    if (file.existsSync()) {
+      var completer = new Completer();
+      List<Section> sections = new List<Section>();
+
+      ReadConfigurationInto(new Path(file.path), sections, () {
+        completer.complete(sections);
+      });
+      return completer.future;
+    }
+    return new Future.value([]);
+  }
+}
+
+class StatusFileNonExistentTestRemover extends StatusFileProcessor {
+  final MultiTestDetector multiTestDetector = new MultiTestDetector();
+  final TestFileLister testFileLister = new TestFileLister();
+
+  Future run(String suiteName, String directory, String filePath) {
+    return _readSections(filePath).then((List<Section> sections) {
+      Set<int> invalidLines = _analyzeStatusFile(directory, filePath, sections);
+      if (invalidLines.length > 0) {
+        return _writeFixedStatusFile(filePath, invalidLines);
+      }
+      return new Future.value();
+    });
+  }
+
+  bool _testExists(String filePath,
+                   List<String> testFiles,
+                   String directory,
+                   TestRule rule) {
+    // TODO: Unify this regular expression matching with status_file_parser.dart
+    List<RegExp> getRuleRegex(String name) {
+      return name.split("/")
+          .map((name) => new RegExp(name.replaceAll('*', '.*')))
+          .toList();
+    }
+    bool matchRegexp(List<RegExp> patterns, String str) {
+      var parts = str.split("/");
+      if (patterns.length > parts.length) {
+        return false;
+      }
+      // NOTE: patterns.length <= parts.length
+      for (var i = 0; i < patterns.length; i++) {
+        if (!patterns[i].hasMatch(parts[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    var rulePattern = getRuleRegex(rule.name);
+    return testFiles.any((String file) {
+      // TODO: Use test_suite.dart's [buildTestCaseDisplayName] instead.
+      var filePath = new Path(file).relativeTo(new Path(directory));
+      String baseTestName = _concat("${filePath.directoryPath}",
+                                    "${filePath.filenameWithoutExtension}");
+
+      List<String> testNames = [];
+      for (var name in multiTestDetector.getMultitestNames(file)) {
+        testNames.add(_concat(baseTestName, name));
+      }
+
+      // If it is not a multitest the testname is [baseTestName]
+      if (testNames.isEmpty) {
+        testNames.add(baseTestName);
+      }
+
+      return testNames.any(
+          (String testName) => matchRegexp(rulePattern, testName));
+    });
+  }
+
+  Set<int> _analyzeStatusFile(String directory,
+                              String filePath,
+                              List<Section> sections) {
+    var invalidLines = new Set<int>();
+    var dartFiles = testFileLister.listTestFiles(directory);
+    for (var section in sections) {
+      for (var rule in section.testRules) {
+        if (!_testExists(filePath, dartFiles, directory, rule)) {
+          print("Invalid rule: ${rule.name} in file "
+                "$filePath:${rule.lineNumber}");
+          invalidLines.add(rule.lineNumber);
+        }
+      }
+    }
+    return invalidLines;
+  }
+
+  _writeFixedStatusFile(String statusFilePath, Set<int> invalidLines) {
+    var lines = new File(statusFilePath).readAsLinesSync();
+    var outputLines = <String>[];
+    for (int i = 0; i < lines.length; i++) {
+      // The status file parser numbers lines starting with 1, not 0.
+      if (!invalidLines.contains(i + 1)) {
+        outputLines.add(lines[i]);
+      }
+    }
+    var outputFile = new File("$statusFilePath.fixed");
+    outputFile.writeAsStringSync(outputLines.join("\n"));
+ }
+
+  String _concat(String base, String part) {
+    if (base == "") return part;
+    if (part == "") return base;
+    return "$base/$part";
+  }
+}
+
+class StatusFileDeflaker extends StatusFileProcessor {
+  TestOutcomeFetcher _testOutcomeFetcher = new TestOutcomeFetcher();
+
+  Future run(String suiteName, String directory, String filePath) {
+    return _readSections(filePath).then((List<Section> sections) {
+      return _generatedDeflakedLines(suiteName, sections)
+          .then((Map<int, String> fixedLines) {
+            if (fixedLines.length > 0) {
+              return _writeFixedStatusFile(filePath, fixedLines);
+            }
+      });
+    });
+  }
+
+  Future _generatedDeflakedLines(String suiteName,
+                                 List<Section> sections) {
+    var fixedLines = new Map<int, String>();
+    return Future.forEach(sections, (Section section) {
+      return Future.forEach(section.testRules, (rule) {
+        return _maybeFixStatusfileLine(suiteName, section, rule, fixedLines);
+      });
+    }).then((_) => fixedLines);
+  }
+
+  Future _maybeFixStatusfileLine(String suiteName,
+                                 Section section,
+                                 TestRule rule,
+                                 Map<int, String> fixedLines) {
+    print("Processing ${section.statusFile.location}: ${rule.lineNumber}");
+    // None of our status file lines have expressions, so we pass {} here.
+    var notedOutcomes = rule.expression
+        .evaluate({})
+        .map((name) => Expectation.byName(name))
+        .where((Expectation expectation) => !expectation.isMetaExpectation)
+        .toSet();
+
+    if (notedOutcomes.isEmpty) return new Future.value();
+
+    // TODO: [rule.name] is actually a pattern not just a testname. We should
+    // find all possible testnames this rule matches against and unify the
+    // outcomes of these tests.
+    return _testOutcomeFetcher.outcomesOf(suiteName, section, rule.name)
+      .then((Set<Expectation> actualOutcomes) {
+
+      var outcomesThatNeverHappened = new Set<Expectation>();
+      for (Expectation notedOutcome in notedOutcomes) {
+        bool found = false;
+        for (Expectation actualOutcome in actualOutcomes) {
+          if (actualOutcome.canBeOutcomeOf(notedOutcome)) {
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          outcomesThatNeverHappened.add(notedOutcome);
+        }
+      }
+
+      if (outcomesThatNeverHappened.length > 0 && actualOutcomes.length > 0) {
+        // Print the change to stdout.
+        print("${rule.name} "
+              "(${section.statusFile.location}:${rule.lineNumber}):");
+        print("   Actual outcomes:         ${actualOutcomes.toList()}");
+        print("   Outcomes in status file: ${notedOutcomes.toList()}");
+        print("   Outcomes in status file that never happened : "
+              "${outcomesThatNeverHappened.toList()}\n");
+
+        // Build the fixed status file line.
+        fixedLines[rule.lineNumber] =
+            '${rule.name}: ${actualOutcomes.join(', ')} '
+            '# before: ${notedOutcomes.join(', ')} / '
+            'never happened:  ${outcomesThatNeverHappened.join(', ')}';
+      }
+    });
+  }
+
+  _writeFixedStatusFile(String filePath, Map<int, String> fixedLines) {
+    var lines = new File(filePath).readAsLinesSync();
+    var outputLines = <String>[];
+    for (int i = 0; i < lines.length; i++) {
+      if (fixedLines.containsKey(i + 1)) {
+        outputLines.add(fixedLines[i + 1]);
+      } else {
+        outputLines.add(lines[i]);
+      }
+    }
+    var output = outputLines.join("\n");
+    var outputFile = new File("$filePath.deflaked");
+    outputFile.writeAsStringSync(output);
+ }
+}
+
+class MultiTestDetector {
+  final multiTestsCache = new Map<String,List<String>>();
+  final multiHtmlTestsCache = new Map<String,List<String>>();
+
+
+  List<String> getMultitestNames(String file) {
+    List<String> names = [];
+    names.addAll(getStandardMultitestNames(file));
+    names.addAll(getHtmlMultitestNames(file));
+    return names;
+  }
+
+  List<String> getStandardMultitestNames(String file) {
+    return multiTestsCache.putIfAbsent(file, () {
+      try {
+        var tests = new Map<String, String>();
+        var outcomes = new Map<String, Set<String>>();
+        if (multiTestRegExp.hasMatch(new File(file).readAsStringSync())) {
+          ExtractTestsFromMultitest(new Path(file), tests, outcomes);
+        }
+        return tests.keys.toList();
+      } catch (error) {
+        print("WARNING: Couldn't determine multitests in file ${file}: $error");
+        return [];
+      }
+    });
+  }
+
+  List<String> getHtmlMultitestNames(String file) {
+    return multiHtmlTestsCache.putIfAbsent(file, () {
+      try {
+        List<String> subtestNames = [];
+        var content = new File(file).readAsStringSync();
+
+        if (multiHtmlTestRegExp.hasMatch(content)) {
+          var matchesIter = multiHtmlTestGroupRegExp.allMatches(content).iterator;
+          while(matchesIter.moveNext()) {
+            String fullMatch = matchesIter.current.group(0);
+            subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
+          }
+        }
+        return subtestNames;
+      } catch (error) {
+        print("WARNING: Couldn't determine multitests in file ${file}: $error");
+      }
+      return [];
+    });
+  }
+}
+
+class TestFileLister {
+  final Map<String, List<String>> _filesCache = {};
+
+  List<String> listTestFiles(String directory) {
+    return _filesCache.putIfAbsent(directory, () {
+      var dir = new Directory(directory);
+      // Cannot test for _test.dart because co19 tests don't have that ending.
+      var dartFiles = dir.listSync(recursive: true)
+          .where((fe) => fe is File)
+          .where((file) => file.path.endsWith(".dart") ||
+                           file.path.endsWith("_test.html"))
+          .map((file) => file.path)
+          .toList();
+      return dartFiles;
+    });
+  }
+}
+
+
+/*
+ * [TestOutcomeFetcher] will fetch test results from a server using a REST-like
+ * interface.
+ */
+class TestOutcomeFetcher {
+  static String SERVER = '108.170.219.8';
+  static int PORT = 4540;
+
+  HttpClient _client = new HttpClient();
+
+  Future<Set<Expectation>> outcomesOf(
+      String suiteName, Section section, String testName) {
+    var pathComponents = ['json', 'test-outcomes', 'outcomes',
+                          Uri.encodeComponent("$suiteName/$testName")];
+    var path = pathComponents.join('/') + '/';
+    var url = new Uri(scheme: 'http', host: SERVER, port: PORT, path: path);
+
+    return _client.getUrl(url)
+      .then((HttpClientRequest request) => request.close())
+      .then((HttpClientResponse response) {
+        return response.transform(UTF8.decoder).transform(JSON.decoder).first
+            .then((List testResults) {
+              var setOfActualOutcomes = new Set<Expectation>();
+
+              try {
+                for (var result in testResults) {
+                  var config = result['configuration'];
+                  var testResult = result['test_result'];
+                  var outcome = testResult['outcome'];
+
+                  // These variables are derived variables and will be set in
+                  // tools/testing/dart/test_options.dart.
+                  // [Mostly due to the fact that we don't have an unary !
+                  //  operator in status file expressions.]
+                  config['unchecked'] = !config['checked'];
+                  config['unminified'] = !config['minified'];
+                  config['nocsp'] = !config['csp'];
+                  config['browser'] =
+                      TestUtils.isBrowserRuntime(config['runtime']);
+                  config['analyzer'] =
+                      TestUtils.isCommandLineAnalyzer(config['compiler']);
+                  config['jscl'] =
+                      TestUtils.isJsCommandLineRuntime(config['runtime']);
+
+                  if (section.condition == null ||
+                      section.condition.evaluate(config)) {
+                    setOfActualOutcomes.add(Expectation.byName(outcome));
+                  }
+                }
+                return setOfActualOutcomes;
+              } catch (error) {
+                print("Warning: Error occured while processing testoutcomes"
+                      ": $error");
+                return [];
+              }
+            }).catchError((error) {
+              print("Warning: Error occured while fetching testoutcomes: $error");
+              return [];
+            });
+    });
+  }
+}
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 5a55119..829e70c 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -95,6 +95,7 @@
     "/foo",
     "/bar",
     "/NonExistingFile",
+    "/NonExistingFile.js",
     "/hahaURL",
   ];
 
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 5541564..4116780 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -100,12 +100,12 @@
         continue;
       } else {
         for (String nextOutcome in annotation.outcomesList) {
-          outcomes[annotation.key].add(nextOutcome);
-          if (!validMultitestOutcomes.contains(nextOutcome)) {
-            print(
-                "Invalid test directive '$nextOutcome' on line ${lineCount}:\n"
-                "${annotation.rest} ");
-            exit(1);
+          if (validMultitestOutcomes.contains(nextOutcome)) {
+            outcomes[annotation.key].add(nextOutcome);
+          } else {
+            DebugLogger.warning(
+                "Warning: Invalid test directive '$nextOutcome' on line "
+                "${lineCount}:\n${annotation.rest} ");
           }
         }
       }
@@ -115,14 +115,21 @@
     }
   }
 
+  var keysToDelete = [];
   // Check that every key (other than the none case) has at least one outcome
   for (var outcomeKey in outcomes.keys) {
     if (outcomeKey != 'none' && outcomes[outcomeKey].isEmpty) {
-      print("Test ${outcomeKey} has no valid annotated outcomes.\n"
-            "Expected one of: ${validMultitestOutcomes.toString()}");
-      exit(1);
+      DebugLogger.warning(
+          "Warning: Test ${outcomeKey} has no valid annotated outcomes.\n"
+          "Expected one of: ${validMultitestOutcomes.toString()}");
+      // If this multitest doesn't have an outcome, mark the multitest for
+      // deletion.
+      keysToDelete.add(outcomeKey);
     }
   }
+  // If a key/multitest was marked for deletion, do the necessary cleanup.
+  keysToDelete.forEach((key) => outcomes.remove(key));
+  keysToDelete.forEach((key) => testsAsLines.remove(key));
 
   // Add the template, with no multitest lines, as a test with key 'none'.
   testsAsLines['none'] = testTemplate;
@@ -141,11 +148,22 @@
   List<String> outcomesList;
   _Annotation() {}
   factory _Annotation.from(String line) {
+    // Do an early return with "null" if this is not a valid multitest
+    // annotation.
     if (!line.contains('///')) {
       return null;
     }
+    var parts = line
+        .split('///')[1]
+        .split(':')
+        .map((s) => s.trim())
+        .where((s) => s.length > 0)
+        .toList();
+    if (parts.length <= 1) {
+      return null;
+    }
+
     var annotation = new _Annotation();
-    var parts = line.split('///')[1].split(':').map((s) => s.trim()).toList();
     annotation.key = parts[0];
     annotation.rest = parts[1];
     annotation.outcomesList = annotation.rest.split(',')
@@ -161,7 +179,12 @@
   Set<String> foundImports = new Set<String>();
   Path libraryDir = topLibrary.directoryPath;
   RegExp relativeImportRegExp = new RegExp(
-      '^(import|part)\\s+["\'](?!(dart:|dart-ext:|package:|/))([^"\']*)["\']');
+      '^(?:@.*\\s+)?' // Allow for a meta-data annotation.
+      '(import|part)'
+      '\\s+["\']'
+      '(?!(dart:|dart-ext:|package:|/))' // Look-ahead: not in package.
+      '([^"\']*)' // The path to the imported file.
+      '["\']');
   while (!toSearch.isEmpty) {
     var thisPass = toSearch;
     toSearch = new Set<Path>();
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 7d12efb..a7d3080 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -7,7 +7,9 @@
 import "dart:async";
 import "dart:convert" show LineSplitter, UTF8;
 import "dart:io";
+
 import "status_expression.dart";
+import "utils.dart" show Path;
 
 class Expectation {
   // Possible outcomes of running a test.
@@ -110,14 +112,25 @@
 final RegExp IssueNumberPattern =
     new RegExp("Issue ([0-9]+)|dartbug.com/([0-9]+)", caseSensitive: false);
 
+class StatusFile {
+  final Path location;
+
+  StatusFile(this.location);
+}
+
 // TODO(whesse): Implement configuration_info library that contains data
 // structures for test configuration, including Section.
 class Section {
-  BooleanExpression condition;
-  List<TestRule> testRules;
+  final StatusFile statusFile;
 
-  Section.always() : condition = null, testRules = new List<TestRule>();
-  Section(this.condition) : testRules = new List<TestRule>();
+  final BooleanExpression condition;
+  final List<TestRule> testRules;
+  final int lineNumber;
+
+  Section.always(this.statusFile, this.lineNumber)
+      : condition = null, testRules = new List<TestRule>();
+  Section(this.statusFile, this.condition, this.lineNumber)
+      : testRules = new List<TestRule>();
 
   bool isEnabled(environment) =>
       condition == null || condition.evaluate(environment);
@@ -153,24 +166,28 @@
     completer.complete();
   }
 
-  ReadConfigurationInto(statusFilePath, sections, sectionsRead);
+  ReadConfigurationInto(new Path(statusFilePath), sections, sectionsRead);
   return completer.future;
 }
 
-void ReadConfigurationInto(path, sections, onDone) {
-  File file = new File(path);
+void ReadConfigurationInto(Path path, sections, onDone) {
+  StatusFile statusFile = new StatusFile(path);
+  File file = new File(path.toNativePath());
   if (!file.existsSync()) {
     throw new Exception('Cannot find test status file $path');
   }
+  int lineNumber = 0;
   Stream<String> lines =
       file.openRead()
           .transform(UTF8.decoder)
           .transform(new LineSplitter());
 
-  Section current = new Section.always();
-  sections.add(current);
+  Section currentSection = new Section.always(statusFile, -1);
+  sections.add(currentSection);
+
 
   lines.listen((String line) {
+    lineNumber++;
     Match match = SplitComment.firstMatch(line);
     line = (match == null) ? "" : match[1];
     line = line.trim();
@@ -184,8 +201,9 @@
       String condition_string = match[1].trim();
       List<String> tokens = new Tokenizer(condition_string).tokenize();
       ExpressionParser parser = new ExpressionParser(new Scanner(tokens));
-      current = new Section(parser.parseBooleanExpression());
-      sections.add(current);
+      currentSection =
+          new Section(statusFile, parser.parseBooleanExpression(), lineNumber);
+      sections.add(currentSection);
       return;
     }
 
@@ -206,7 +224,8 @@
         if (issueString == null) issueString = match[2];
       }
       int issue = issueString != null ? int.parse(issueString) : null;
-      current.testRules.add(new TestRule(name, expression, issue));
+      currentSection.testRules.add(
+          new TestRule(name, expression, issue, lineNumber));
       return;
     }
 
@@ -220,8 +239,12 @@
   String name;
   SetExpression expression;
   int issue;
+  int lineNumber;
 
-  TestRule(this.name, this.expression, this.issue);
+  TestRule(this.name,
+           this.expression,
+           this.issue,
+           this.lineNumber);
 
   bool get hasIssue => issue != null;
 
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index a2056ab..2ac75de 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -224,7 +224,7 @@
   static final INTERESTED_CONFIGURATION_PARAMETERS =
       ['mode', 'arch', 'compiler', 'runtime', 'checked', 'host_checked',
        'minified', 'csp', 'system', 'vm_options', 'use_sdk',
-       'use_repository_packages', 'use_public_packages'];
+       'use_repository_packages', 'use_public_packages', 'builder_tag'];
 
   IOSink _sink;
 
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 4c2cfbc..d296355 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -26,6 +26,12 @@
 part "browser_test.dart";
 
 
+RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*");
+RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()");
+// Require at least one non-space character before '///'
+RegExp multiTestRegExp = new RegExp(r"\S *"
+                                    r"/// \w+:(.*)");
+
 /**
  * A simple function that tests [arg] and returns `true` or `false`.
  */
@@ -635,8 +641,6 @@
   final bool listRecursively;
   final extraVmOptions;
 
-  static final RegExp multiTestRegExp = new RegExp(r"/// [0-9][0-9]:(.*)");
-
   StandardTestSuite(Map configuration,
                     String suiteName,
                     Path suiteDirectory,
@@ -1606,8 +1610,6 @@
     RegExp dartOptionsRegExp = new RegExp(r"// DartOptions=(.*)");
     RegExp otherScriptsRegExp = new RegExp(r"// OtherScripts=(.*)");
     RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)");
-    RegExp multiHtmlTestRegExp =
-        new RegExp(r"useHtmlIndividualConfiguration()");
     RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
     // TODO(gram) Clean these up once the old directives are not supported.
     RegExp domImportRegExp =
@@ -1673,15 +1675,9 @@
     String isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
     bool containsDomImport = domImportRegExp.hasMatch(contents);
 
-    // Note: This is brittle. It's the age-old problem of having a context free
-    // language but the means to easily identify the construct is a regular
-    // expression, aka impossible. Therefore we just make an approximation of
-    // the number of top-level "group(...)" occurrences. This assumes you import
-    // unittest with no prefix and always directly call "group(". It only uses
-    // top-level "groups" so tests running nested groups will be no-ops.
-    RegExp numTests = new RegExp(r"\s*[^/]\s*group\('[^,']*");
     List<String> subtestNames = [];
-    Iterator matchesIter = numTests.allMatches(contents).iterator;
+    Iterator matchesIter =
+        multiHtmlTestGroupRegExp.allMatches(contents).iterator;
     while(matchesIter.moveNext() && isMultiHtmlTest) {
       String fullMatch = matchesIter.current.group(0);
       subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
diff --git a/tools/utils.py b/tools/utils.py
index 49ff0b1..a8ad21d 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -318,6 +318,14 @@
     return None
 
 def GetSVNRevision():
+  # When building from tarball use tools/SVN_REVISION
+  svn_revision_file = os.path.join(DART_DIR, 'tools', 'SVN_REVISION')
+  try:
+    with open(svn_revision_file) as fd:
+      return fd.read()
+  except:
+    pass
+
   # FIXME(kustermann): Make this work for newer SVN versions as well (where
   # we've got only one '.svn' directory)
   custom_env = dict(os.environ)
@@ -339,14 +347,6 @@
   if revision:
     return revision
 
-  # When building from tarball use tools/SVN_REVISION
-  svn_revision_file = os.path.join(DART_DIR, 'tools', 'SVN_REVISION')
-  try:
-    with open(svn_revision_file) as fd:
-      return fd.read()
-  except:
-    pass
-
   # Only fail on the buildbot in case of a SVN client version mismatch.
   user = GetUserName()
   if user != 'chrome-bot':
diff --git a/utils/apidoc/docgen.gyp b/utils/apidoc/docgen.gyp
index d57e9c3..59aa15f 100644
--- a/utils/apidoc/docgen.gyp
+++ b/utils/apidoc/docgen.gyp
@@ -80,10 +80,15 @@
             '--out=<(PRODUCT_DIR)/api_docs/docgen',
             '--json',
             '--include-sdk',
+            '--no-include-dependent-packages',
             '--package-root=<(PRODUCT_DIR)/packages',
             '--exclude-lib=async_helper',
             '--exclude-lib=expect',
             '--exclude-lib=docgen',
+            '--exclude-lib=canonicalization.a',
+            '--exclude-lib=canonicalization.b',
+            '--exclude-lib=canonicalization.c',
+            '--exclude-lib=canonicalization.d',
             '../../pkg',          
           ],
           'message': 'Running docgen: <(_action)',
diff --git a/utils/dartfmt/.gitignore b/utils/dartfmt/.gitignore
new file mode 100644
index 0000000..357f6bb
--- /dev/null
+++ b/utils/dartfmt/.gitignore
@@ -0,0 +1,2 @@
+/dartfmt.Makefile
+/dartfmt.target.mk